diff --git a/Makefile.am b/Makefile.am
index 73ff1ed..5cdadab 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -403,15 +403,6 @@
   java/core/src/main/java/com/google/protobuf/Utf8.java                            \
   java/core/src/main/java/com/google/protobuf/WireFormat.java                      \
   java/core/src/main/java/com/google/protobuf/Writer.java                          \
-  java/core/src/main/kotlin/com/google/protobuf/DslList.kt                         \
-  java/core/src/main/kotlin/com/google/protobuf/DslMap.kt                          \
-  java/core/src/main/kotlin/com/google/protobuf/DslProxy.kt                        \
-  java/core/src/main/kotlin/com/google/protobuf/ExtendableMessageExtensions.kt     \
-  java/core/src/main/kotlin/com/google/protobuf/ExtendableMessageLiteExtensions.kt \
-  java/core/src/main/kotlin/com/google/protobuf/ExtensionList.kt                   \
-  java/core/src/main/kotlin/com/google/protobuf/OnlyForUseByGeneratedProtoCode.kt  \
-  java/core/src/main/kotlin/com/google/protobuf/ProtoDslMarker.kt                  \
-  java/core/src/main/kotlin/com/google/protobuf/UnmodifiableCollections.kt         \
   java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java             \
   java/core/src/test/java/com/google/protobuf/AbstractProto2LiteSchemaTest.java    \
   java/core/src/test/java/com/google/protobuf/AbstractProto2SchemaTest.java        \
@@ -507,18 +498,9 @@
   java/core/src/test/java/com/google/protobuf/WireFormatTest.java                  \
   java/core/src/test/java/com/google/protobuf/WrappersLiteOfMethodTest.java        \
   java/core/src/test/java/com/google/protobuf/WrappersOfMethodTest.java            \
-  java/core/src/test/kotlin/com/google/protobuf/DslListTest.kt                     \
-  java/core/src/test/kotlin/com/google/protobuf/DslMapTest.kt                      \
-  java/core/src/test/kotlin/com/google/protobuf/ExtendableMessageExtensionsTest.kt \
-  java/core/src/test/kotlin/com/google/protobuf/ExtensionListTest.kt               \
-  java/core/src/test/kotlin/com/google/protobuf/Proto2Test.kt                      \
-  java/core/src/test/kotlin/com/google/protobuf/Proto3Test.kt                      \
   java/core/src/test/proto/com/google/protobuf/any_test.proto                      \
   java/core/src/test/proto/com/google/protobuf/cached_field_size_test.proto        \
   java/core/src/test/proto/com/google/protobuf/deprecated_file.proto               \
-  java/core/src/test/proto/com/google/protobuf/evil_names_proto2.proto             \
-  java/core/src/test/proto/com/google/protobuf/evil_names_proto3.proto             \
-  java/core/src/test/proto/com/google/protobuf/example_extensible_message.proto    \
   java/core/src/test/proto/com/google/protobuf/field_presence_test.proto           \
   java/core/src/test/proto/com/google/protobuf/lazy_fields_lite.proto              \
   java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto          \
@@ -528,7 +510,6 @@
   java/core/src/test/proto/com/google/protobuf/map_lite_test.proto                 \
   java/core/src/test/proto/com/google/protobuf/map_test.proto                      \
   java/core/src/test/proto/com/google/protobuf/message_lite_extension_util_test.proto\
-  java/core/src/test/proto/com/google/protobuf/multiple_files_proto3.proto         \
   java/core/src/test/proto/com/google/protobuf/multiple_files_test.proto           \
   java/core/src/test/proto/com/google/protobuf/nested_builders_test.proto          \
   java/core/src/test/proto/com/google/protobuf/nested_extension.proto              \
@@ -549,6 +530,27 @@
   java/core/src/test/proto/com/google/protobuf/test_check_utf8_size.proto          \
   java/core/src/test/proto/com/google/protobuf/test_custom_options.proto           \
   java/core/src/test/proto/com/google/protobuf/wrappers_test.proto                 \
+  java/kotlin/src/main/kotlin/com/google/protobuf/DslList.kt                       \
+  java/kotlin/src/main/kotlin/com/google/protobuf/DslMap.kt                        \
+  java/kotlin/src/main/kotlin/com/google/protobuf/DslProxy.kt                      \
+  java/kotlin/src/main/kotlin/com/google/protobuf/ExtendableMessageExtensions.kt   \
+  java/kotlin/src/main/kotlin/com/google/protobuf/ExtendableMessageLiteExtensions.kt\
+  java/kotlin/src/main/kotlin/com/google/protobuf/ExtensionList.kt                 \
+  java/kotlin/src/main/kotlin/com/google/protobuf/OnlyForUseByGeneratedProtoCode.kt\
+  java/kotlin/src/main/kotlin/com/google/protobuf/ProtoDslMarker.kt                \
+  java/kotlin/src/main/kotlin/com/google/protobuf/UnmodifiableCollections.kt       \
+  java/kotlin/src/test/kotlin/com/google/protobuf/DslListTest.kt                   \
+  java/kotlin/src/test/kotlin/com/google/protobuf/DslMapTest.kt                    \
+  java/kotlin/src/test/kotlin/com/google/protobuf/ExtendableMessageExtensionsTest.kt\
+  java/kotlin/src/test/kotlin/com/google/protobuf/ExtensionListTest.kt             \
+  java/kotlin/src/test/kotlin/com/google/protobuf/Proto2Test.kt                    \
+  java/kotlin/src/test/kotlin/com/google/protobuf/Proto3Test.kt                    \
+  java/kotlin/src/test/proto/com/google/protobuf/evil_names_proto2.proto           \
+  java/kotlin/src/test/proto/com/google/protobuf/evil_names_proto3.proto           \
+  java/kotlin/src/test/proto/com/google/protobuf/example_extensible_message.proto  \
+  java/kotlin/src/test/proto/com/google/protobuf/multiple_files_proto3.proto       \
+  java/kotlin-lite/src/test/kotlin/com/google/protobuf/ExtendableMessageLiteExtensionsTest.kt\
+  java/kotlin-lite/src/test/kotlin/com/google/protobuf/Proto2LiteTest.kt           \
   java/lite.md                                                                     \
   java/lite/BUILD                                                                  \
   java/lite/generate-sources-build.xml                                             \
@@ -558,8 +560,6 @@
   java/lite/process-lite-sources-build.xml                                         \
   java/lite/src/test/java/com/google/protobuf/LiteTest.java                        \
   java/lite/src/test/java/com/google/protobuf/Proto2MessageLiteInfoFactory.java    \
-  java/lite/src/test/kotlin/com/google/protobuf/ExtendableMessageLiteExtensionsTest.kt \
-  java/lite/src/test/kotlin/com/google/protobuf/Proto2LiteTest.kt                  \
   java/pom.xml                                                                     \
   java/util/BUILD                                                                  \
   java/util/pom.xml                                                                \
diff --git a/java/core/pom.xml b/java/core/pom.xml
index 70e4bfc..4df7d43 100644
--- a/java/core/pom.xml
+++ b/java/core/pom.xml
@@ -38,11 +38,6 @@
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava-testlib</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
       <groupId>com.google.truth</groupId>
       <artifactId>truth</artifactId>
       <scope>test</scope>
diff --git a/java/kotlin-lite/target/antrun/build-main.xml b/java/kotlin-lite/target/antrun/build-main.xml
deleted file mode 100644
index e694803..0000000
--- a/java/kotlin-lite/target/antrun/build-main.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<project name="maven-antrun-" default="main"  >
-<target name="main">
-  <ant antfile="process-lite-sources-build.xml"/>
-</target>
-</project>
\ No newline at end of file
diff --git a/java/kotlin-lite/target/classes/META-INF/MANIFEST.MF b/java/kotlin-lite/target/classes/META-INF/MANIFEST.MF
deleted file mode 100644
index 99837bd..0000000
--- a/java/kotlin-lite/target/classes/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,21 +0,0 @@
-Manifest-Version: 1.0
-Automatic-Module-Name: com.google.protobuf
-Bnd-LastModified: 1617123864936
-Build-Jdk: 11.0.10
-Built-By: deannagarcia
-Bundle-Description: Lite version of Protocol Buffers library. This versi
- on is optimized for code size, but does    not guarantee API/ABI stabil
- ity.
-Bundle-DocURL: https://developers.google.com/protocol-buffers/
-Bundle-License: https://opensource.org/licenses/BSD-3-Clause
-Bundle-ManifestVersion: 2
-Bundle-Name: Protocol Buffers [Lite]
-Bundle-SymbolicName: com.google.protobuf
-Bundle-Version: 3.15.6
-Created-By: Apache Maven Bundle Plugin
-Export-Package: com.google.protobuf;version="3.15.6"
-Import-Package: sun.misc;resolution:=optional,com.google.protobuf;versio
- n="[3.15,4)",kotlin,kotlin.annotation,kotlin.jvm.internal,kotlin.jvm.in
- ternal.markers
-Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.7))"
-Tool: Bnd-3.0.0.201509101326
diff --git a/java/kotlin-lite/target/classes/META-INF/protobuf-javalite.kotlin_module b/java/kotlin-lite/target/classes/META-INF/protobuf-javalite.kotlin_module
deleted file mode 100644
index 966edfe..0000000
--- a/java/kotlin-lite/target/classes/META-INF/protobuf-javalite.kotlin_module
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/AbstractMessageLite$Builder$LimitedInputStream.class b/java/kotlin-lite/target/classes/com/google/protobuf/AbstractMessageLite$Builder$LimitedInputStream.class
deleted file mode 100644
index b79c69a..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/AbstractMessageLite$Builder$LimitedInputStream.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/AbstractMessageLite$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/AbstractMessageLite$Builder.class
deleted file mode 100644
index fa13546..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/AbstractMessageLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/AbstractMessageLite$InternalOneOfEnum.class b/java/kotlin-lite/target/classes/com/google/protobuf/AbstractMessageLite$InternalOneOfEnum.class
deleted file mode 100644
index 8e98f8c..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/AbstractMessageLite$InternalOneOfEnum.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/AbstractMessageLite.class b/java/kotlin-lite/target/classes/com/google/protobuf/AbstractMessageLite.class
deleted file mode 100644
index 1baec63..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/AbstractMessageLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/AbstractParser.class b/java/kotlin-lite/target/classes/com/google/protobuf/AbstractParser.class
deleted file mode 100644
index eeefa54..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/AbstractParser.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/AbstractProtobufList.class b/java/kotlin-lite/target/classes/com/google/protobuf/AbstractProtobufList.class
deleted file mode 100644
index 21e65d3..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/AbstractProtobufList.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/AllocatedBuffer$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/AllocatedBuffer$1.class
deleted file mode 100644
index 92e3ada..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/AllocatedBuffer$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/AllocatedBuffer$2.class b/java/kotlin-lite/target/classes/com/google/protobuf/AllocatedBuffer$2.class
deleted file mode 100644
index 2d21560..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/AllocatedBuffer$2.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/AllocatedBuffer.class b/java/kotlin-lite/target/classes/com/google/protobuf/AllocatedBuffer.class
deleted file mode 100644
index 53703ce..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/AllocatedBuffer.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Android.class b/java/kotlin-lite/target/classes/com/google/protobuf/Android.class
deleted file mode 100644
index 94bccbd..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Android.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Any$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/Any$1.class
deleted file mode 100644
index 397b7f2..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Any$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Any$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/Any$Builder.class
deleted file mode 100644
index 8f9308f..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Any$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Any.class b/java/kotlin-lite/target/classes/com/google/protobuf/Any.class
deleted file mode 100644
index 48f0e81..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Any.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/AnyOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/AnyOrBuilder.class
deleted file mode 100644
index 63a6a71..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/AnyOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/AnyProto.class b/java/kotlin-lite/target/classes/com/google/protobuf/AnyProto.class
deleted file mode 100644
index c5b8148..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/AnyProto.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Api$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/Api$1.class
deleted file mode 100644
index 189b46b..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Api$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Api$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/Api$Builder.class
deleted file mode 100644
index 92fb1ab..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Api$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Api.class b/java/kotlin-lite/target/classes/com/google/protobuf/Api.class
deleted file mode 100644
index d41c0ed..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Api.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ApiOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/ApiOrBuilder.class
deleted file mode 100644
index d197152..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ApiOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ApiProto.class b/java/kotlin-lite/target/classes/com/google/protobuf/ApiProto.class
deleted file mode 100644
index c3bf617..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ApiProto.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ArrayDecoders$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/ArrayDecoders$1.class
deleted file mode 100644
index 799ca8e..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ArrayDecoders$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ArrayDecoders$Registers.class b/java/kotlin-lite/target/classes/com/google/protobuf/ArrayDecoders$Registers.class
deleted file mode 100644
index b551c23..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ArrayDecoders$Registers.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ArrayDecoders.class b/java/kotlin-lite/target/classes/com/google/protobuf/ArrayDecoders.class
deleted file mode 100644
index ed353dd..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ArrayDecoders.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BinaryReader$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/BinaryReader$1.class
deleted file mode 100644
index db2ae3b..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BinaryReader$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BinaryReader$SafeHeapReader.class b/java/kotlin-lite/target/classes/com/google/protobuf/BinaryReader$SafeHeapReader.class
deleted file mode 100644
index 1333693..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BinaryReader$SafeHeapReader.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BinaryReader.class b/java/kotlin-lite/target/classes/com/google/protobuf/BinaryReader.class
deleted file mode 100644
index 30d971b..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BinaryReader.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BinaryWriter$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/BinaryWriter$1.class
deleted file mode 100644
index d1f16c7..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BinaryWriter$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BinaryWriter$SafeDirectWriter.class b/java/kotlin-lite/target/classes/com/google/protobuf/BinaryWriter$SafeDirectWriter.class
deleted file mode 100644
index b5fe1bd..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BinaryWriter$SafeDirectWriter.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BinaryWriter$SafeHeapWriter.class b/java/kotlin-lite/target/classes/com/google/protobuf/BinaryWriter$SafeHeapWriter.class
deleted file mode 100644
index 57d03fe..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BinaryWriter$SafeHeapWriter.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BinaryWriter$UnsafeDirectWriter.class b/java/kotlin-lite/target/classes/com/google/protobuf/BinaryWriter$UnsafeDirectWriter.class
deleted file mode 100644
index ff45dea..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BinaryWriter$UnsafeDirectWriter.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BinaryWriter$UnsafeHeapWriter.class b/java/kotlin-lite/target/classes/com/google/protobuf/BinaryWriter$UnsafeHeapWriter.class
deleted file mode 100644
index d82dff1..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BinaryWriter$UnsafeHeapWriter.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BinaryWriter.class b/java/kotlin-lite/target/classes/com/google/protobuf/BinaryWriter.class
deleted file mode 100644
index d797930..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BinaryWriter.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BoolValue$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/BoolValue$1.class
deleted file mode 100644
index a49a5ab..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BoolValue$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BoolValue$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/BoolValue$Builder.class
deleted file mode 100644
index 70656b7..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BoolValue$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BoolValue.class b/java/kotlin-lite/target/classes/com/google/protobuf/BoolValue.class
deleted file mode 100644
index ab79d2c..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BoolValue.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BoolValueOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/BoolValueOrBuilder.class
deleted file mode 100644
index 344b977..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BoolValueOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BooleanArrayList.class b/java/kotlin-lite/target/classes/com/google/protobuf/BooleanArrayList.class
deleted file mode 100644
index 68e7c9b..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BooleanArrayList.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BufferAllocator$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/BufferAllocator$1.class
deleted file mode 100644
index db88c0e..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BufferAllocator$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BufferAllocator.class b/java/kotlin-lite/target/classes/com/google/protobuf/BufferAllocator.class
deleted file mode 100644
index 66b5a08..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BufferAllocator.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ByteBufferWriter.class b/java/kotlin-lite/target/classes/com/google/protobuf/ByteBufferWriter.class
deleted file mode 100644
index 1f5fa25..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ByteBufferWriter.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ByteOutput.class b/java/kotlin-lite/target/classes/com/google/protobuf/ByteOutput.class
deleted file mode 100644
index 3307ca9..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ByteOutput.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$1.class
deleted file mode 100644
index 28e3b9c..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$2.class b/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$2.class
deleted file mode 100644
index 192acaa..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$2.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$AbstractByteIterator.class b/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$AbstractByteIterator.class
deleted file mode 100644
index eaa31e3..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$AbstractByteIterator.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$ArraysByteArrayCopier.class b/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$ArraysByteArrayCopier.class
deleted file mode 100644
index 13bb1e8..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$ArraysByteArrayCopier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$BoundedByteString.class b/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$BoundedByteString.class
deleted file mode 100644
index 35baf6e..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$BoundedByteString.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$ByteArrayCopier.class b/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$ByteArrayCopier.class
deleted file mode 100644
index bcb2ee5..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$ByteArrayCopier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$ByteIterator.class b/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$ByteIterator.class
deleted file mode 100644
index 72086f6..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$ByteIterator.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$CodedBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$CodedBuilder.class
deleted file mode 100644
index 92f9f69..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$CodedBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$LeafByteString.class b/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$LeafByteString.class
deleted file mode 100644
index 5696237..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$LeafByteString.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$LiteralByteString.class b/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$LiteralByteString.class
deleted file mode 100644
index 157ad95..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$LiteralByteString.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$Output.class b/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$Output.class
deleted file mode 100644
index 2a59b8d..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$Output.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$SystemByteArrayCopier.class b/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$SystemByteArrayCopier.class
deleted file mode 100644
index b409059..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString$SystemByteArrayCopier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString.class b/java/kotlin-lite/target/classes/com/google/protobuf/ByteString.class
deleted file mode 100644
index b7d64f1..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ByteString.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BytesValue$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/BytesValue$1.class
deleted file mode 100644
index 05897e9..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BytesValue$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BytesValue$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/BytesValue$Builder.class
deleted file mode 100644
index b3c6a99..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BytesValue$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BytesValue.class b/java/kotlin-lite/target/classes/com/google/protobuf/BytesValue.class
deleted file mode 100644
index 8a83ead..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BytesValue.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/BytesValueOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/BytesValueOrBuilder.class
deleted file mode 100644
index da5c8b5..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/BytesValueOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$1.class
deleted file mode 100644
index 16da296..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$ArrayDecoder.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$ArrayDecoder.class
deleted file mode 100644
index 04a4409..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$ArrayDecoder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$IterableDirectByteBufferDecoder.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$IterableDirectByteBufferDecoder.class
deleted file mode 100644
index 24448bd..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$IterableDirectByteBufferDecoder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$StreamDecoder$RefillCallback.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$StreamDecoder$RefillCallback.class
deleted file mode 100644
index e515f4d..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$StreamDecoder$RefillCallback.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$StreamDecoder$SkippedDataSink.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$StreamDecoder$SkippedDataSink.class
deleted file mode 100644
index 31a6caa..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$StreamDecoder$SkippedDataSink.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$StreamDecoder.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$StreamDecoder.class
deleted file mode 100644
index af4848c..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$StreamDecoder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$UnsafeDirectNioDecoder.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$UnsafeDirectNioDecoder.class
deleted file mode 100644
index 9aa2072..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream$UnsafeDirectNioDecoder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream.class
deleted file mode 100644
index 8c1ca5e..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStream.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStreamReader$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStreamReader$1.class
deleted file mode 100644
index 57a9277..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStreamReader$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStreamReader.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStreamReader.class
deleted file mode 100644
index 1035191..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedInputStreamReader.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$1.class
deleted file mode 100644
index 6e8f8b6..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$AbstractBufferedEncoder.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$AbstractBufferedEncoder.class
deleted file mode 100644
index cd6be47..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$AbstractBufferedEncoder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$ArrayEncoder.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$ArrayEncoder.class
deleted file mode 100644
index 47decd5..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$ArrayEncoder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$ByteOutputEncoder.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$ByteOutputEncoder.class
deleted file mode 100644
index 5ee2a32..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$ByteOutputEncoder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$HeapNioEncoder.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$HeapNioEncoder.class
deleted file mode 100644
index 4cdd239..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$HeapNioEncoder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$OutOfSpaceException.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$OutOfSpaceException.class
deleted file mode 100644
index 1287580..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$OutOfSpaceException.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$OutputStreamEncoder.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$OutputStreamEncoder.class
deleted file mode 100644
index a16a1d7..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$OutputStreamEncoder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$SafeDirectNioEncoder.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$SafeDirectNioEncoder.class
deleted file mode 100644
index 166bd51..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$SafeDirectNioEncoder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$UnsafeDirectNioEncoder.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$UnsafeDirectNioEncoder.class
deleted file mode 100644
index 0208cf0..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream$UnsafeDirectNioEncoder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream.class
deleted file mode 100644
index 29fcf07..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStream.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStreamWriter$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStreamWriter$1.class
deleted file mode 100644
index 2400384..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStreamWriter$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStreamWriter.class b/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStreamWriter.class
deleted file mode 100644
index 7b8fe1b..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/CodedOutputStreamWriter.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/DoubleArrayList.class b/java/kotlin-lite/target/classes/com/google/protobuf/DoubleArrayList.class
deleted file mode 100644
index b8e0dc2..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/DoubleArrayList.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/DoubleValue$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/DoubleValue$1.class
deleted file mode 100644
index 11b102b..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/DoubleValue$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/DoubleValue$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/DoubleValue$Builder.class
deleted file mode 100644
index b5405e9..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/DoubleValue$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/DoubleValue.class b/java/kotlin-lite/target/classes/com/google/protobuf/DoubleValue.class
deleted file mode 100644
index e3cbe73..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/DoubleValue.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/DoubleValueOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/DoubleValueOrBuilder.class
deleted file mode 100644
index c7ae321..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/DoubleValueOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Duration$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/Duration$1.class
deleted file mode 100644
index 7228c3f..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Duration$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Duration$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/Duration$Builder.class
deleted file mode 100644
index f81da97..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Duration$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Duration.class b/java/kotlin-lite/target/classes/com/google/protobuf/Duration.class
deleted file mode 100644
index 336ffbe..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Duration.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/DurationOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/DurationOrBuilder.class
deleted file mode 100644
index 067fb70..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/DurationOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/DurationProto.class b/java/kotlin-lite/target/classes/com/google/protobuf/DurationProto.class
deleted file mode 100644
index 3cb3ec6..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/DurationProto.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Empty$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/Empty$1.class
deleted file mode 100644
index d1b55dd..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Empty$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Empty$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/Empty$Builder.class
deleted file mode 100644
index 8af81c9..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Empty$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Empty.class b/java/kotlin-lite/target/classes/com/google/protobuf/Empty.class
deleted file mode 100644
index 5412018..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Empty.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/EmptyOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/EmptyOrBuilder.class
deleted file mode 100644
index 0e3e1fa..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/EmptyOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/EmptyProto.class b/java/kotlin-lite/target/classes/com/google/protobuf/EmptyProto.class
deleted file mode 100644
index 622d06f..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/EmptyProto.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Enum$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/Enum$1.class
deleted file mode 100644
index e9e9fed..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Enum$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Enum$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/Enum$Builder.class
deleted file mode 100644
index 335c20a..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Enum$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Enum.class b/java/kotlin-lite/target/classes/com/google/protobuf/Enum.class
deleted file mode 100644
index ddd94ae..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Enum.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/EnumOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/EnumOrBuilder.class
deleted file mode 100644
index 122ee91..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/EnumOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/EnumValue$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/EnumValue$1.class
deleted file mode 100644
index aac3008..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/EnumValue$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/EnumValue$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/EnumValue$Builder.class
deleted file mode 100644
index 0d31584..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/EnumValue$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/EnumValue.class b/java/kotlin-lite/target/classes/com/google/protobuf/EnumValue.class
deleted file mode 100644
index 2cfdad4..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/EnumValue.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/EnumValueOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/EnumValueOrBuilder.class
deleted file mode 100644
index 2e5a21b..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/EnumValueOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ExperimentalApi.class b/java/kotlin-lite/target/classes/com/google/protobuf/ExperimentalApi.class
deleted file mode 100644
index ee21fbf..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ExperimentalApi.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionLite.class b/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionLite.class
deleted file mode 100644
index 4cc58a7..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionRegistryFactory.class b/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionRegistryFactory.class
deleted file mode 100644
index a881401..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionRegistryFactory.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionRegistryLite$ExtensionClassHolder.class b/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionRegistryLite$ExtensionClassHolder.class
deleted file mode 100644
index 5fe9f76..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionRegistryLite$ExtensionClassHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionRegistryLite$ObjectIntPair.class b/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionRegistryLite$ObjectIntPair.class
deleted file mode 100644
index 72c4823..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionRegistryLite$ObjectIntPair.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionRegistryLite.class b/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionRegistryLite.class
deleted file mode 100644
index 034cdac..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionRegistryLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionSchema.class b/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionSchema.class
deleted file mode 100644
index 2012de7..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionSchema.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionSchemaLite$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionSchemaLite$1.class
deleted file mode 100644
index 1b67f7a..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionSchemaLite$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionSchemaLite.class b/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionSchemaLite.class
deleted file mode 100644
index c45dcff..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionSchemaLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionSchemas.class b/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionSchemas.class
deleted file mode 100644
index cb980fe..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ExtensionSchemas.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Field$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/Field$1.class
deleted file mode 100644
index 933f734..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Field$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Field$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/Field$Builder.class
deleted file mode 100644
index 36ff454..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Field$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Field$Cardinality$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/Field$Cardinality$1.class
deleted file mode 100644
index 5760760..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Field$Cardinality$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Field$Cardinality$CardinalityVerifier.class b/java/kotlin-lite/target/classes/com/google/protobuf/Field$Cardinality$CardinalityVerifier.class
deleted file mode 100644
index 7622b72..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Field$Cardinality$CardinalityVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Field$Cardinality.class b/java/kotlin-lite/target/classes/com/google/protobuf/Field$Cardinality.class
deleted file mode 100644
index 23f3dc5..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Field$Cardinality.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Field$Kind$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/Field$Kind$1.class
deleted file mode 100644
index 81eb303..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Field$Kind$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Field$Kind$KindVerifier.class b/java/kotlin-lite/target/classes/com/google/protobuf/Field$Kind$KindVerifier.class
deleted file mode 100644
index e9a1f24..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Field$Kind$KindVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Field$Kind.class b/java/kotlin-lite/target/classes/com/google/protobuf/Field$Kind.class
deleted file mode 100644
index 528963c..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Field$Kind.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Field.class b/java/kotlin-lite/target/classes/com/google/protobuf/Field.class
deleted file mode 100644
index 96afb9e..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Field.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FieldInfo$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/FieldInfo$1.class
deleted file mode 100644
index 2c2e2a3..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FieldInfo$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FieldInfo$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/FieldInfo$Builder.class
deleted file mode 100644
index 21b24b6..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FieldInfo$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FieldInfo.class b/java/kotlin-lite/target/classes/com/google/protobuf/FieldInfo.class
deleted file mode 100644
index f321af7..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FieldInfo.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FieldMask$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/FieldMask$1.class
deleted file mode 100644
index cc0d416..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FieldMask$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FieldMask$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/FieldMask$Builder.class
deleted file mode 100644
index c738aad..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FieldMask$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FieldMask.class b/java/kotlin-lite/target/classes/com/google/protobuf/FieldMask.class
deleted file mode 100644
index b123060..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FieldMask.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FieldMaskOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/FieldMaskOrBuilder.class
deleted file mode 100644
index 2e4ea04..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FieldMaskOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FieldMaskProto.class b/java/kotlin-lite/target/classes/com/google/protobuf/FieldMaskProto.class
deleted file mode 100644
index b0bac3b..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FieldMaskProto.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FieldOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/FieldOrBuilder.class
deleted file mode 100644
index 667c551..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FieldOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FieldSet$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/FieldSet$1.class
deleted file mode 100644
index 1264bc4..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FieldSet$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FieldSet$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/FieldSet$Builder.class
deleted file mode 100644
index 9beda36..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FieldSet$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FieldSet$FieldDescriptorLite.class b/java/kotlin-lite/target/classes/com/google/protobuf/FieldSet$FieldDescriptorLite.class
deleted file mode 100644
index 170d3b2..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FieldSet$FieldDescriptorLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FieldSet.class b/java/kotlin-lite/target/classes/com/google/protobuf/FieldSet.class
deleted file mode 100644
index bde362b..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FieldSet.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FieldType$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/FieldType$1.class
deleted file mode 100644
index 5e31d0a..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FieldType$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FieldType$Collection.class b/java/kotlin-lite/target/classes/com/google/protobuf/FieldType$Collection.class
deleted file mode 100644
index 62e80ed..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FieldType$Collection.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FieldType.class b/java/kotlin-lite/target/classes/com/google/protobuf/FieldType.class
deleted file mode 100644
index 1db06ab..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FieldType.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FloatArrayList.class b/java/kotlin-lite/target/classes/com/google/protobuf/FloatArrayList.class
deleted file mode 100644
index 84e15f1..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FloatArrayList.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FloatValue$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/FloatValue$1.class
deleted file mode 100644
index 79737cd..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FloatValue$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FloatValue$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/FloatValue$Builder.class
deleted file mode 100644
index 944b681..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FloatValue$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FloatValue.class b/java/kotlin-lite/target/classes/com/google/protobuf/FloatValue.class
deleted file mode 100644
index 9fa301c..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FloatValue.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/FloatValueOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/FloatValueOrBuilder.class
deleted file mode 100644
index 08b00d4..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/FloatValueOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageInfoFactory.class b/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageInfoFactory.class
deleted file mode 100644
index ef5aac3..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageInfoFactory.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$1.class
deleted file mode 100644
index 904c99e..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$Builder.class
deleted file mode 100644
index 53c1cff..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$DefaultInstanceBasedParser.class b/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$DefaultInstanceBasedParser.class
deleted file mode 100644
index 4a15fe4..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$DefaultInstanceBasedParser.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$ExtendableBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$ExtendableBuilder.class
deleted file mode 100644
index 4f9cc82..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$ExtendableBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$ExtendableMessage$ExtensionWriter.class b/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$ExtendableMessage$ExtensionWriter.class
deleted file mode 100644
index 9fb00ba..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$ExtendableMessage$ExtensionWriter.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$ExtendableMessage.class b/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$ExtendableMessage.class
deleted file mode 100644
index 948ce73..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$ExtendableMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$ExtendableMessageOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$ExtendableMessageOrBuilder.class
deleted file mode 100644
index c463262..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$ExtendableMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$ExtensionDescriptor.class b/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$ExtensionDescriptor.class
deleted file mode 100644
index 868f536..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$ExtensionDescriptor.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$GeneratedExtension.class b/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$GeneratedExtension.class
deleted file mode 100644
index 709ccec..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$GeneratedExtension.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$MethodToInvoke.class b/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$MethodToInvoke.class
deleted file mode 100644
index 72d3a4c..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$MethodToInvoke.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$SerializedForm.class b/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$SerializedForm.class
deleted file mode 100644
index 60924d7..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite$SerializedForm.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite.class b/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite.class
deleted file mode 100644
index 64a5c3f..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/GeneratedMessageLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Int32Value$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/Int32Value$1.class
deleted file mode 100644
index df5936f..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Int32Value$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Int32Value$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/Int32Value$Builder.class
deleted file mode 100644
index dc3862f..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Int32Value$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Int32Value.class b/java/kotlin-lite/target/classes/com/google/protobuf/Int32Value.class
deleted file mode 100644
index a12434e..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Int32Value.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Int32ValueOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/Int32ValueOrBuilder.class
deleted file mode 100644
index a01ff79..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Int32ValueOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Int64Value$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/Int64Value$1.class
deleted file mode 100644
index 758c783..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Int64Value$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Int64Value$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/Int64Value$Builder.class
deleted file mode 100644
index fe2f2f7..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Int64Value$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Int64Value.class b/java/kotlin-lite/target/classes/com/google/protobuf/Int64Value.class
deleted file mode 100644
index fa12966..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Int64Value.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Int64ValueOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/Int64ValueOrBuilder.class
deleted file mode 100644
index 06611c6..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Int64ValueOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/IntArrayList.class b/java/kotlin-lite/target/classes/com/google/protobuf/IntArrayList.class
deleted file mode 100644
index 95a07a4..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/IntArrayList.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$BooleanList.class b/java/kotlin-lite/target/classes/com/google/protobuf/Internal$BooleanList.class
deleted file mode 100644
index c990551..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$BooleanList.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$DoubleList.class b/java/kotlin-lite/target/classes/com/google/protobuf/Internal$DoubleList.class
deleted file mode 100644
index 20213cc..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$DoubleList.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$EnumLite.class b/java/kotlin-lite/target/classes/com/google/protobuf/Internal$EnumLite.class
deleted file mode 100644
index f7529a7..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$EnumLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$EnumLiteMap.class b/java/kotlin-lite/target/classes/com/google/protobuf/Internal$EnumLiteMap.class
deleted file mode 100644
index 8926294..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$EnumLiteMap.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$EnumVerifier.class b/java/kotlin-lite/target/classes/com/google/protobuf/Internal$EnumVerifier.class
deleted file mode 100644
index 4f51684..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$EnumVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$FloatList.class b/java/kotlin-lite/target/classes/com/google/protobuf/Internal$FloatList.class
deleted file mode 100644
index 94c893e..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$FloatList.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$IntList.class b/java/kotlin-lite/target/classes/com/google/protobuf/Internal$IntList.class
deleted file mode 100644
index 411446b..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$IntList.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$ListAdapter$Converter.class b/java/kotlin-lite/target/classes/com/google/protobuf/Internal$ListAdapter$Converter.class
deleted file mode 100644
index d55d021..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$ListAdapter$Converter.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$ListAdapter.class b/java/kotlin-lite/target/classes/com/google/protobuf/Internal$ListAdapter.class
deleted file mode 100644
index 022c33d..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$ListAdapter.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$LongList.class b/java/kotlin-lite/target/classes/com/google/protobuf/Internal$LongList.class
deleted file mode 100644
index a39f9cd..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$LongList.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$MapAdapter$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/Internal$MapAdapter$1.class
deleted file mode 100644
index 27b93fd..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$MapAdapter$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$MapAdapter$Converter.class b/java/kotlin-lite/target/classes/com/google/protobuf/Internal$MapAdapter$Converter.class
deleted file mode 100644
index 758e651..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$MapAdapter$Converter.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$MapAdapter$EntryAdapter.class b/java/kotlin-lite/target/classes/com/google/protobuf/Internal$MapAdapter$EntryAdapter.class
deleted file mode 100644
index 45ba6ed..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$MapAdapter$EntryAdapter.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$MapAdapter$IteratorAdapter.class b/java/kotlin-lite/target/classes/com/google/protobuf/Internal$MapAdapter$IteratorAdapter.class
deleted file mode 100644
index 2db85e3..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$MapAdapter$IteratorAdapter.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$MapAdapter$SetAdapter.class b/java/kotlin-lite/target/classes/com/google/protobuf/Internal$MapAdapter$SetAdapter.class
deleted file mode 100644
index 601ab08..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$MapAdapter$SetAdapter.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$MapAdapter.class b/java/kotlin-lite/target/classes/com/google/protobuf/Internal$MapAdapter.class
deleted file mode 100644
index a9d70d0..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$MapAdapter.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$ProtobufList.class b/java/kotlin-lite/target/classes/com/google/protobuf/Internal$ProtobufList.class
deleted file mode 100644
index 26b6d47..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Internal$ProtobufList.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Internal.class b/java/kotlin-lite/target/classes/com/google/protobuf/Internal.class
deleted file mode 100644
index f62d009..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Internal.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/InvalidProtocolBufferException$InvalidWireTypeException.class b/java/kotlin-lite/target/classes/com/google/protobuf/InvalidProtocolBufferException$InvalidWireTypeException.class
deleted file mode 100644
index d2c6bef..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/InvalidProtocolBufferException$InvalidWireTypeException.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/InvalidProtocolBufferException.class b/java/kotlin-lite/target/classes/com/google/protobuf/InvalidProtocolBufferException.class
deleted file mode 100644
index e83d6e2..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/InvalidProtocolBufferException.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/IterableByteBufferInputStream.class b/java/kotlin-lite/target/classes/com/google/protobuf/IterableByteBufferInputStream.class
deleted file mode 100644
index 81e0fe4..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/IterableByteBufferInputStream.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/JavaType.class b/java/kotlin-lite/target/classes/com/google/protobuf/JavaType.class
deleted file mode 100644
index 656ff6c..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/JavaType.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/LazyField$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/LazyField$1.class
deleted file mode 100644
index 36f5db8..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/LazyField$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/LazyField$LazyEntry.class b/java/kotlin-lite/target/classes/com/google/protobuf/LazyField$LazyEntry.class
deleted file mode 100644
index fc22a98..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/LazyField$LazyEntry.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/LazyField$LazyIterator.class b/java/kotlin-lite/target/classes/com/google/protobuf/LazyField$LazyIterator.class
deleted file mode 100644
index f96db16..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/LazyField$LazyIterator.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/LazyField.class b/java/kotlin-lite/target/classes/com/google/protobuf/LazyField.class
deleted file mode 100644
index 64ef415..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/LazyField.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/LazyFieldLite.class b/java/kotlin-lite/target/classes/com/google/protobuf/LazyFieldLite.class
deleted file mode 100644
index af95471..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/LazyFieldLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/LazyStringArrayList$ByteArrayListView.class b/java/kotlin-lite/target/classes/com/google/protobuf/LazyStringArrayList$ByteArrayListView.class
deleted file mode 100644
index 904e5b1..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/LazyStringArrayList$ByteArrayListView.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/LazyStringArrayList$ByteStringListView.class b/java/kotlin-lite/target/classes/com/google/protobuf/LazyStringArrayList$ByteStringListView.class
deleted file mode 100644
index 5404ef0..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/LazyStringArrayList$ByteStringListView.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/LazyStringArrayList.class b/java/kotlin-lite/target/classes/com/google/protobuf/LazyStringArrayList.class
deleted file mode 100644
index 6973bcd..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/LazyStringArrayList.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/LazyStringList.class b/java/kotlin-lite/target/classes/com/google/protobuf/LazyStringList.class
deleted file mode 100644
index d906bc9..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/LazyStringList.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ListFieldSchema$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/ListFieldSchema$1.class
deleted file mode 100644
index 3a187a2..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ListFieldSchema$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ListFieldSchema$ListFieldSchemaFull.class b/java/kotlin-lite/target/classes/com/google/protobuf/ListFieldSchema$ListFieldSchemaFull.class
deleted file mode 100644
index 589fb2c..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ListFieldSchema$ListFieldSchemaFull.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ListFieldSchema$ListFieldSchemaLite.class b/java/kotlin-lite/target/classes/com/google/protobuf/ListFieldSchema$ListFieldSchemaLite.class
deleted file mode 100644
index 6822eeb..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ListFieldSchema$ListFieldSchemaLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ListFieldSchema.class b/java/kotlin-lite/target/classes/com/google/protobuf/ListFieldSchema.class
deleted file mode 100644
index b439b86..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ListFieldSchema.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ListValue$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/ListValue$1.class
deleted file mode 100644
index 3f1ec2f..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ListValue$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ListValue$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/ListValue$Builder.class
deleted file mode 100644
index 03f2552..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ListValue$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ListValue.class b/java/kotlin-lite/target/classes/com/google/protobuf/ListValue.class
deleted file mode 100644
index b078bc9..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ListValue.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ListValueOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/ListValueOrBuilder.class
deleted file mode 100644
index 8dacb4a..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ListValueOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/LongArrayList.class b/java/kotlin-lite/target/classes/com/google/protobuf/LongArrayList.class
deleted file mode 100644
index 53c7de3..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/LongArrayList.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ManifestSchemaFactory$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/ManifestSchemaFactory$1.class
deleted file mode 100644
index 909b938..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ManifestSchemaFactory$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ManifestSchemaFactory$CompositeMessageInfoFactory.class b/java/kotlin-lite/target/classes/com/google/protobuf/ManifestSchemaFactory$CompositeMessageInfoFactory.class
deleted file mode 100644
index e82186a..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ManifestSchemaFactory$CompositeMessageInfoFactory.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ManifestSchemaFactory.class b/java/kotlin-lite/target/classes/com/google/protobuf/ManifestSchemaFactory.class
deleted file mode 100644
index 007f217..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ManifestSchemaFactory.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MapEntryLite$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/MapEntryLite$1.class
deleted file mode 100644
index bc1bb3d..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MapEntryLite$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MapEntryLite$Metadata.class b/java/kotlin-lite/target/classes/com/google/protobuf/MapEntryLite$Metadata.class
deleted file mode 100644
index 3b69598..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MapEntryLite$Metadata.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MapEntryLite.class b/java/kotlin-lite/target/classes/com/google/protobuf/MapEntryLite.class
deleted file mode 100644
index a57cd89..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MapEntryLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MapFieldLite.class b/java/kotlin-lite/target/classes/com/google/protobuf/MapFieldLite.class
deleted file mode 100644
index 42129d7..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MapFieldLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MapFieldSchema.class b/java/kotlin-lite/target/classes/com/google/protobuf/MapFieldSchema.class
deleted file mode 100644
index 8ef7502..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MapFieldSchema.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MapFieldSchemaLite.class b/java/kotlin-lite/target/classes/com/google/protobuf/MapFieldSchemaLite.class
deleted file mode 100644
index 9ace23c..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MapFieldSchemaLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MapFieldSchemas.class b/java/kotlin-lite/target/classes/com/google/protobuf/MapFieldSchemas.class
deleted file mode 100644
index 0e5c900..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MapFieldSchemas.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MessageInfo.class b/java/kotlin-lite/target/classes/com/google/protobuf/MessageInfo.class
deleted file mode 100644
index 93c461a..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MessageInfo.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MessageInfoFactory.class b/java/kotlin-lite/target/classes/com/google/protobuf/MessageInfoFactory.class
deleted file mode 100644
index 65128b1..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MessageInfoFactory.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MessageLite$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/MessageLite$Builder.class
deleted file mode 100644
index 5148c02..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MessageLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MessageLite.class b/java/kotlin-lite/target/classes/com/google/protobuf/MessageLite.class
deleted file mode 100644
index a309e33..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MessageLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MessageLiteOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/MessageLiteOrBuilder.class
deleted file mode 100644
index 33413d4..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MessageLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MessageLiteToString.class b/java/kotlin-lite/target/classes/com/google/protobuf/MessageLiteToString.class
deleted file mode 100644
index f3db2d2..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MessageLiteToString.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MessageSchema$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/MessageSchema$1.class
deleted file mode 100644
index 2595bc0..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MessageSchema$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MessageSchema.class b/java/kotlin-lite/target/classes/com/google/protobuf/MessageSchema.class
deleted file mode 100644
index 5ca3358..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MessageSchema.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MessageSetSchema.class b/java/kotlin-lite/target/classes/com/google/protobuf/MessageSetSchema.class
deleted file mode 100644
index 16a0e46..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MessageSetSchema.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Method$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/Method$1.class
deleted file mode 100644
index 4792b47..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Method$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Method$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/Method$Builder.class
deleted file mode 100644
index d9daf9e..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Method$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Method.class b/java/kotlin-lite/target/classes/com/google/protobuf/Method.class
deleted file mode 100644
index ab48753..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Method.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MethodOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/MethodOrBuilder.class
deleted file mode 100644
index 89984a2..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MethodOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Mixin$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/Mixin$1.class
deleted file mode 100644
index 4600fd3..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Mixin$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Mixin$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/Mixin$Builder.class
deleted file mode 100644
index 46c3454..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Mixin$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Mixin.class b/java/kotlin-lite/target/classes/com/google/protobuf/Mixin.class
deleted file mode 100644
index a261772..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Mixin.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MixinOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/MixinOrBuilder.class
deleted file mode 100644
index 6c74712..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MixinOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MutabilityOracle$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/MutabilityOracle$1.class
deleted file mode 100644
index 5e32301..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MutabilityOracle$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/MutabilityOracle.class b/java/kotlin-lite/target/classes/com/google/protobuf/MutabilityOracle.class
deleted file mode 100644
index cc3f3d4..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/MutabilityOracle.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/NewInstanceSchema.class b/java/kotlin-lite/target/classes/com/google/protobuf/NewInstanceSchema.class
deleted file mode 100644
index bf08e42..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/NewInstanceSchema.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/NewInstanceSchemaLite.class b/java/kotlin-lite/target/classes/com/google/protobuf/NewInstanceSchemaLite.class
deleted file mode 100644
index 14c004e..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/NewInstanceSchemaLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/NewInstanceSchemas.class b/java/kotlin-lite/target/classes/com/google/protobuf/NewInstanceSchemas.class
deleted file mode 100644
index 0ab924b..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/NewInstanceSchemas.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/NioByteString$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/NioByteString$1.class
deleted file mode 100644
index fad72ce..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/NioByteString$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/NioByteString.class b/java/kotlin-lite/target/classes/com/google/protobuf/NioByteString.class
deleted file mode 100644
index 974b819..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/NioByteString.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/NullValue$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/NullValue$1.class
deleted file mode 100644
index 89fbf74..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/NullValue$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/NullValue$NullValueVerifier.class b/java/kotlin-lite/target/classes/com/google/protobuf/NullValue$NullValueVerifier.class
deleted file mode 100644
index 82c3899..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/NullValue$NullValueVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/NullValue.class b/java/kotlin-lite/target/classes/com/google/protobuf/NullValue.class
deleted file mode 100644
index 79a7e0d..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/NullValue.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/OneofInfo.class b/java/kotlin-lite/target/classes/com/google/protobuf/OneofInfo.class
deleted file mode 100644
index 7dccf4f..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/OneofInfo.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Option$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/Option$1.class
deleted file mode 100644
index 75b8100..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Option$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Option$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/Option$Builder.class
deleted file mode 100644
index 716c9af..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Option$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Option.class b/java/kotlin-lite/target/classes/com/google/protobuf/Option.class
deleted file mode 100644
index e62aa84..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Option.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/OptionOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/OptionOrBuilder.class
deleted file mode 100644
index 9194a11..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/OptionOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Parser.class b/java/kotlin-lite/target/classes/com/google/protobuf/Parser.class
deleted file mode 100644
index df71610..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Parser.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/PrimitiveNonBoxingCollection.class b/java/kotlin-lite/target/classes/com/google/protobuf/PrimitiveNonBoxingCollection.class
deleted file mode 100644
index fd32754..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/PrimitiveNonBoxingCollection.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ProtoSyntax.class b/java/kotlin-lite/target/classes/com/google/protobuf/ProtoSyntax.class
deleted file mode 100644
index 84042d4..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ProtoSyntax.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Protobuf.class b/java/kotlin-lite/target/classes/com/google/protobuf/Protobuf.class
deleted file mode 100644
index 1411d9a..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Protobuf.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ProtobufArrayList.class b/java/kotlin-lite/target/classes/com/google/protobuf/ProtobufArrayList.class
deleted file mode 100644
index 52359f7..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ProtobufArrayList.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ProtobufLists.class b/java/kotlin-lite/target/classes/com/google/protobuf/ProtobufLists.class
deleted file mode 100644
index 3ba32bc..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ProtobufLists.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ProtocolStringList.class b/java/kotlin-lite/target/classes/com/google/protobuf/ProtocolStringList.class
deleted file mode 100644
index 616fe69..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ProtocolStringList.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/RawMessageInfo.class b/java/kotlin-lite/target/classes/com/google/protobuf/RawMessageInfo.class
deleted file mode 100644
index b0eb2a3..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/RawMessageInfo.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Reader.class b/java/kotlin-lite/target/classes/com/google/protobuf/Reader.class
deleted file mode 100644
index 487ed18..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Reader.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/RopeByteString$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/RopeByteString$1.class
deleted file mode 100644
index b8f9d25..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/RopeByteString$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/RopeByteString$Balancer.class b/java/kotlin-lite/target/classes/com/google/protobuf/RopeByteString$Balancer.class
deleted file mode 100644
index da3ca01..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/RopeByteString$Balancer.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/RopeByteString$PieceIterator.class b/java/kotlin-lite/target/classes/com/google/protobuf/RopeByteString$PieceIterator.class
deleted file mode 100644
index 83c5326..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/RopeByteString$PieceIterator.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/RopeByteString$RopeInputStream.class b/java/kotlin-lite/target/classes/com/google/protobuf/RopeByteString$RopeInputStream.class
deleted file mode 100644
index 7451942..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/RopeByteString$RopeInputStream.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/RopeByteString.class b/java/kotlin-lite/target/classes/com/google/protobuf/RopeByteString.class
deleted file mode 100644
index c747049..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/RopeByteString.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Schema.class b/java/kotlin-lite/target/classes/com/google/protobuf/Schema.class
deleted file mode 100644
index d5e0349..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Schema.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/SchemaFactory.class b/java/kotlin-lite/target/classes/com/google/protobuf/SchemaFactory.class
deleted file mode 100644
index d219235..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/SchemaFactory.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/SchemaUtil.class b/java/kotlin-lite/target/classes/com/google/protobuf/SchemaUtil.class
deleted file mode 100644
index 34d1cad..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/SchemaUtil.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$1.class
deleted file mode 100644
index 9b101db..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$DescendingEntryIterator.class b/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$DescendingEntryIterator.class
deleted file mode 100644
index b22a66b..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$DescendingEntryIterator.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$DescendingEntrySet.class b/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$DescendingEntrySet.class
deleted file mode 100644
index 229f851..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$DescendingEntrySet.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$EmptySet$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$EmptySet$1.class
deleted file mode 100644
index 940145c..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$EmptySet$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$EmptySet$2.class b/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$EmptySet$2.class
deleted file mode 100644
index a4d440e..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$EmptySet$2.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$EmptySet.class b/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$EmptySet.class
deleted file mode 100644
index e177d2e..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$EmptySet.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$Entry.class b/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$Entry.class
deleted file mode 100644
index 1ee612a..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$Entry.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$EntryIterator.class b/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$EntryIterator.class
deleted file mode 100644
index 1339a5e..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$EntryIterator.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$EntrySet.class b/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$EntrySet.class
deleted file mode 100644
index 8c08326..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap$EntrySet.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap.class b/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap.class
deleted file mode 100644
index 8d2d436..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/SmallSortedMap.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/SourceContext$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/SourceContext$1.class
deleted file mode 100644
index 62d24b9..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/SourceContext$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/SourceContext$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/SourceContext$Builder.class
deleted file mode 100644
index c4b18f1..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/SourceContext$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/SourceContext.class b/java/kotlin-lite/target/classes/com/google/protobuf/SourceContext.class
deleted file mode 100644
index 966d897..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/SourceContext.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/SourceContextOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/SourceContextOrBuilder.class
deleted file mode 100644
index 887236c..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/SourceContextOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/SourceContextProto.class b/java/kotlin-lite/target/classes/com/google/protobuf/SourceContextProto.class
deleted file mode 100644
index 186aa09..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/SourceContextProto.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/StringValue$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/StringValue$1.class
deleted file mode 100644
index 80c9912..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/StringValue$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/StringValue$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/StringValue$Builder.class
deleted file mode 100644
index ca4e0f3..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/StringValue$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/StringValue.class b/java/kotlin-lite/target/classes/com/google/protobuf/StringValue.class
deleted file mode 100644
index 380d44e..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/StringValue.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/StringValueOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/StringValueOrBuilder.class
deleted file mode 100644
index 1e70a31..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/StringValueOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Struct$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/Struct$1.class
deleted file mode 100644
index 2b7a198..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Struct$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Struct$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/Struct$Builder.class
deleted file mode 100644
index 05a6926..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Struct$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Struct$FieldsDefaultEntryHolder.class b/java/kotlin-lite/target/classes/com/google/protobuf/Struct$FieldsDefaultEntryHolder.class
deleted file mode 100644
index e0f5986..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Struct$FieldsDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Struct.class b/java/kotlin-lite/target/classes/com/google/protobuf/Struct.class
deleted file mode 100644
index fc878ce..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Struct.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/StructOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/StructOrBuilder.class
deleted file mode 100644
index 3d39498..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/StructOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/StructProto.class b/java/kotlin-lite/target/classes/com/google/protobuf/StructProto.class
deleted file mode 100644
index 310ddc8..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/StructProto.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/StructuralMessageInfo$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/StructuralMessageInfo$Builder.class
deleted file mode 100644
index d0daed9..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/StructuralMessageInfo$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/StructuralMessageInfo.class b/java/kotlin-lite/target/classes/com/google/protobuf/StructuralMessageInfo.class
deleted file mode 100644
index 637bcec..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/StructuralMessageInfo.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Syntax$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/Syntax$1.class
deleted file mode 100644
index a16278a..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Syntax$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Syntax$SyntaxVerifier.class b/java/kotlin-lite/target/classes/com/google/protobuf/Syntax$SyntaxVerifier.class
deleted file mode 100644
index c43c1e2..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Syntax$SyntaxVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Syntax.class b/java/kotlin-lite/target/classes/com/google/protobuf/Syntax.class
deleted file mode 100644
index 1fa405e..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Syntax.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/TextFormatEscaper$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/TextFormatEscaper$1.class
deleted file mode 100644
index 67e33cf..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/TextFormatEscaper$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/TextFormatEscaper$2.class b/java/kotlin-lite/target/classes/com/google/protobuf/TextFormatEscaper$2.class
deleted file mode 100644
index e3a88b1..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/TextFormatEscaper$2.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/TextFormatEscaper$ByteSequence.class b/java/kotlin-lite/target/classes/com/google/protobuf/TextFormatEscaper$ByteSequence.class
deleted file mode 100644
index c354dfd..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/TextFormatEscaper$ByteSequence.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/TextFormatEscaper.class b/java/kotlin-lite/target/classes/com/google/protobuf/TextFormatEscaper.class
deleted file mode 100644
index 36714cd..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/TextFormatEscaper.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Timestamp$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/Timestamp$1.class
deleted file mode 100644
index 7414861..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Timestamp$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Timestamp$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/Timestamp$Builder.class
deleted file mode 100644
index 2f0239e..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Timestamp$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Timestamp.class b/java/kotlin-lite/target/classes/com/google/protobuf/Timestamp.class
deleted file mode 100644
index 157cf7d..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Timestamp.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/TimestampOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/TimestampOrBuilder.class
deleted file mode 100644
index c83b78f..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/TimestampOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/TimestampProto.class b/java/kotlin-lite/target/classes/com/google/protobuf/TimestampProto.class
deleted file mode 100644
index 6b37ace..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/TimestampProto.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Type$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/Type$1.class
deleted file mode 100644
index ae52233..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Type$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Type$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/Type$Builder.class
deleted file mode 100644
index dc2c6ca..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Type$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Type.class b/java/kotlin-lite/target/classes/com/google/protobuf/Type.class
deleted file mode 100644
index 41b6a5f..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Type.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/TypeOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/TypeOrBuilder.class
deleted file mode 100644
index 4c86fc9..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/TypeOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/TypeProto.class b/java/kotlin-lite/target/classes/com/google/protobuf/TypeProto.class
deleted file mode 100644
index 546c0c4..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/TypeProto.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UInt32Value$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/UInt32Value$1.class
deleted file mode 100644
index 4a73da7..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UInt32Value$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UInt32Value$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/UInt32Value$Builder.class
deleted file mode 100644
index e7607bd..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UInt32Value$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UInt32Value.class b/java/kotlin-lite/target/classes/com/google/protobuf/UInt32Value.class
deleted file mode 100644
index 754c10c..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UInt32Value.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UInt32ValueOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/UInt32ValueOrBuilder.class
deleted file mode 100644
index f7764ed..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UInt32ValueOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UInt64Value$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/UInt64Value$1.class
deleted file mode 100644
index 70e9efe..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UInt64Value$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UInt64Value$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/UInt64Value$Builder.class
deleted file mode 100644
index c028aab..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UInt64Value$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UInt64Value.class b/java/kotlin-lite/target/classes/com/google/protobuf/UInt64Value.class
deleted file mode 100644
index 1c0e31f..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UInt64Value.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UInt64ValueOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/UInt64ValueOrBuilder.class
deleted file mode 100644
index 1a23c8e..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UInt64ValueOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UninitializedMessageException.class b/java/kotlin-lite/target/classes/com/google/protobuf/UninitializedMessageException.class
deleted file mode 100644
index f5f1bff..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UninitializedMessageException.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UnknownFieldSchema.class b/java/kotlin-lite/target/classes/com/google/protobuf/UnknownFieldSchema.class
deleted file mode 100644
index 1e6d5bf..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UnknownFieldSchema.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UnknownFieldSetLite.class b/java/kotlin-lite/target/classes/com/google/protobuf/UnknownFieldSetLite.class
deleted file mode 100644
index bfc35a9..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UnknownFieldSetLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UnknownFieldSetLiteSchema.class b/java/kotlin-lite/target/classes/com/google/protobuf/UnknownFieldSetLiteSchema.class
deleted file mode 100644
index 39cfb4c..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UnknownFieldSetLiteSchema.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UnmodifiableLazyStringList$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/UnmodifiableLazyStringList$1.class
deleted file mode 100644
index 1121583..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UnmodifiableLazyStringList$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UnmodifiableLazyStringList$2.class b/java/kotlin-lite/target/classes/com/google/protobuf/UnmodifiableLazyStringList$2.class
deleted file mode 100644
index dec6074..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UnmodifiableLazyStringList$2.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UnmodifiableLazyStringList.class b/java/kotlin-lite/target/classes/com/google/protobuf/UnmodifiableLazyStringList.class
deleted file mode 100644
index be251bd2..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UnmodifiableLazyStringList.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UnsafeUtil$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/UnsafeUtil$1.class
deleted file mode 100644
index 11babcf..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UnsafeUtil$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UnsafeUtil$Android32MemoryAccessor.class b/java/kotlin-lite/target/classes/com/google/protobuf/UnsafeUtil$Android32MemoryAccessor.class
deleted file mode 100644
index 1dbe6da..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UnsafeUtil$Android32MemoryAccessor.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UnsafeUtil$Android64MemoryAccessor.class b/java/kotlin-lite/target/classes/com/google/protobuf/UnsafeUtil$Android64MemoryAccessor.class
deleted file mode 100644
index 832f148..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UnsafeUtil$Android64MemoryAccessor.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UnsafeUtil$JvmMemoryAccessor.class b/java/kotlin-lite/target/classes/com/google/protobuf/UnsafeUtil$JvmMemoryAccessor.class
deleted file mode 100644
index 011bec8..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UnsafeUtil$JvmMemoryAccessor.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UnsafeUtil$MemoryAccessor.class b/java/kotlin-lite/target/classes/com/google/protobuf/UnsafeUtil$MemoryAccessor.class
deleted file mode 100644
index 2ad9379..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UnsafeUtil$MemoryAccessor.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/UnsafeUtil.class b/java/kotlin-lite/target/classes/com/google/protobuf/UnsafeUtil.class
deleted file mode 100644
index c9ed08b..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/UnsafeUtil.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Utf8$DecodeUtil.class b/java/kotlin-lite/target/classes/com/google/protobuf/Utf8$DecodeUtil.class
deleted file mode 100644
index 652fc27..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Utf8$DecodeUtil.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Utf8$Processor.class b/java/kotlin-lite/target/classes/com/google/protobuf/Utf8$Processor.class
deleted file mode 100644
index 2b4dde6..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Utf8$Processor.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Utf8$SafeProcessor.class b/java/kotlin-lite/target/classes/com/google/protobuf/Utf8$SafeProcessor.class
deleted file mode 100644
index e103d0e..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Utf8$SafeProcessor.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Utf8$UnpairedSurrogateException.class b/java/kotlin-lite/target/classes/com/google/protobuf/Utf8$UnpairedSurrogateException.class
deleted file mode 100644
index 85975ea..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Utf8$UnpairedSurrogateException.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Utf8$UnsafeProcessor.class b/java/kotlin-lite/target/classes/com/google/protobuf/Utf8$UnsafeProcessor.class
deleted file mode 100644
index 194eb15..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Utf8$UnsafeProcessor.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Utf8.class b/java/kotlin-lite/target/classes/com/google/protobuf/Utf8.class
deleted file mode 100644
index 85afc8a..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Utf8.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Value$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/Value$1.class
deleted file mode 100644
index a959a8f..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Value$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Value$Builder.class b/java/kotlin-lite/target/classes/com/google/protobuf/Value$Builder.class
deleted file mode 100644
index 81d609e..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Value$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Value$KindCase.class b/java/kotlin-lite/target/classes/com/google/protobuf/Value$KindCase.class
deleted file mode 100644
index 0431e1a..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Value$KindCase.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Value.class b/java/kotlin-lite/target/classes/com/google/protobuf/Value.class
deleted file mode 100644
index c728575..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Value.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/ValueOrBuilder.class b/java/kotlin-lite/target/classes/com/google/protobuf/ValueOrBuilder.class
deleted file mode 100644
index 24bdfe5..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/ValueOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$1.class
deleted file mode 100644
index 012fda3..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$FieldType$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$FieldType$1.class
deleted file mode 100644
index cb6bf52..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$FieldType$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$FieldType$2.class b/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$FieldType$2.class
deleted file mode 100644
index e01c846..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$FieldType$2.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$FieldType$3.class b/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$FieldType$3.class
deleted file mode 100644
index 37ecf4a..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$FieldType$3.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$FieldType$4.class b/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$FieldType$4.class
deleted file mode 100644
index 0b51691..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$FieldType$4.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$FieldType.class b/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$FieldType.class
deleted file mode 100644
index 036dddf..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$FieldType.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$JavaType.class b/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$JavaType.class
deleted file mode 100644
index 122f9a1..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$JavaType.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$Utf8Validation$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$Utf8Validation$1.class
deleted file mode 100644
index 30a65a7..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$Utf8Validation$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$Utf8Validation$2.class b/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$Utf8Validation$2.class
deleted file mode 100644
index 5c91de8..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$Utf8Validation$2.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$Utf8Validation$3.class b/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$Utf8Validation$3.class
deleted file mode 100644
index 34d9cb4..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$Utf8Validation$3.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$Utf8Validation.class b/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$Utf8Validation.class
deleted file mode 100644
index 8977081..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat$Utf8Validation.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat.class b/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat.class
deleted file mode 100644
index f8352eb..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/WireFormat.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/WrappersProto.class b/java/kotlin-lite/target/classes/com/google/protobuf/WrappersProto.class
deleted file mode 100644
index 9ded533..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/WrappersProto.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Writer$FieldOrder.class b/java/kotlin-lite/target/classes/com/google/protobuf/Writer$FieldOrder.class
deleted file mode 100644
index 78ccae0..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Writer$FieldOrder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/Writer.class b/java/kotlin-lite/target/classes/com/google/protobuf/Writer.class
deleted file mode 100644
index f0e3534..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/Writer.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/DslList.class b/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/DslList.class
deleted file mode 100644
index 0b2690f..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/DslList.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/DslMap.class b/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/DslMap.class
deleted file mode 100644
index fb484d0..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/DslMap.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/DslProxy.class b/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/DslProxy.class
deleted file mode 100644
index 4dce33a..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/DslProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/ExtendableMessageLiteExtensionsKt.class b/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/ExtendableMessageLiteExtensionsKt.class
deleted file mode 100644
index d410852..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/ExtendableMessageLiteExtensionsKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/ExtensionList.class b/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/ExtensionList.class
deleted file mode 100644
index f299c88..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/ExtensionList.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/OnlyForUseByGeneratedProtoCode.class b/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/OnlyForUseByGeneratedProtoCode.class
deleted file mode 100644
index a70b0fc..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/OnlyForUseByGeneratedProtoCode.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/ProtoDslMarker.class b/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/ProtoDslMarker.class
deleted file mode 100644
index 3ed7d63..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/ProtoDslMarker.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableCollection.class b/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableCollection.class
deleted file mode 100644
index 3391fdf..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableCollection.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableIterator.class b/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableIterator.class
deleted file mode 100644
index fbaa709..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableIterator.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableListIterator.class b/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableListIterator.class
deleted file mode 100644
index 40fee0d..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableListIterator.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableMapEntries$iterator$1.class b/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableMapEntries$iterator$1.class
deleted file mode 100644
index e2670a8..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableMapEntries$iterator$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableMapEntries.class b/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableMapEntries.class
deleted file mode 100644
index e634a02..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableMapEntries.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableMapEntry.class b/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableMapEntry.class
deleted file mode 100644
index 0103112..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableMapEntry.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableSet.class b/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableSet.class
deleted file mode 100644
index fb96843..0000000
--- a/java/kotlin-lite/target/classes/com/google/protobuf/kotlin/UnmodifiableSet.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/classes/google/protobuf/any.proto b/java/kotlin-lite/target/classes/google/protobuf/any.proto
deleted file mode 100644
index 6ed8a23..0000000
--- a/java/kotlin-lite/target/classes/google/protobuf/any.proto
+++ /dev/null
@@ -1,158 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-
-package google.protobuf;
-
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option go_package = "google.golang.org/protobuf/types/known/anypb";
-option java_package = "com.google.protobuf";
-option java_outer_classname = "AnyProto";
-option java_multiple_files = true;
-option objc_class_prefix = "GPB";
-
-// `Any` contains an arbitrary serialized protocol buffer message along with a
-// URL that describes the type of the serialized message.
-//
-// Protobuf library provides support to pack/unpack Any values in the form
-// of utility functions or additional generated methods of the Any type.
-//
-// Example 1: Pack and unpack a message in C++.
-//
-//     Foo foo = ...;
-//     Any any;
-//     any.PackFrom(foo);
-//     ...
-//     if (any.UnpackTo(&foo)) {
-//       ...
-//     }
-//
-// Example 2: Pack and unpack a message in Java.
-//
-//     Foo foo = ...;
-//     Any any = Any.pack(foo);
-//     ...
-//     if (any.is(Foo.class)) {
-//       foo = any.unpack(Foo.class);
-//     }
-//
-//  Example 3: Pack and unpack a message in Python.
-//
-//     foo = Foo(...)
-//     any = Any()
-//     any.Pack(foo)
-//     ...
-//     if any.Is(Foo.DESCRIPTOR):
-//       any.Unpack(foo)
-//       ...
-//
-//  Example 4: Pack and unpack a message in Go
-//
-//      foo := &pb.Foo{...}
-//      any, err := anypb.New(foo)
-//      if err != nil {
-//        ...
-//      }
-//      ...
-//      foo := &pb.Foo{}
-//      if err := any.UnmarshalTo(foo); err != nil {
-//        ...
-//      }
-//
-// The pack methods provided by protobuf library will by default use
-// 'type.googleapis.com/full.type.name' as the type URL and the unpack
-// methods only use the fully qualified type name after the last '/'
-// in the type URL, for example "foo.bar.com/x/y.z" will yield type
-// name "y.z".
-//
-//
-// JSON
-// ====
-// The JSON representation of an `Any` value uses the regular
-// representation of the deserialized, embedded message, with an
-// additional field `@type` which contains the type URL. Example:
-//
-//     package google.profile;
-//     message Person {
-//       string first_name = 1;
-//       string last_name = 2;
-//     }
-//
-//     {
-//       "@type": "type.googleapis.com/google.profile.Person",
-//       "firstName": <string>,
-//       "lastName": <string>
-//     }
-//
-// If the embedded message type is well-known and has a custom JSON
-// representation, that representation will be embedded adding a field
-// `value` which holds the custom JSON in addition to the `@type`
-// field. Example (for message [google.protobuf.Duration][]):
-//
-//     {
-//       "@type": "type.googleapis.com/google.protobuf.Duration",
-//       "value": "1.212s"
-//     }
-//
-message Any {
-  // A URL/resource name that uniquely identifies the type of the serialized
-  // protocol buffer message. This string must contain at least
-  // one "/" character. The last segment of the URL's path must represent
-  // the fully qualified name of the type (as in
-  // `path/google.protobuf.Duration`). The name should be in a canonical form
-  // (e.g., leading "." is not accepted).
-  //
-  // In practice, teams usually precompile into the binary all types that they
-  // expect it to use in the context of Any. However, for URLs which use the
-  // scheme `http`, `https`, or no scheme, one can optionally set up a type
-  // server that maps type URLs to message definitions as follows:
-  //
-  // * If no scheme is provided, `https` is assumed.
-  // * An HTTP GET on the URL must yield a [google.protobuf.Type][]
-  //   value in binary format, or produce an error.
-  // * Applications are allowed to cache lookup results based on the
-  //   URL, or have them precompiled into a binary to avoid any
-  //   lookup. Therefore, binary compatibility needs to be preserved
-  //   on changes to types. (Use versioned type names to manage
-  //   breaking changes.)
-  //
-  // Note: this functionality is not currently available in the official
-  // protobuf release, and it is not used for type URLs beginning with
-  // type.googleapis.com.
-  //
-  // Schemes other than `http`, `https` (or the empty scheme) might be
-  // used with implementation specific semantics.
-  //
-  string type_url = 1;
-
-  // Must be a valid serialized protocol buffer of the above specified type.
-  bytes value = 2;
-}
diff --git a/java/kotlin-lite/target/classes/google/protobuf/api.proto b/java/kotlin-lite/target/classes/google/protobuf/api.proto
deleted file mode 100644
index 3d598fc..0000000
--- a/java/kotlin-lite/target/classes/google/protobuf/api.proto
+++ /dev/null
@@ -1,208 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-
-package google.protobuf;
-
-import "google/protobuf/source_context.proto";
-import "google/protobuf/type.proto";
-
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option java_package = "com.google.protobuf";
-option java_outer_classname = "ApiProto";
-option java_multiple_files = true;
-option objc_class_prefix = "GPB";
-option go_package = "google.golang.org/protobuf/types/known/apipb";
-
-// Api is a light-weight descriptor for an API Interface.
-//
-// Interfaces are also described as "protocol buffer services" in some contexts,
-// such as by the "service" keyword in a .proto file, but they are different
-// from API Services, which represent a concrete implementation of an interface
-// as opposed to simply a description of methods and bindings. They are also
-// sometimes simply referred to as "APIs" in other contexts, such as the name of
-// this message itself. See https://cloud.google.com/apis/design/glossary for
-// detailed terminology.
-message Api {
-  // The fully qualified name of this interface, including package name
-  // followed by the interface's simple name.
-  string name = 1;
-
-  // The methods of this interface, in unspecified order.
-  repeated Method methods = 2;
-
-  // Any metadata attached to the interface.
-  repeated Option options = 3;
-
-  // A version string for this interface. If specified, must have the form
-  // `major-version.minor-version`, as in `1.10`. If the minor version is
-  // omitted, it defaults to zero. If the entire version field is empty, the
-  // major version is derived from the package name, as outlined below. If the
-  // field is not empty, the version in the package name will be verified to be
-  // consistent with what is provided here.
-  //
-  // The versioning schema uses [semantic
-  // versioning](http://semver.org) where the major version number
-  // indicates a breaking change and the minor version an additive,
-  // non-breaking change. Both version numbers are signals to users
-  // what to expect from different versions, and should be carefully
-  // chosen based on the product plan.
-  //
-  // The major version is also reflected in the package name of the
-  // interface, which must end in `v<major-version>`, as in
-  // `google.feature.v1`. For major versions 0 and 1, the suffix can
-  // be omitted. Zero major versions must only be used for
-  // experimental, non-GA interfaces.
-  //
-  //
-  string version = 4;
-
-  // Source context for the protocol buffer service represented by this
-  // message.
-  SourceContext source_context = 5;
-
-  // Included interfaces. See [Mixin][].
-  repeated Mixin mixins = 6;
-
-  // The source syntax of the service.
-  Syntax syntax = 7;
-}
-
-// Method represents a method of an API interface.
-message Method {
-  // The simple name of this method.
-  string name = 1;
-
-  // A URL of the input message type.
-  string request_type_url = 2;
-
-  // If true, the request is streamed.
-  bool request_streaming = 3;
-
-  // The URL of the output message type.
-  string response_type_url = 4;
-
-  // If true, the response is streamed.
-  bool response_streaming = 5;
-
-  // Any metadata attached to the method.
-  repeated Option options = 6;
-
-  // The source syntax of this method.
-  Syntax syntax = 7;
-}
-
-// Declares an API Interface to be included in this interface. The including
-// interface must redeclare all the methods from the included interface, but
-// documentation and options are inherited as follows:
-//
-// - If after comment and whitespace stripping, the documentation
-//   string of the redeclared method is empty, it will be inherited
-//   from the original method.
-//
-// - Each annotation belonging to the service config (http,
-//   visibility) which is not set in the redeclared method will be
-//   inherited.
-//
-// - If an http annotation is inherited, the path pattern will be
-//   modified as follows. Any version prefix will be replaced by the
-//   version of the including interface plus the [root][] path if
-//   specified.
-//
-// Example of a simple mixin:
-//
-//     package google.acl.v1;
-//     service AccessControl {
-//       // Get the underlying ACL object.
-//       rpc GetAcl(GetAclRequest) returns (Acl) {
-//         option (google.api.http).get = "/v1/{resource=**}:getAcl";
-//       }
-//     }
-//
-//     package google.storage.v2;
-//     service Storage {
-//       rpc GetAcl(GetAclRequest) returns (Acl);
-//
-//       // Get a data record.
-//       rpc GetData(GetDataRequest) returns (Data) {
-//         option (google.api.http).get = "/v2/{resource=**}";
-//       }
-//     }
-//
-// Example of a mixin configuration:
-//
-//     apis:
-//     - name: google.storage.v2.Storage
-//       mixins:
-//       - name: google.acl.v1.AccessControl
-//
-// The mixin construct implies that all methods in `AccessControl` are
-// also declared with same name and request/response types in
-// `Storage`. A documentation generator or annotation processor will
-// see the effective `Storage.GetAcl` method after inheriting
-// documentation and annotations as follows:
-//
-//     service Storage {
-//       // Get the underlying ACL object.
-//       rpc GetAcl(GetAclRequest) returns (Acl) {
-//         option (google.api.http).get = "/v2/{resource=**}:getAcl";
-//       }
-//       ...
-//     }
-//
-// Note how the version in the path pattern changed from `v1` to `v2`.
-//
-// If the `root` field in the mixin is specified, it should be a
-// relative path under which inherited HTTP paths are placed. Example:
-//
-//     apis:
-//     - name: google.storage.v2.Storage
-//       mixins:
-//       - name: google.acl.v1.AccessControl
-//         root: acls
-//
-// This implies the following inherited HTTP annotation:
-//
-//     service Storage {
-//       // Get the underlying ACL object.
-//       rpc GetAcl(GetAclRequest) returns (Acl) {
-//         option (google.api.http).get = "/v2/acls/{resource=**}:getAcl";
-//       }
-//       ...
-//     }
-message Mixin {
-  // The fully qualified name of the interface which is included.
-  string name = 1;
-
-  // If non-empty specifies a path under which inherited HTTP paths
-  // are rooted.
-  string root = 2;
-}
diff --git a/java/kotlin-lite/target/classes/google/protobuf/duration.proto b/java/kotlin-lite/target/classes/google/protobuf/duration.proto
deleted file mode 100644
index 81c3e36..0000000
--- a/java/kotlin-lite/target/classes/google/protobuf/duration.proto
+++ /dev/null
@@ -1,116 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-
-package google.protobuf;
-
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option cc_enable_arenas = true;
-option go_package = "google.golang.org/protobuf/types/known/durationpb";
-option java_package = "com.google.protobuf";
-option java_outer_classname = "DurationProto";
-option java_multiple_files = true;
-option objc_class_prefix = "GPB";
-
-// A Duration represents a signed, fixed-length span of time represented
-// as a count of seconds and fractions of seconds at nanosecond
-// resolution. It is independent of any calendar and concepts like "day"
-// or "month". It is related to Timestamp in that the difference between
-// two Timestamp values is a Duration and it can be added or subtracted
-// from a Timestamp. Range is approximately +-10,000 years.
-//
-// # Examples
-//
-// Example 1: Compute Duration from two Timestamps in pseudo code.
-//
-//     Timestamp start = ...;
-//     Timestamp end = ...;
-//     Duration duration = ...;
-//
-//     duration.seconds = end.seconds - start.seconds;
-//     duration.nanos = end.nanos - start.nanos;
-//
-//     if (duration.seconds < 0 && duration.nanos > 0) {
-//       duration.seconds += 1;
-//       duration.nanos -= 1000000000;
-//     } else if (duration.seconds > 0 && duration.nanos < 0) {
-//       duration.seconds -= 1;
-//       duration.nanos += 1000000000;
-//     }
-//
-// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
-//
-//     Timestamp start = ...;
-//     Duration duration = ...;
-//     Timestamp end = ...;
-//
-//     end.seconds = start.seconds + duration.seconds;
-//     end.nanos = start.nanos + duration.nanos;
-//
-//     if (end.nanos < 0) {
-//       end.seconds -= 1;
-//       end.nanos += 1000000000;
-//     } else if (end.nanos >= 1000000000) {
-//       end.seconds += 1;
-//       end.nanos -= 1000000000;
-//     }
-//
-// Example 3: Compute Duration from datetime.timedelta in Python.
-//
-//     td = datetime.timedelta(days=3, minutes=10)
-//     duration = Duration()
-//     duration.FromTimedelta(td)
-//
-// # JSON Mapping
-//
-// In JSON format, the Duration type is encoded as a string rather than an
-// object, where the string ends in the suffix "s" (indicating seconds) and
-// is preceded by the number of seconds, with nanoseconds expressed as
-// fractional seconds. For example, 3 seconds with 0 nanoseconds should be
-// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should
-// be expressed in JSON format as "3.000000001s", and 3 seconds and 1
-// microsecond should be expressed in JSON format as "3.000001s".
-//
-//
-message Duration {
-  // Signed seconds of the span of time. Must be from -315,576,000,000
-  // to +315,576,000,000 inclusive. Note: these bounds are computed from:
-  // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
-  int64 seconds = 1;
-
-  // Signed fractions of a second at nanosecond resolution of the span
-  // of time. Durations less than one second are represented with a 0
-  // `seconds` field and a positive or negative `nanos` field. For durations
-  // of one second or more, a non-zero value for the `nanos` field must be
-  // of the same sign as the `seconds` field. Must be from -999,999,999
-  // to +999,999,999 inclusive.
-  int32 nanos = 2;
-}
diff --git a/java/kotlin-lite/target/classes/google/protobuf/empty.proto b/java/kotlin-lite/target/classes/google/protobuf/empty.proto
deleted file mode 100644
index 5f992de..0000000
--- a/java/kotlin-lite/target/classes/google/protobuf/empty.proto
+++ /dev/null
@@ -1,52 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-
-package google.protobuf;
-
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option go_package = "google.golang.org/protobuf/types/known/emptypb";
-option java_package = "com.google.protobuf";
-option java_outer_classname = "EmptyProto";
-option java_multiple_files = true;
-option objc_class_prefix = "GPB";
-option cc_enable_arenas = true;
-
-// A generic empty message that you can re-use to avoid defining duplicated
-// empty messages in your APIs. A typical example is to use it as the request
-// or the response type of an API method. For instance:
-//
-//     service Foo {
-//       rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
-//     }
-//
-// The JSON representation for `Empty` is empty JSON object `{}`.
-message Empty {}
diff --git a/java/kotlin-lite/target/classes/google/protobuf/field_mask.proto b/java/kotlin-lite/target/classes/google/protobuf/field_mask.proto
deleted file mode 100644
index 6b5104f..0000000
--- a/java/kotlin-lite/target/classes/google/protobuf/field_mask.proto
+++ /dev/null
@@ -1,245 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-
-package google.protobuf;
-
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option java_package = "com.google.protobuf";
-option java_outer_classname = "FieldMaskProto";
-option java_multiple_files = true;
-option objc_class_prefix = "GPB";
-option go_package = "google.golang.org/protobuf/types/known/fieldmaskpb";
-option cc_enable_arenas = true;
-
-// `FieldMask` represents a set of symbolic field paths, for example:
-//
-//     paths: "f.a"
-//     paths: "f.b.d"
-//
-// Here `f` represents a field in some root message, `a` and `b`
-// fields in the message found in `f`, and `d` a field found in the
-// message in `f.b`.
-//
-// Field masks are used to specify a subset of fields that should be
-// returned by a get operation or modified by an update operation.
-// Field masks also have a custom JSON encoding (see below).
-//
-// # Field Masks in Projections
-//
-// When used in the context of a projection, a response message or
-// sub-message is filtered by the API to only contain those fields as
-// specified in the mask. For example, if the mask in the previous
-// example is applied to a response message as follows:
-//
-//     f {
-//       a : 22
-//       b {
-//         d : 1
-//         x : 2
-//       }
-//       y : 13
-//     }
-//     z: 8
-//
-// The result will not contain specific values for fields x,y and z
-// (their value will be set to the default, and omitted in proto text
-// output):
-//
-//
-//     f {
-//       a : 22
-//       b {
-//         d : 1
-//       }
-//     }
-//
-// A repeated field is not allowed except at the last position of a
-// paths string.
-//
-// If a FieldMask object is not present in a get operation, the
-// operation applies to all fields (as if a FieldMask of all fields
-// had been specified).
-//
-// Note that a field mask does not necessarily apply to the
-// top-level response message. In case of a REST get operation, the
-// field mask applies directly to the response, but in case of a REST
-// list operation, the mask instead applies to each individual message
-// in the returned resource list. In case of a REST custom method,
-// other definitions may be used. Where the mask applies will be
-// clearly documented together with its declaration in the API.  In
-// any case, the effect on the returned resource/resources is required
-// behavior for APIs.
-//
-// # Field Masks in Update Operations
-//
-// A field mask in update operations specifies which fields of the
-// targeted resource are going to be updated. The API is required
-// to only change the values of the fields as specified in the mask
-// and leave the others untouched. If a resource is passed in to
-// describe the updated values, the API ignores the values of all
-// fields not covered by the mask.
-//
-// If a repeated field is specified for an update operation, new values will
-// be appended to the existing repeated field in the target resource. Note that
-// a repeated field is only allowed in the last position of a `paths` string.
-//
-// If a sub-message is specified in the last position of the field mask for an
-// update operation, then new value will be merged into the existing sub-message
-// in the target resource.
-//
-// For example, given the target message:
-//
-//     f {
-//       b {
-//         d: 1
-//         x: 2
-//       }
-//       c: [1]
-//     }
-//
-// And an update message:
-//
-//     f {
-//       b {
-//         d: 10
-//       }
-//       c: [2]
-//     }
-//
-// then if the field mask is:
-//
-//  paths: ["f.b", "f.c"]
-//
-// then the result will be:
-//
-//     f {
-//       b {
-//         d: 10
-//         x: 2
-//       }
-//       c: [1, 2]
-//     }
-//
-// An implementation may provide options to override this default behavior for
-// repeated and message fields.
-//
-// In order to reset a field's value to the default, the field must
-// be in the mask and set to the default value in the provided resource.
-// Hence, in order to reset all fields of a resource, provide a default
-// instance of the resource and set all fields in the mask, or do
-// not provide a mask as described below.
-//
-// If a field mask is not present on update, the operation applies to
-// all fields (as if a field mask of all fields has been specified).
-// Note that in the presence of schema evolution, this may mean that
-// fields the client does not know and has therefore not filled into
-// the request will be reset to their default. If this is unwanted
-// behavior, a specific service may require a client to always specify
-// a field mask, producing an error if not.
-//
-// As with get operations, the location of the resource which
-// describes the updated values in the request message depends on the
-// operation kind. In any case, the effect of the field mask is
-// required to be honored by the API.
-//
-// ## Considerations for HTTP REST
-//
-// The HTTP kind of an update operation which uses a field mask must
-// be set to PATCH instead of PUT in order to satisfy HTTP semantics
-// (PUT must only be used for full updates).
-//
-// # JSON Encoding of Field Masks
-//
-// In JSON, a field mask is encoded as a single string where paths are
-// separated by a comma. Fields name in each path are converted
-// to/from lower-camel naming conventions.
-//
-// As an example, consider the following message declarations:
-//
-//     message Profile {
-//       User user = 1;
-//       Photo photo = 2;
-//     }
-//     message User {
-//       string display_name = 1;
-//       string address = 2;
-//     }
-//
-// In proto a field mask for `Profile` may look as such:
-//
-//     mask {
-//       paths: "user.display_name"
-//       paths: "photo"
-//     }
-//
-// In JSON, the same mask is represented as below:
-//
-//     {
-//       mask: "user.displayName,photo"
-//     }
-//
-// # Field Masks and Oneof Fields
-//
-// Field masks treat fields in oneofs just as regular fields. Consider the
-// following message:
-//
-//     message SampleMessage {
-//       oneof test_oneof {
-//         string name = 4;
-//         SubMessage sub_message = 9;
-//       }
-//     }
-//
-// The field mask can be:
-//
-//     mask {
-//       paths: "name"
-//     }
-//
-// Or:
-//
-//     mask {
-//       paths: "sub_message"
-//     }
-//
-// Note that oneof type names ("test_oneof" in this case) cannot be used in
-// paths.
-//
-// ## Field Mask Verification
-//
-// The implementation of any API method which has a FieldMask type field in the
-// request should verify the included field paths, and return an
-// `INVALID_ARGUMENT` error if any path is unmappable.
-message FieldMask {
-  // The set of field mask paths.
-  repeated string paths = 1;
-}
diff --git a/java/kotlin-lite/target/classes/google/protobuf/source_context.proto b/java/kotlin-lite/target/classes/google/protobuf/source_context.proto
deleted file mode 100644
index 06bfc43..0000000
--- a/java/kotlin-lite/target/classes/google/protobuf/source_context.proto
+++ /dev/null
@@ -1,48 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-
-package google.protobuf;
-
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option java_package = "com.google.protobuf";
-option java_outer_classname = "SourceContextProto";
-option java_multiple_files = true;
-option objc_class_prefix = "GPB";
-option go_package = "google.golang.org/protobuf/types/known/sourcecontextpb";
-
-// `SourceContext` represents information about the source of a
-// protobuf element, like the file in which it is defined.
-message SourceContext {
-  // The path-qualified name of the .proto file that contained the associated
-  // protobuf element.  For example: `"google/protobuf/source_context.proto"`.
-  string file_name = 1;
-}
diff --git a/java/kotlin-lite/target/classes/google/protobuf/struct.proto b/java/kotlin-lite/target/classes/google/protobuf/struct.proto
deleted file mode 100644
index 545215c..0000000
--- a/java/kotlin-lite/target/classes/google/protobuf/struct.proto
+++ /dev/null
@@ -1,95 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-
-package google.protobuf;
-
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option cc_enable_arenas = true;
-option go_package = "google.golang.org/protobuf/types/known/structpb";
-option java_package = "com.google.protobuf";
-option java_outer_classname = "StructProto";
-option java_multiple_files = true;
-option objc_class_prefix = "GPB";
-
-// `Struct` represents a structured data value, consisting of fields
-// which map to dynamically typed values. In some languages, `Struct`
-// might be supported by a native representation. For example, in
-// scripting languages like JS a struct is represented as an
-// object. The details of that representation are described together
-// with the proto support for the language.
-//
-// The JSON representation for `Struct` is JSON object.
-message Struct {
-  // Unordered map of dynamically typed values.
-  map<string, Value> fields = 1;
-}
-
-// `Value` represents a dynamically typed value which can be either
-// null, a number, a string, a boolean, a recursive struct value, or a
-// list of values. A producer of value is expected to set one of that
-// variants, absence of any variant indicates an error.
-//
-// The JSON representation for `Value` is JSON value.
-message Value {
-  // The kind of value.
-  oneof kind {
-    // Represents a null value.
-    NullValue null_value = 1;
-    // Represents a double value.
-    double number_value = 2;
-    // Represents a string value.
-    string string_value = 3;
-    // Represents a boolean value.
-    bool bool_value = 4;
-    // Represents a structured value.
-    Struct struct_value = 5;
-    // Represents a repeated `Value`.
-    ListValue list_value = 6;
-  }
-}
-
-// `NullValue` is a singleton enumeration to represent the null value for the
-// `Value` type union.
-//
-//  The JSON representation for `NullValue` is JSON `null`.
-enum NullValue {
-  // Null value.
-  NULL_VALUE = 0;
-}
-
-// `ListValue` is a wrapper around a repeated field of values.
-//
-// The JSON representation for `ListValue` is JSON array.
-message ListValue {
-  // Repeated field of dynamically typed values.
-  repeated Value values = 1;
-}
diff --git a/java/kotlin-lite/target/classes/google/protobuf/timestamp.proto b/java/kotlin-lite/target/classes/google/protobuf/timestamp.proto
deleted file mode 100644
index 3b2df6d..0000000
--- a/java/kotlin-lite/target/classes/google/protobuf/timestamp.proto
+++ /dev/null
@@ -1,147 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-
-package google.protobuf;
-
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option cc_enable_arenas = true;
-option go_package = "google.golang.org/protobuf/types/known/timestamppb";
-option java_package = "com.google.protobuf";
-option java_outer_classname = "TimestampProto";
-option java_multiple_files = true;
-option objc_class_prefix = "GPB";
-
-// A Timestamp represents a point in time independent of any time zone or local
-// calendar, encoded as a count of seconds and fractions of seconds at
-// nanosecond resolution. The count is relative to an epoch at UTC midnight on
-// January 1, 1970, in the proleptic Gregorian calendar which extends the
-// Gregorian calendar backwards to year one.
-//
-// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap
-// second table is needed for interpretation, using a [24-hour linear
-// smear](https://developers.google.com/time/smear).
-//
-// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By
-// restricting to that range, we ensure that we can convert to and from [RFC
-// 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings.
-//
-// # Examples
-//
-// Example 1: Compute Timestamp from POSIX `time()`.
-//
-//     Timestamp timestamp;
-//     timestamp.set_seconds(time(NULL));
-//     timestamp.set_nanos(0);
-//
-// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
-//
-//     struct timeval tv;
-//     gettimeofday(&tv, NULL);
-//
-//     Timestamp timestamp;
-//     timestamp.set_seconds(tv.tv_sec);
-//     timestamp.set_nanos(tv.tv_usec * 1000);
-//
-// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
-//
-//     FILETIME ft;
-//     GetSystemTimeAsFileTime(&ft);
-//     UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
-//
-//     // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
-//     // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
-//     Timestamp timestamp;
-//     timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
-//     timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
-//
-// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
-//
-//     long millis = System.currentTimeMillis();
-//
-//     Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
-//         .setNanos((int) ((millis % 1000) * 1000000)).build();
-//
-//
-// Example 5: Compute Timestamp from Java `Instant.now()`.
-//
-//     Instant now = Instant.now();
-//
-//     Timestamp timestamp =
-//         Timestamp.newBuilder().setSeconds(now.getEpochSecond())
-//             .setNanos(now.getNano()).build();
-//
-//
-// Example 6: Compute Timestamp from current time in Python.
-//
-//     timestamp = Timestamp()
-//     timestamp.GetCurrentTime()
-//
-// # JSON Mapping
-//
-// In JSON format, the Timestamp type is encoded as a string in the
-// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
-// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
-// where {year} is always expressed using four digits while {month}, {day},
-// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
-// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
-// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
-// is required. A proto3 JSON serializer should always use UTC (as indicated by
-// "Z") when printing the Timestamp type and a proto3 JSON parser should be
-// able to accept both UTC and other timezones (as indicated by an offset).
-//
-// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
-// 01:30 UTC on January 15, 2017.
-//
-// In JavaScript, one can convert a Date object to this format using the
-// standard
-// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
-// method. In Python, a standard `datetime.datetime` object can be converted
-// to this format using
-// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with
-// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use
-// the Joda Time's [`ISODateTimeFormat.dateTime()`](
-// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D
-// ) to obtain a formatter capable of generating timestamps in this format.
-//
-//
-message Timestamp {
-  // Represents seconds of UTC time since Unix epoch
-  // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
-  // 9999-12-31T23:59:59Z inclusive.
-  int64 seconds = 1;
-
-  // Non-negative fractions of a second at nanosecond resolution. Negative
-  // second values with fractions must still have non-negative nanos values
-  // that count forward in time. Must be from 0 to 999,999,999
-  // inclusive.
-  int32 nanos = 2;
-}
diff --git a/java/kotlin-lite/target/classes/google/protobuf/type.proto b/java/kotlin-lite/target/classes/google/protobuf/type.proto
deleted file mode 100644
index d3f6a68..0000000
--- a/java/kotlin-lite/target/classes/google/protobuf/type.proto
+++ /dev/null
@@ -1,187 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-
-package google.protobuf;
-
-import "google/protobuf/any.proto";
-import "google/protobuf/source_context.proto";
-
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option cc_enable_arenas = true;
-option java_package = "com.google.protobuf";
-option java_outer_classname = "TypeProto";
-option java_multiple_files = true;
-option objc_class_prefix = "GPB";
-option go_package = "google.golang.org/protobuf/types/known/typepb";
-
-// A protocol buffer message type.
-message Type {
-  // The fully qualified message name.
-  string name = 1;
-  // The list of fields.
-  repeated Field fields = 2;
-  // The list of types appearing in `oneof` definitions in this type.
-  repeated string oneofs = 3;
-  // The protocol buffer options.
-  repeated Option options = 4;
-  // The source context.
-  SourceContext source_context = 5;
-  // The source syntax.
-  Syntax syntax = 6;
-}
-
-// A single field of a message type.
-message Field {
-  // Basic field types.
-  enum Kind {
-    // Field type unknown.
-    TYPE_UNKNOWN = 0;
-    // Field type double.
-    TYPE_DOUBLE = 1;
-    // Field type float.
-    TYPE_FLOAT = 2;
-    // Field type int64.
-    TYPE_INT64 = 3;
-    // Field type uint64.
-    TYPE_UINT64 = 4;
-    // Field type int32.
-    TYPE_INT32 = 5;
-    // Field type fixed64.
-    TYPE_FIXED64 = 6;
-    // Field type fixed32.
-    TYPE_FIXED32 = 7;
-    // Field type bool.
-    TYPE_BOOL = 8;
-    // Field type string.
-    TYPE_STRING = 9;
-    // Field type group. Proto2 syntax only, and deprecated.
-    TYPE_GROUP = 10;
-    // Field type message.
-    TYPE_MESSAGE = 11;
-    // Field type bytes.
-    TYPE_BYTES = 12;
-    // Field type uint32.
-    TYPE_UINT32 = 13;
-    // Field type enum.
-    TYPE_ENUM = 14;
-    // Field type sfixed32.
-    TYPE_SFIXED32 = 15;
-    // Field type sfixed64.
-    TYPE_SFIXED64 = 16;
-    // Field type sint32.
-    TYPE_SINT32 = 17;
-    // Field type sint64.
-    TYPE_SINT64 = 18;
-  }
-
-  // Whether a field is optional, required, or repeated.
-  enum Cardinality {
-    // For fields with unknown cardinality.
-    CARDINALITY_UNKNOWN = 0;
-    // For optional fields.
-    CARDINALITY_OPTIONAL = 1;
-    // For required fields. Proto2 syntax only.
-    CARDINALITY_REQUIRED = 2;
-    // For repeated fields.
-    CARDINALITY_REPEATED = 3;
-  }
-
-  // The field type.
-  Kind kind = 1;
-  // The field cardinality.
-  Cardinality cardinality = 2;
-  // The field number.
-  int32 number = 3;
-  // The field name.
-  string name = 4;
-  // The field type URL, without the scheme, for message or enumeration
-  // types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
-  string type_url = 6;
-  // The index of the field type in `Type.oneofs`, for message or enumeration
-  // types. The first type has index 1; zero means the type is not in the list.
-  int32 oneof_index = 7;
-  // Whether to use alternative packed wire representation.
-  bool packed = 8;
-  // The protocol buffer options.
-  repeated Option options = 9;
-  // The field JSON name.
-  string json_name = 10;
-  // The string value of the default value of this field. Proto2 syntax only.
-  string default_value = 11;
-}
-
-// Enum type definition.
-message Enum {
-  // Enum type name.
-  string name = 1;
-  // Enum value definitions.
-  repeated EnumValue enumvalue = 2;
-  // Protocol buffer options.
-  repeated Option options = 3;
-  // The source context.
-  SourceContext source_context = 4;
-  // The source syntax.
-  Syntax syntax = 5;
-}
-
-// Enum value definition.
-message EnumValue {
-  // Enum value name.
-  string name = 1;
-  // Enum value number.
-  int32 number = 2;
-  // Protocol buffer options.
-  repeated Option options = 3;
-}
-
-// A protocol buffer option, which can be attached to a message, field,
-// enumeration, etc.
-message Option {
-  // The option's name. For protobuf built-in options (options defined in
-  // descriptor.proto), this is the short name. For example, `"map_entry"`.
-  // For custom options, it should be the fully-qualified name. For example,
-  // `"google.api.http"`.
-  string name = 1;
-  // The option's value packed in an Any message. If the value is a primitive,
-  // the corresponding wrapper type defined in google/protobuf/wrappers.proto
-  // should be used. If the value is an enum, it should be stored as an int32
-  // value using the google.protobuf.Int32Value type.
-  Any value = 2;
-}
-
-// The syntax in which a protocol buffer element is defined.
-enum Syntax {
-  // Syntax `proto2`.
-  SYNTAX_PROTO2 = 0;
-  // Syntax `proto3`.
-  SYNTAX_PROTO3 = 1;
-}
diff --git a/java/kotlin-lite/target/classes/google/protobuf/wrappers.proto b/java/kotlin-lite/target/classes/google/protobuf/wrappers.proto
deleted file mode 100644
index d49dd53..0000000
--- a/java/kotlin-lite/target/classes/google/protobuf/wrappers.proto
+++ /dev/null
@@ -1,123 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Wrappers for primitive (non-message) types. These types are useful
-// for embedding primitives in the `google.protobuf.Any` type and for places
-// where we need to distinguish between the absence of a primitive
-// typed field and its default value.
-//
-// These wrappers have no meaningful use within repeated fields as they lack
-// the ability to detect presence on individual elements.
-// These wrappers have no meaningful use within a map or a oneof since
-// individual entries of a map or fields of a oneof can already detect presence.
-
-syntax = "proto3";
-
-package google.protobuf;
-
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option cc_enable_arenas = true;
-option go_package = "google.golang.org/protobuf/types/known/wrapperspb";
-option java_package = "com.google.protobuf";
-option java_outer_classname = "WrappersProto";
-option java_multiple_files = true;
-option objc_class_prefix = "GPB";
-
-// Wrapper message for `double`.
-//
-// The JSON representation for `DoubleValue` is JSON number.
-message DoubleValue {
-  // The double value.
-  double value = 1;
-}
-
-// Wrapper message for `float`.
-//
-// The JSON representation for `FloatValue` is JSON number.
-message FloatValue {
-  // The float value.
-  float value = 1;
-}
-
-// Wrapper message for `int64`.
-//
-// The JSON representation for `Int64Value` is JSON string.
-message Int64Value {
-  // The int64 value.
-  int64 value = 1;
-}
-
-// Wrapper message for `uint64`.
-//
-// The JSON representation for `UInt64Value` is JSON string.
-message UInt64Value {
-  // The uint64 value.
-  uint64 value = 1;
-}
-
-// Wrapper message for `int32`.
-//
-// The JSON representation for `Int32Value` is JSON number.
-message Int32Value {
-  // The int32 value.
-  int32 value = 1;
-}
-
-// Wrapper message for `uint32`.
-//
-// The JSON representation for `UInt32Value` is JSON number.
-message UInt32Value {
-  // The uint32 value.
-  uint32 value = 1;
-}
-
-// Wrapper message for `bool`.
-//
-// The JSON representation for `BoolValue` is JSON `true` and `false`.
-message BoolValue {
-  // The bool value.
-  bool value = 1;
-}
-
-// Wrapper message for `string`.
-//
-// The JSON representation for `StringValue` is JSON string.
-message StringValue {
-  // The string value.
-  string value = 1;
-}
-
-// Wrapper message for `bytes`.
-//
-// The JSON representation for `BytesValue` is JSON string.
-message BytesValue {
-  // The bytes value.
-  bytes value = 1;
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/AbstractMessageLite.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/AbstractMessageLite.java
deleted file mode 100644
index 4e3cf42..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/AbstractMessageLite.java
+++ /dev/null
@@ -1,439 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.Internal.checkNotNull;
-
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * A partial implementation of the {@link MessageLite} interface which implements as many methods of
- * that interface as possible in terms of other methods.
- *
- * @author kenton@google.com Kenton Varda
- */
-public abstract class AbstractMessageLite<
-        MessageType extends AbstractMessageLite<MessageType, BuilderType>,
-        BuilderType extends AbstractMessageLite.Builder<MessageType, BuilderType>>
-    implements MessageLite {
-  protected int memoizedHashCode = 0;
-
-  @Override
-  public ByteString toByteString() {
-    try {
-      final ByteString.CodedBuilder out = ByteString.newCodedBuilder(getSerializedSize());
-      writeTo(out.getCodedOutput());
-      return out.build();
-    } catch (IOException e) {
-      throw new RuntimeException(getSerializingExceptionMessage("ByteString"), e);
-    }
-  }
-
-  @Override
-  public byte[] toByteArray() {
-    try {
-      final byte[] result = new byte[getSerializedSize()];
-      final CodedOutputStream output = CodedOutputStream.newInstance(result);
-      writeTo(output);
-      output.checkNoSpaceLeft();
-      return result;
-    } catch (IOException e) {
-      throw new RuntimeException(getSerializingExceptionMessage("byte array"), e);
-    }
-  }
-
-  @Override
-  public void writeTo(final OutputStream output) throws IOException {
-    final int bufferSize = CodedOutputStream.computePreferredBufferSize(getSerializedSize());
-    final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output, bufferSize);
-    writeTo(codedOutput);
-    codedOutput.flush();
-  }
-
-  @Override
-  public void writeDelimitedTo(final OutputStream output) throws IOException {
-    final int serialized = getSerializedSize();
-    final int bufferSize =
-        CodedOutputStream.computePreferredBufferSize(
-            CodedOutputStream.computeRawVarint32Size(serialized) + serialized);
-    final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output, bufferSize);
-    codedOutput.writeRawVarint32(serialized);
-    writeTo(codedOutput);
-    codedOutput.flush();
-  }
-
-  // We'd like these to be abstract but some folks are extending this class directly. They shouldn't
-  // be doing that and they should feel bad.
-  int getMemoizedSerializedSize() {
-    throw new UnsupportedOperationException();
-  }
-
-  void setMemoizedSerializedSize(int size) {
-    throw new UnsupportedOperationException();
-  }
-
-
-  int getSerializedSize(Schema schema) {
-    int memoizedSerializedSize = getMemoizedSerializedSize();
-    if (memoizedSerializedSize == -1) {
-      memoizedSerializedSize = schema.getSerializedSize(this);
-      setMemoizedSerializedSize(memoizedSerializedSize);
-    }
-    return memoizedSerializedSize;
-  }
-
-  /** Package private helper method for AbstractParser to create UninitializedMessageException. */
-  UninitializedMessageException newUninitializedMessageException() {
-    return new UninitializedMessageException(this);
-  }
-
-  private String getSerializingExceptionMessage(String target) {
-    return "Serializing "
-        + getClass().getName()
-        + " to a "
-        + target
-        + " threw an IOException (should never happen).";
-  }
-
-  protected static void checkByteStringIsUtf8(ByteString byteString)
-      throws IllegalArgumentException {
-    if (!byteString.isValidUtf8()) {
-      throw new IllegalArgumentException("Byte string is not UTF-8.");
-    }
-  }
-
-  // For binary compatibility
-  @Deprecated
-  protected static <T> void addAll(final Iterable<T> values, final Collection<? super T> list) {
-    Builder.addAll(values, (List) list);
-  }
-
-  protected static <T> void addAll(final Iterable<T> values, final List<? super T> list) {
-    Builder.addAll(values, list);
-  }
-
-  /** Interface for an enum which signifies which field in a {@code oneof} was specified. */
-  protected interface InternalOneOfEnum {
-    /**
-     * Retrieves the field number of the field which was set in this {@code oneof}, or {@code 0} if
-     * none were.
-     */
-    int getNumber();
-  }
-
-  /**
-   * A partial implementation of the {@link Message.Builder} interface which implements as many
-   * methods of that interface as possible in terms of other methods.
-   */
-  @SuppressWarnings("unchecked")
-  public abstract static class Builder<
-          MessageType extends AbstractMessageLite<MessageType, BuilderType>,
-          BuilderType extends Builder<MessageType, BuilderType>>
-      implements MessageLite.Builder {
-    // The compiler produces an error if this is not declared explicitly.
-    @Override
-    public abstract BuilderType clone();
-
-    @Override
-    public BuilderType mergeFrom(final CodedInputStream input) throws IOException {
-      return mergeFrom(input, ExtensionRegistryLite.getEmptyRegistry());
-    }
-
-    // Re-defined here for return type covariance.
-    @Override
-    public abstract BuilderType mergeFrom(
-        final CodedInputStream input, final ExtensionRegistryLite extensionRegistry)
-        throws IOException;
-
-    @Override
-    public BuilderType mergeFrom(final ByteString data) throws InvalidProtocolBufferException {
-      try {
-        final CodedInputStream input = data.newCodedInput();
-        mergeFrom(input);
-        input.checkLastTagWas(0);
-        return (BuilderType) this;
-      } catch (InvalidProtocolBufferException e) {
-        throw e;
-      } catch (IOException e) {
-        throw new RuntimeException(getReadingExceptionMessage("ByteString"), e);
-      }
-    }
-
-    @Override
-    public BuilderType mergeFrom(
-        final ByteString data, final ExtensionRegistryLite extensionRegistry)
-        throws InvalidProtocolBufferException {
-      try {
-        final CodedInputStream input = data.newCodedInput();
-        mergeFrom(input, extensionRegistry);
-        input.checkLastTagWas(0);
-        return (BuilderType) this;
-      } catch (InvalidProtocolBufferException e) {
-        throw e;
-      } catch (IOException e) {
-        throw new RuntimeException(getReadingExceptionMessage("ByteString"), e);
-      }
-    }
-
-    @Override
-    public BuilderType mergeFrom(final byte[] data) throws InvalidProtocolBufferException {
-      return mergeFrom(data, 0, data.length);
-    }
-
-    @Override
-    public BuilderType mergeFrom(final byte[] data, final int off, final int len)
-        throws InvalidProtocolBufferException {
-      try {
-        final CodedInputStream input = CodedInputStream.newInstance(data, off, len);
-        mergeFrom(input);
-        input.checkLastTagWas(0);
-        return (BuilderType) this;
-      } catch (InvalidProtocolBufferException e) {
-        throw e;
-      } catch (IOException e) {
-        throw new RuntimeException(getReadingExceptionMessage("byte array"), e);
-      }
-    }
-
-    @Override
-    public BuilderType mergeFrom(final byte[] data, final ExtensionRegistryLite extensionRegistry)
-        throws InvalidProtocolBufferException {
-      return mergeFrom(data, 0, data.length, extensionRegistry);
-    }
-
-    @Override
-    public BuilderType mergeFrom(
-        final byte[] data,
-        final int off,
-        final int len,
-        final ExtensionRegistryLite extensionRegistry)
-        throws InvalidProtocolBufferException {
-      try {
-        final CodedInputStream input = CodedInputStream.newInstance(data, off, len);
-        mergeFrom(input, extensionRegistry);
-        input.checkLastTagWas(0);
-        return (BuilderType) this;
-      } catch (InvalidProtocolBufferException e) {
-        throw e;
-      } catch (IOException e) {
-        throw new RuntimeException(getReadingExceptionMessage("byte array"), e);
-      }
-    }
-
-    @Override
-    public BuilderType mergeFrom(final InputStream input) throws IOException {
-      final CodedInputStream codedInput = CodedInputStream.newInstance(input);
-      mergeFrom(codedInput);
-      codedInput.checkLastTagWas(0);
-      return (BuilderType) this;
-    }
-
-    @Override
-    public BuilderType mergeFrom(
-        final InputStream input, final ExtensionRegistryLite extensionRegistry) throws IOException {
-      final CodedInputStream codedInput = CodedInputStream.newInstance(input);
-      mergeFrom(codedInput, extensionRegistry);
-      codedInput.checkLastTagWas(0);
-      return (BuilderType) this;
-    }
-
-    /**
-     * An InputStream implementations which reads from some other InputStream but is limited to a
-     * particular number of bytes. Used by mergeDelimitedFrom(). This is intentionally
-     * package-private so that UnknownFieldSet can share it.
-     */
-    static final class LimitedInputStream extends FilterInputStream {
-      private int limit;
-
-      LimitedInputStream(InputStream in, int limit) {
-        super(in);
-        this.limit = limit;
-      }
-
-      @Override
-      public int available() throws IOException {
-        return Math.min(super.available(), limit);
-      }
-
-      @Override
-      public int read() throws IOException {
-        if (limit <= 0) {
-          return -1;
-        }
-        final int result = super.read();
-        if (result >= 0) {
-          --limit;
-        }
-        return result;
-      }
-
-      @Override
-      public int read(final byte[] b, final int off, int len) throws IOException {
-        if (limit <= 0) {
-          return -1;
-        }
-        len = Math.min(len, limit);
-        final int result = super.read(b, off, len);
-        if (result >= 0) {
-          limit -= result;
-        }
-        return result;
-      }
-
-      @Override
-      public long skip(final long n) throws IOException {
-        final long result = super.skip(Math.min(n, limit));
-        if (result >= 0) {
-          limit -= result;
-        }
-        return result;
-      }
-    }
-
-    @Override
-    public boolean mergeDelimitedFrom(
-        final InputStream input, final ExtensionRegistryLite extensionRegistry) throws IOException {
-      final int firstByte = input.read();
-      if (firstByte == -1) {
-        return false;
-      }
-      final int size = CodedInputStream.readRawVarint32(firstByte, input);
-      final InputStream limitedInput = new LimitedInputStream(input, size);
-      mergeFrom(limitedInput, extensionRegistry);
-      return true;
-    }
-
-    @Override
-    public boolean mergeDelimitedFrom(final InputStream input) throws IOException {
-      return mergeDelimitedFrom(input, ExtensionRegistryLite.getEmptyRegistry());
-    }
-
-    @Override
-    @SuppressWarnings("unchecked") // isInstance takes care of this
-    public BuilderType mergeFrom(final MessageLite other) {
-      if (!getDefaultInstanceForType().getClass().isInstance(other)) {
-        throw new IllegalArgumentException(
-            "mergeFrom(MessageLite) can only merge messages of the same type.");
-      }
-
-      return internalMergeFrom((MessageType) other);
-    }
-
-    protected abstract BuilderType internalMergeFrom(MessageType message);
-
-    private String getReadingExceptionMessage(String target) {
-      return "Reading "
-          + getClass().getName()
-          + " from a "
-          + target
-          + " threw an IOException (should never happen).";
-    }
-
-    // We check nulls as we iterate to avoid iterating over values twice.
-    private static <T> void addAllCheckingNulls(Iterable<T> values, List<? super T> list) {
-      if (list instanceof ArrayList && values instanceof Collection) {
-        ((ArrayList<T>) list).ensureCapacity(list.size() + ((Collection<T>) values).size());
-      }
-      int begin = list.size();
-      for (T value : values) {
-        if (value == null) {
-          // encountered a null value so we must undo our modifications prior to throwing
-          String message = "Element at index " + (list.size() - begin) + " is null.";
-          for (int i = list.size() - 1; i >= begin; i--) {
-            list.remove(i);
-          }
-          throw new NullPointerException(message);
-        }
-        list.add(value);
-      }
-    }
-
-    /** Construct an UninitializedMessageException reporting missing fields in the given message. */
-    protected static UninitializedMessageException newUninitializedMessageException(
-        MessageLite message) {
-      return new UninitializedMessageException(message);
-    }
-
-    // For binary compatibility.
-    @Deprecated
-    protected static <T> void addAll(final Iterable<T> values, final Collection<? super T> list) {
-      addAll(values, (List<T>) list);
-    }
-
-    /**
-     * Adds the {@code values} to the {@code list}. This is a helper method used by generated code.
-     * Users should ignore it.
-     *
-     * @throws NullPointerException if {@code values} or any of the elements of {@code values} is
-     *     null.
-     */
-    protected static <T> void addAll(final Iterable<T> values, final List<? super T> list) {
-      checkNotNull(values);
-      if (values instanceof LazyStringList) {
-        // For StringOrByteStringLists, check the underlying elements to avoid
-        // forcing conversions of ByteStrings to Strings.
-        // TODO(dweis): Could we just prohibit nulls in all protobuf lists and get rid of this? Is
-        // if even possible to hit this condition as all protobuf methods check for null first,
-        // right?
-        List<?> lazyValues = ((LazyStringList) values).getUnderlyingElements();
-        LazyStringList lazyList = (LazyStringList) list;
-        int begin = list.size();
-        for (Object value : lazyValues) {
-          if (value == null) {
-            // encountered a null value so we must undo our modifications prior to throwing
-            String message = "Element at index " + (lazyList.size() - begin) + " is null.";
-            for (int i = lazyList.size() - 1; i >= begin; i--) {
-              lazyList.remove(i);
-            }
-            throw new NullPointerException(message);
-          }
-          if (value instanceof ByteString) {
-            lazyList.add((ByteString) value);
-          } else {
-            lazyList.add((String) value);
-          }
-        }
-      } else {
-        if (values instanceof PrimitiveNonBoxingCollection) {
-          list.addAll((Collection<T>) values);
-        } else {
-          addAllCheckingNulls(values, list);
-        }
-      }
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/AbstractParser.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/AbstractParser.java
deleted file mode 100644
index abfaca8..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/AbstractParser.java
+++ /dev/null
@@ -1,274 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-
-/**
- * A partial implementation of the {@link Parser} interface which implements as many methods of that
- * interface as possible in terms of other methods.
- *
- * <p>Note: This class implements all the convenience methods in the {@link Parser} interface. See
- * {@link Parser} for related javadocs. Subclasses need to implement {@link
- * Parser#parsePartialFrom(CodedInputStream, ExtensionRegistryLite)}
- *
- * @author liujisi@google.com (Pherl Liu)
- */
-public abstract class AbstractParser<MessageType extends MessageLite>
-    implements Parser<MessageType> {
-  /** Creates an UninitializedMessageException for MessageType. */
-  private UninitializedMessageException newUninitializedMessageException(MessageType message) {
-    if (message instanceof AbstractMessageLite) {
-      return ((AbstractMessageLite) message).newUninitializedMessageException();
-    }
-    return new UninitializedMessageException(message);
-  }
-
-  /**
-   * Helper method to check if message is initialized.
-   *
-   * @throws InvalidProtocolBufferException if it is not initialized.
-   * @return The message to check.
-   */
-  private MessageType checkMessageInitialized(MessageType message)
-      throws InvalidProtocolBufferException {
-    if (message != null && !message.isInitialized()) {
-      throw newUninitializedMessageException(message)
-          .asInvalidProtocolBufferException()
-          .setUnfinishedMessage(message);
-    }
-    return message;
-  }
-
-  private static final ExtensionRegistryLite EMPTY_REGISTRY =
-      ExtensionRegistryLite.getEmptyRegistry();
-
-  @Override
-  public MessageType parsePartialFrom(CodedInputStream input)
-      throws InvalidProtocolBufferException {
-    return parsePartialFrom(input, EMPTY_REGISTRY);
-  }
-
-  @Override
-  public MessageType parseFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    return checkMessageInitialized(parsePartialFrom(input, extensionRegistry));
-  }
-
-  @Override
-  public MessageType parseFrom(CodedInputStream input) throws InvalidProtocolBufferException {
-    return parseFrom(input, EMPTY_REGISTRY);
-  }
-
-  @Override
-  public MessageType parsePartialFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    MessageType message;
-    try {
-      CodedInputStream input = data.newCodedInput();
-      message = parsePartialFrom(input, extensionRegistry);
-      try {
-        input.checkLastTagWas(0);
-      } catch (InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(message);
-      }
-      return message;
-    } catch (InvalidProtocolBufferException e) {
-      throw e;
-    }
-  }
-
-  @Override
-  public MessageType parsePartialFrom(ByteString data) throws InvalidProtocolBufferException {
-    return parsePartialFrom(data, EMPTY_REGISTRY);
-  }
-
-  @Override
-  public MessageType parseFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    return checkMessageInitialized(parsePartialFrom(data, extensionRegistry));
-  }
-
-  @Override
-  public MessageType parseFrom(ByteString data) throws InvalidProtocolBufferException {
-    return parseFrom(data, EMPTY_REGISTRY);
-  }
-
-  @Override
-  public MessageType parseFrom(ByteBuffer data, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    MessageType message;
-    try {
-      CodedInputStream input = CodedInputStream.newInstance(data);
-      message = parsePartialFrom(input, extensionRegistry);
-      try {
-        input.checkLastTagWas(0);
-      } catch (InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(message);
-      }
-    } catch (InvalidProtocolBufferException e) {
-      throw e;
-    }
-
-    return checkMessageInitialized(message);
-  }
-
-  @Override
-  public MessageType parseFrom(ByteBuffer data) throws InvalidProtocolBufferException {
-    return parseFrom(data, EMPTY_REGISTRY);
-  }
-
-  @Override
-  public MessageType parsePartialFrom(
-      byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    try {
-      CodedInputStream input = CodedInputStream.newInstance(data, off, len);
-      MessageType message = parsePartialFrom(input, extensionRegistry);
-      try {
-        input.checkLastTagWas(0);
-      } catch (InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(message);
-      }
-      return message;
-    } catch (InvalidProtocolBufferException e) {
-      throw e;
-    }
-  }
-
-  @Override
-  public MessageType parsePartialFrom(byte[] data, int off, int len)
-      throws InvalidProtocolBufferException {
-    return parsePartialFrom(data, off, len, EMPTY_REGISTRY);
-  }
-
-  @Override
-  public MessageType parsePartialFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    return parsePartialFrom(data, 0, data.length, extensionRegistry);
-  }
-
-  @Override
-  public MessageType parsePartialFrom(byte[] data) throws InvalidProtocolBufferException {
-    return parsePartialFrom(data, 0, data.length, EMPTY_REGISTRY);
-  }
-
-  @Override
-  public MessageType parseFrom(
-      byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    return checkMessageInitialized(parsePartialFrom(data, off, len, extensionRegistry));
-  }
-
-  @Override
-  public MessageType parseFrom(byte[] data, int off, int len)
-      throws InvalidProtocolBufferException {
-    return parseFrom(data, off, len, EMPTY_REGISTRY);
-  }
-
-  @Override
-  public MessageType parseFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    return parseFrom(data, 0, data.length, extensionRegistry);
-  }
-
-  @Override
-  public MessageType parseFrom(byte[] data) throws InvalidProtocolBufferException {
-    return parseFrom(data, EMPTY_REGISTRY);
-  }
-
-  @Override
-  public MessageType parsePartialFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    CodedInputStream codedInput = CodedInputStream.newInstance(input);
-    MessageType message = parsePartialFrom(codedInput, extensionRegistry);
-    try {
-      codedInput.checkLastTagWas(0);
-    } catch (InvalidProtocolBufferException e) {
-      throw e.setUnfinishedMessage(message);
-    }
-    return message;
-  }
-
-  @Override
-  public MessageType parsePartialFrom(InputStream input) throws InvalidProtocolBufferException {
-    return parsePartialFrom(input, EMPTY_REGISTRY);
-  }
-
-  @Override
-  public MessageType parseFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    return checkMessageInitialized(parsePartialFrom(input, extensionRegistry));
-  }
-
-  @Override
-  public MessageType parseFrom(InputStream input) throws InvalidProtocolBufferException {
-    return parseFrom(input, EMPTY_REGISTRY);
-  }
-
-  @Override
-  public MessageType parsePartialDelimitedFrom(
-      InputStream input, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    int size;
-    try {
-      int firstByte = input.read();
-      if (firstByte == -1) {
-        return null;
-      }
-      size = CodedInputStream.readRawVarint32(firstByte, input);
-    } catch (IOException e) {
-      throw new InvalidProtocolBufferException(e);
-    }
-    InputStream limitedInput = new LimitedInputStream(input, size);
-    return parsePartialFrom(limitedInput, extensionRegistry);
-  }
-
-  @Override
-  public MessageType parsePartialDelimitedFrom(InputStream input)
-      throws InvalidProtocolBufferException {
-    return parsePartialDelimitedFrom(input, EMPTY_REGISTRY);
-  }
-
-  @Override
-  public MessageType parseDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    return checkMessageInitialized(parsePartialDelimitedFrom(input, extensionRegistry));
-  }
-
-  @Override
-  public MessageType parseDelimitedFrom(InputStream input) throws InvalidProtocolBufferException {
-    return parseDelimitedFrom(input, EMPTY_REGISTRY);
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/AbstractProtobufList.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/AbstractProtobufList.java
deleted file mode 100644
index e792d7d..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/AbstractProtobufList.java
+++ /dev/null
@@ -1,180 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import com.google.protobuf.Internal.ProtobufList;
-import java.util.AbstractList;
-import java.util.Collection;
-import java.util.List;
-import java.util.RandomAccess;
-
-/**
- * An abstract implementation of {@link ProtobufList} which manages mutability semantics. All mutate
- * methods must check if the list is mutable before proceeding. Subclasses must invoke {@link
- * #ensureIsMutable()} manually when overriding those methods.
- *
- * <p>This implementation assumes all subclasses are array based, supporting random access.
- */
-abstract class AbstractProtobufList<E> extends AbstractList<E> implements ProtobufList<E> {
-
-  protected static final int DEFAULT_CAPACITY = 10;
-
-  /** Whether or not this list is modifiable. */
-  private boolean isMutable;
-
-  /** Constructs a mutable list by default. */
-  AbstractProtobufList() {
-    isMutable = true;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (o == this) {
-      return true;
-    }
-    if (!(o instanceof List)) {
-      return false;
-    }
-    // Handle lists that do not support RandomAccess as efficiently as possible by using an iterator
-    // based approach in our super class. Otherwise our index based approach will avoid those
-    // allocations.
-    if (!(o instanceof RandomAccess)) {
-      return super.equals(o);
-    }
-
-    List<?> other = (List<?>) o;
-    final int size = size();
-    if (size != other.size()) {
-      return false;
-    }
-    for (int i = 0; i < size; i++) {
-      if (!get(i).equals(other.get(i))) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    final int size = size();
-    int hashCode = 1;
-    for (int i = 0; i < size; i++) {
-      hashCode = (31 * hashCode) + get(i).hashCode();
-    }
-    return hashCode;
-  }
-
-  @Override
-  public boolean add(E e) {
-    ensureIsMutable();
-    return super.add(e);
-  }
-
-  @Override
-  public void add(int index, E element) {
-    ensureIsMutable();
-    super.add(index, element);
-  }
-
-  @Override
-  public boolean addAll(Collection<? extends E> c) {
-    ensureIsMutable();
-    return super.addAll(c);
-  }
-
-  @Override
-  public boolean addAll(int index, Collection<? extends E> c) {
-    ensureIsMutable();
-    return super.addAll(index, c);
-  }
-
-  @Override
-  public void clear() {
-    ensureIsMutable();
-    super.clear();
-  }
-
-  @Override
-  public boolean isModifiable() {
-    return isMutable;
-  }
-
-  @Override
-  public final void makeImmutable() {
-    isMutable = false;
-  }
-
-  @Override
-  public E remove(int index) {
-    ensureIsMutable();
-    return super.remove(index);
-  }
-
-  @Override
-  public boolean remove(Object o) {
-    ensureIsMutable();
-    int index = indexOf(o);
-    if (index == -1) {
-      return false;
-    }
-    remove(index);
-    return true;
-  }
-
-  @Override
-  public boolean removeAll(Collection<?> c) {
-    ensureIsMutable();
-    return super.removeAll(c);
-  }
-
-  @Override
-  public boolean retainAll(Collection<?> c) {
-    ensureIsMutable();
-    return super.retainAll(c);
-  }
-
-  @Override
-  public E set(int index, E element) {
-    ensureIsMutable();
-    return super.set(index, element);
-  }
-
-  /**
-   * Throws an {@link UnsupportedOperationException} if the list is immutable. Subclasses are
-   * responsible for invoking this method on mutate operations.
-   */
-  protected void ensureIsMutable() {
-    if (!isMutable) {
-      throw new UnsupportedOperationException();
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/AllocatedBuffer.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/AllocatedBuffer.java
deleted file mode 100644
index a01a6c1..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/AllocatedBuffer.java
+++ /dev/null
@@ -1,263 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.Internal.checkNotNull;
-
-import java.nio.ByteBuffer;
-
-/**
- * A buffer that was allocated by a {@link BufferAllocator}. For every buffer, it is guaranteed that
- * at least one of {@link #hasArray()} or {@link #hasNioBuffer()} will be {@code true}.
- */
-@ExperimentalApi
-abstract class AllocatedBuffer {
-  /**
-   * Indicates whether this buffer contains a backing {@link ByteBuffer} (i.e. it is safe to call
-   * {@link #nioBuffer()}).
-   */
-  public abstract boolean hasNioBuffer();
-
-  /**
-   * Indicates whether this buffer contains a backing array (i.e. it is safe to call {@link
-   * #array()}).
-   */
-  public abstract boolean hasArray();
-
-  /**
-   * Returns the {@link ByteBuffer} that backs this buffer <i>(optional operation)</i>.
-   *
-   * <p>Call {@link #hasNioBuffer()} before invoking this method in order to ensure that this buffer
-   * has a backing {@link ByteBuffer}.
-   *
-   * @return The {@link ByteBuffer} that backs this buffer
-   * @throws UnsupportedOperationException If this buffer is not backed by a {@link ByteBuffer}.
-   */
-  public abstract ByteBuffer nioBuffer();
-
-  /**
-   * Returns the byte array that backs this buffer <i>(optional operation)</i>.
-   *
-   * <p>Call {@link #hasArray()} before invoking this method in order to ensure that this buffer has
-   * an accessible backing array.
-   *
-   * @return The array that backs this buffer
-   * @throws java.nio.ReadOnlyBufferException If this buffer is backed by an array but is read-only
-   * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
-   */
-  public abstract byte[] array();
-
-  /**
-   * Returns the offset within this buffer's backing array of the first element of the buffer
-   * <i>(optional operation)</i>.
-   *
-   * <p>If this buffer is backed by an array then {@link #position()} corresponds to the array index
-   * {@link #position()} {@code +} {@link #arrayOffset()}.
-   *
-   * <p>Invoke the {@link #hasArray hasArray} method before invoking this method in order to ensure
-   * that this buffer has an accessible backing array.
-   *
-   * @return The offset within this buffer's array of the first element of the buffer
-   * @throws java.nio.ReadOnlyBufferException If this buffer is backed by an array but is read-only
-   * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
-   */
-  public abstract int arrayOffset();
-
-  /**
-   * Returns this buffer's position.
-   *
-   * @return The position of this buffer
-   */
-  public abstract int position();
-
-  /**
-   * Sets this buffer's position.
-   *
-   * @param position The new position value; must be non-negative and no larger than the current
-   *     limit
-   * @return This buffer
-   * @throws IllegalArgumentException If the preconditions on {@code position} do not hold
-   */
-  public abstract AllocatedBuffer position(int position);
-
-  /**
-   * Returns this buffer's limit.
-   *
-   * @return The limit of this buffer
-   */
-  public abstract int limit();
-
-  /**
-   * Returns the number of elements between the current {@link #position()} and the {@link #limit()}
-   * .
-   *
-   * @return The number of elements remaining in this buffer
-   */
-  public abstract int remaining();
-
-  /**
-   * Creates a new {@link AllocatedBuffer} that is backed by the given array. The returned buffer
-   * will have {@link #hasArray} == {@code true}, {@link #arrayOffset()} == {@code 0}, {@link
-   * #position()} == {@code 0} and {@link #limit()} equal to the length of {@code bytes}.
-   */
-  public static AllocatedBuffer wrap(byte[] bytes) {
-    return wrapNoCheck(bytes, 0, bytes.length);
-  }
-
-  /**
-   * Creates a new {@link AllocatedBuffer} that is backed by the given array. The returned buffer
-   * will have {@link #hasArray} == {@code true}, {@link #arrayOffset()} == {@code offset}, {@link
-   * #position()} == {@code 0} and {@link #limit()} == {@code length}.
-   */
-  public static AllocatedBuffer wrap(final byte[] bytes, final int offset, final int length) {
-    if (offset < 0 || length < 0 || (offset + length) > bytes.length) {
-      throw new IndexOutOfBoundsException(
-          String.format("bytes.length=%d, offset=%d, length=%d", bytes.length, offset, length));
-    }
-
-    return wrapNoCheck(bytes, offset, length);
-  }
-
-  /**
-   * Creates a new {@link AllocatedBuffer} that is backed by the given {@link ByteBuffer}. The
-   * returned buffer will have {@link #hasNioBuffer} == {@code true}.
-   */
-  public static AllocatedBuffer wrap(final ByteBuffer buffer) {
-    checkNotNull(buffer, "buffer");
-
-    return new AllocatedBuffer() {
-
-      @Override
-      public boolean hasNioBuffer() {
-        return true;
-      }
-
-      @Override
-      public ByteBuffer nioBuffer() {
-        return buffer;
-      }
-
-      @Override
-      public boolean hasArray() {
-        return buffer.hasArray();
-      }
-
-      @Override
-      public byte[] array() {
-        return buffer.array();
-      }
-
-      @Override
-      public int arrayOffset() {
-        return buffer.arrayOffset();
-      }
-
-      @Override
-      public int position() {
-        return buffer.position();
-      }
-
-      @Override
-      public AllocatedBuffer position(int position) {
-        buffer.position(position);
-        return this;
-      }
-
-      @Override
-      public int limit() {
-        return buffer.limit();
-      }
-
-      @Override
-      public int remaining() {
-        return buffer.remaining();
-      }
-    };
-  }
-
-  private static AllocatedBuffer wrapNoCheck(
-      final byte[] bytes, final int offset, final int length) {
-    return new AllocatedBuffer() {
-      // Relative to offset.
-      private int position;
-
-      @Override
-      public boolean hasNioBuffer() {
-        return false;
-      }
-
-      @Override
-      public ByteBuffer nioBuffer() {
-        throw new UnsupportedOperationException();
-      }
-
-      @Override
-      public boolean hasArray() {
-        return true;
-      }
-
-      @Override
-      public byte[] array() {
-        return bytes;
-      }
-
-      @Override
-      public int arrayOffset() {
-        return offset;
-      }
-
-      @Override
-      public int position() {
-        return position;
-      }
-
-      @Override
-      public AllocatedBuffer position(int position) {
-        if (position < 0 || position > length) {
-          throw new IllegalArgumentException("Invalid position: " + position);
-        }
-        this.position = position;
-        return this;
-      }
-
-      @Override
-      public int limit() {
-        // Relative to offset.
-        return length;
-      }
-
-      @Override
-      public int remaining() {
-        return length - position;
-      }
-    };
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Android.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Android.java
deleted file mode 100644
index 5a7ce9e..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Android.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-final class Android {
-  private Android() {
-  }
-
-  // Set to true in lite_proguard_android.pgcfg.
-  @SuppressWarnings("ConstantField")
-  private static boolean ASSUME_ANDROID;
-
-  private static final Class<?> MEMORY_CLASS = getClassForName("libcore.io.Memory");
-
-  private static final boolean IS_ROBOLECTRIC =
-      !ASSUME_ANDROID && getClassForName("org.robolectric.Robolectric") != null;
-
-  /** Returns {@code true} if running on an Android device. */
-  static boolean isOnAndroidDevice() {
-    return ASSUME_ANDROID || (MEMORY_CLASS != null && !IS_ROBOLECTRIC);
-  }
-
-  /** Returns the memory class or {@code null} if not on Android device. */
-  static Class<?> getMemoryClass() {
-    return MEMORY_CLASS;
-  }
-
-  @SuppressWarnings("unchecked")
-  private static <T> Class<T> getClassForName(String name) {
-    try {
-      return (Class<T>) Class.forName(name);
-    } catch (Throwable e) {
-      return null;
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Any.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Any.java
deleted file mode 100644
index 70ab047..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Any.java
+++ /dev/null
@@ -1,761 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/any.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * `Any` contains an arbitrary serialized protocol buffer message along with a
- * URL that describes the type of the serialized message.
- * Protobuf library provides support to pack/unpack Any values in the form
- * of utility functions or additional generated methods of the Any type.
- * Example 1: Pack and unpack a message in C++.
- *     Foo foo = ...;
- *     Any any;
- *     any.PackFrom(foo);
- *     ...
- *     if (any.UnpackTo(&amp;foo)) {
- *       ...
- *     }
- * Example 2: Pack and unpack a message in Java.
- *     Foo foo = ...;
- *     Any any = Any.pack(foo);
- *     ...
- *     if (any.is(Foo.class)) {
- *       foo = any.unpack(Foo.class);
- *     }
- *  Example 3: Pack and unpack a message in Python.
- *     foo = Foo(...)
- *     any = Any()
- *     any.Pack(foo)
- *     ...
- *     if any.Is(Foo.DESCRIPTOR):
- *       any.Unpack(foo)
- *       ...
- *  Example 4: Pack and unpack a message in Go
- *      foo := &amp;pb.Foo{...}
- *      any, err := anypb.New(foo)
- *      if err != nil {
- *        ...
- *      }
- *      ...
- *      foo := &amp;pb.Foo{}
- *      if err := any.UnmarshalTo(foo); err != nil {
- *        ...
- *      }
- * The pack methods provided by protobuf library will by default use
- * 'type.googleapis.com/full.type.name' as the type URL and the unpack
- * methods only use the fully qualified type name after the last '/'
- * in the type URL, for example "foo.bar.com/x/y.z" will yield type
- * name "y.z".
- * JSON
- * ====
- * The JSON representation of an `Any` value uses the regular
- * representation of the deserialized, embedded message, with an
- * additional field `&#64;type` which contains the type URL. Example:
- *     package google.profile;
- *     message Person {
- *       string first_name = 1;
- *       string last_name = 2;
- *     }
- *     {
- *       "&#64;type": "type.googleapis.com/google.profile.Person",
- *       "firstName": &lt;string&gt;,
- *       "lastName": &lt;string&gt;
- *     }
- * If the embedded message type is well-known and has a custom JSON
- * representation, that representation will be embedded adding a field
- * `value` which holds the custom JSON in addition to the `&#64;type`
- * field. Example (for message [google.protobuf.Duration][]):
- *     {
- *       "&#64;type": "type.googleapis.com/google.protobuf.Duration",
- *       "value": "1.212s"
- *     }
- * </pre>
- *
- * Protobuf type {@code google.protobuf.Any}
- */
-public  final class Any extends
-    com.google.protobuf.GeneratedMessageLite<
-        Any, Any.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.Any)
-    AnyOrBuilder {
-  private Any() {
-    typeUrl_ = "";
-    value_ = com.google.protobuf.ByteString.EMPTY;
-  }
-  public static final int TYPE_URL_FIELD_NUMBER = 1;
-  private java.lang.String typeUrl_;
-  /**
-   * <pre>
-   * A URL/resource name that uniquely identifies the type of the serialized
-   * protocol buffer message. This string must contain at least
-   * one "/" character. The last segment of the URL's path must represent
-   * the fully qualified name of the type (as in
-   * `path/google.protobuf.Duration`). The name should be in a canonical form
-   * (e.g., leading "." is not accepted).
-   * In practice, teams usually precompile into the binary all types that they
-   * expect it to use in the context of Any. However, for URLs which use the
-   * scheme `http`, `https`, or no scheme, one can optionally set up a type
-   * server that maps type URLs to message definitions as follows:
-   * * If no scheme is provided, `https` is assumed.
-   * * An HTTP GET on the URL must yield a [google.protobuf.Type][]
-   *   value in binary format, or produce an error.
-   * * Applications are allowed to cache lookup results based on the
-   *   URL, or have them precompiled into a binary to avoid any
-   *   lookup. Therefore, binary compatibility needs to be preserved
-   *   on changes to types. (Use versioned type names to manage
-   *   breaking changes.)
-   * Note: this functionality is not currently available in the official
-   * protobuf release, and it is not used for type URLs beginning with
-   * type.googleapis.com.
-   * Schemes other than `http`, `https` (or the empty scheme) might be
-   * used with implementation specific semantics.
-   * </pre>
-   *
-   * <code>string type_url = 1;</code>
-   * @return The typeUrl.
-   */
-  @java.lang.Override
-  public java.lang.String getTypeUrl() {
-    return typeUrl_;
-  }
-  /**
-   * <pre>
-   * A URL/resource name that uniquely identifies the type of the serialized
-   * protocol buffer message. This string must contain at least
-   * one "/" character. The last segment of the URL's path must represent
-   * the fully qualified name of the type (as in
-   * `path/google.protobuf.Duration`). The name should be in a canonical form
-   * (e.g., leading "." is not accepted).
-   * In practice, teams usually precompile into the binary all types that they
-   * expect it to use in the context of Any. However, for URLs which use the
-   * scheme `http`, `https`, or no scheme, one can optionally set up a type
-   * server that maps type URLs to message definitions as follows:
-   * * If no scheme is provided, `https` is assumed.
-   * * An HTTP GET on the URL must yield a [google.protobuf.Type][]
-   *   value in binary format, or produce an error.
-   * * Applications are allowed to cache lookup results based on the
-   *   URL, or have them precompiled into a binary to avoid any
-   *   lookup. Therefore, binary compatibility needs to be preserved
-   *   on changes to types. (Use versioned type names to manage
-   *   breaking changes.)
-   * Note: this functionality is not currently available in the official
-   * protobuf release, and it is not used for type URLs beginning with
-   * type.googleapis.com.
-   * Schemes other than `http`, `https` (or the empty scheme) might be
-   * used with implementation specific semantics.
-   * </pre>
-   *
-   * <code>string type_url = 1;</code>
-   * @return The bytes for typeUrl.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getTypeUrlBytes() {
-    return com.google.protobuf.ByteString.copyFromUtf8(typeUrl_);
-  }
-  /**
-   * <pre>
-   * A URL/resource name that uniquely identifies the type of the serialized
-   * protocol buffer message. This string must contain at least
-   * one "/" character. The last segment of the URL's path must represent
-   * the fully qualified name of the type (as in
-   * `path/google.protobuf.Duration`). The name should be in a canonical form
-   * (e.g., leading "." is not accepted).
-   * In practice, teams usually precompile into the binary all types that they
-   * expect it to use in the context of Any. However, for URLs which use the
-   * scheme `http`, `https`, or no scheme, one can optionally set up a type
-   * server that maps type URLs to message definitions as follows:
-   * * If no scheme is provided, `https` is assumed.
-   * * An HTTP GET on the URL must yield a [google.protobuf.Type][]
-   *   value in binary format, or produce an error.
-   * * Applications are allowed to cache lookup results based on the
-   *   URL, or have them precompiled into a binary to avoid any
-   *   lookup. Therefore, binary compatibility needs to be preserved
-   *   on changes to types. (Use versioned type names to manage
-   *   breaking changes.)
-   * Note: this functionality is not currently available in the official
-   * protobuf release, and it is not used for type URLs beginning with
-   * type.googleapis.com.
-   * Schemes other than `http`, `https` (or the empty scheme) might be
-   * used with implementation specific semantics.
-   * </pre>
-   *
-   * <code>string type_url = 1;</code>
-   * @param value The typeUrl to set.
-   */
-  private void setTypeUrl(
-      java.lang.String value) {
-    value.getClass();
-  
-    typeUrl_ = value;
-  }
-  /**
-   * <pre>
-   * A URL/resource name that uniquely identifies the type of the serialized
-   * protocol buffer message. This string must contain at least
-   * one "/" character. The last segment of the URL's path must represent
-   * the fully qualified name of the type (as in
-   * `path/google.protobuf.Duration`). The name should be in a canonical form
-   * (e.g., leading "." is not accepted).
-   * In practice, teams usually precompile into the binary all types that they
-   * expect it to use in the context of Any. However, for URLs which use the
-   * scheme `http`, `https`, or no scheme, one can optionally set up a type
-   * server that maps type URLs to message definitions as follows:
-   * * If no scheme is provided, `https` is assumed.
-   * * An HTTP GET on the URL must yield a [google.protobuf.Type][]
-   *   value in binary format, or produce an error.
-   * * Applications are allowed to cache lookup results based on the
-   *   URL, or have them precompiled into a binary to avoid any
-   *   lookup. Therefore, binary compatibility needs to be preserved
-   *   on changes to types. (Use versioned type names to manage
-   *   breaking changes.)
-   * Note: this functionality is not currently available in the official
-   * protobuf release, and it is not used for type URLs beginning with
-   * type.googleapis.com.
-   * Schemes other than `http`, `https` (or the empty scheme) might be
-   * used with implementation specific semantics.
-   * </pre>
-   *
-   * <code>string type_url = 1;</code>
-   */
-  private void clearTypeUrl() {
-    
-    typeUrl_ = getDefaultInstance().getTypeUrl();
-  }
-  /**
-   * <pre>
-   * A URL/resource name that uniquely identifies the type of the serialized
-   * protocol buffer message. This string must contain at least
-   * one "/" character. The last segment of the URL's path must represent
-   * the fully qualified name of the type (as in
-   * `path/google.protobuf.Duration`). The name should be in a canonical form
-   * (e.g., leading "." is not accepted).
-   * In practice, teams usually precompile into the binary all types that they
-   * expect it to use in the context of Any. However, for URLs which use the
-   * scheme `http`, `https`, or no scheme, one can optionally set up a type
-   * server that maps type URLs to message definitions as follows:
-   * * If no scheme is provided, `https` is assumed.
-   * * An HTTP GET on the URL must yield a [google.protobuf.Type][]
-   *   value in binary format, or produce an error.
-   * * Applications are allowed to cache lookup results based on the
-   *   URL, or have them precompiled into a binary to avoid any
-   *   lookup. Therefore, binary compatibility needs to be preserved
-   *   on changes to types. (Use versioned type names to manage
-   *   breaking changes.)
-   * Note: this functionality is not currently available in the official
-   * protobuf release, and it is not used for type URLs beginning with
-   * type.googleapis.com.
-   * Schemes other than `http`, `https` (or the empty scheme) might be
-   * used with implementation specific semantics.
-   * </pre>
-   *
-   * <code>string type_url = 1;</code>
-   * @param value The bytes for typeUrl to set.
-   */
-  private void setTypeUrlBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    typeUrl_ = value.toStringUtf8();
-    
-  }
-
-  public static final int VALUE_FIELD_NUMBER = 2;
-  private com.google.protobuf.ByteString value_;
-  /**
-   * <pre>
-   * Must be a valid serialized protocol buffer of the above specified type.
-   * </pre>
-   *
-   * <code>bytes value = 2;</code>
-   * @return The value.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString getValue() {
-    return value_;
-  }
-  /**
-   * <pre>
-   * Must be a valid serialized protocol buffer of the above specified type.
-   * </pre>
-   *
-   * <code>bytes value = 2;</code>
-   * @param value The value to set.
-   */
-  private void setValue(com.google.protobuf.ByteString value) {
-    value.getClass();
-  
-    value_ = value;
-  }
-  /**
-   * <pre>
-   * Must be a valid serialized protocol buffer of the above specified type.
-   * </pre>
-   *
-   * <code>bytes value = 2;</code>
-   */
-  private void clearValue() {
-    
-    value_ = getDefaultInstance().getValue();
-  }
-
-  public static com.google.protobuf.Any parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Any parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Any parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Any parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Any parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Any parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Any parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Any parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Any parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Any parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Any parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Any parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.Any prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * `Any` contains an arbitrary serialized protocol buffer message along with a
-   * URL that describes the type of the serialized message.
-   * Protobuf library provides support to pack/unpack Any values in the form
-   * of utility functions or additional generated methods of the Any type.
-   * Example 1: Pack and unpack a message in C++.
-   *     Foo foo = ...;
-   *     Any any;
-   *     any.PackFrom(foo);
-   *     ...
-   *     if (any.UnpackTo(&amp;foo)) {
-   *       ...
-   *     }
-   * Example 2: Pack and unpack a message in Java.
-   *     Foo foo = ...;
-   *     Any any = Any.pack(foo);
-   *     ...
-   *     if (any.is(Foo.class)) {
-   *       foo = any.unpack(Foo.class);
-   *     }
-   *  Example 3: Pack and unpack a message in Python.
-   *     foo = Foo(...)
-   *     any = Any()
-   *     any.Pack(foo)
-   *     ...
-   *     if any.Is(Foo.DESCRIPTOR):
-   *       any.Unpack(foo)
-   *       ...
-   *  Example 4: Pack and unpack a message in Go
-   *      foo := &amp;pb.Foo{...}
-   *      any, err := anypb.New(foo)
-   *      if err != nil {
-   *        ...
-   *      }
-   *      ...
-   *      foo := &amp;pb.Foo{}
-   *      if err := any.UnmarshalTo(foo); err != nil {
-   *        ...
-   *      }
-   * The pack methods provided by protobuf library will by default use
-   * 'type.googleapis.com/full.type.name' as the type URL and the unpack
-   * methods only use the fully qualified type name after the last '/'
-   * in the type URL, for example "foo.bar.com/x/y.z" will yield type
-   * name "y.z".
-   * JSON
-   * ====
-   * The JSON representation of an `Any` value uses the regular
-   * representation of the deserialized, embedded message, with an
-   * additional field `&#64;type` which contains the type URL. Example:
-   *     package google.profile;
-   *     message Person {
-   *       string first_name = 1;
-   *       string last_name = 2;
-   *     }
-   *     {
-   *       "&#64;type": "type.googleapis.com/google.profile.Person",
-   *       "firstName": &lt;string&gt;,
-   *       "lastName": &lt;string&gt;
-   *     }
-   * If the embedded message type is well-known and has a custom JSON
-   * representation, that representation will be embedded adding a field
-   * `value` which holds the custom JSON in addition to the `&#64;type`
-   * field. Example (for message [google.protobuf.Duration][]):
-   *     {
-   *       "&#64;type": "type.googleapis.com/google.protobuf.Duration",
-   *       "value": "1.212s"
-   *     }
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.Any}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.Any, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.Any)
-      com.google.protobuf.AnyOrBuilder {
-    // Construct using com.google.protobuf.Any.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * A URL/resource name that uniquely identifies the type of the serialized
-     * protocol buffer message. This string must contain at least
-     * one "/" character. The last segment of the URL's path must represent
-     * the fully qualified name of the type (as in
-     * `path/google.protobuf.Duration`). The name should be in a canonical form
-     * (e.g., leading "." is not accepted).
-     * In practice, teams usually precompile into the binary all types that they
-     * expect it to use in the context of Any. However, for URLs which use the
-     * scheme `http`, `https`, or no scheme, one can optionally set up a type
-     * server that maps type URLs to message definitions as follows:
-     * * If no scheme is provided, `https` is assumed.
-     * * An HTTP GET on the URL must yield a [google.protobuf.Type][]
-     *   value in binary format, or produce an error.
-     * * Applications are allowed to cache lookup results based on the
-     *   URL, or have them precompiled into a binary to avoid any
-     *   lookup. Therefore, binary compatibility needs to be preserved
-     *   on changes to types. (Use versioned type names to manage
-     *   breaking changes.)
-     * Note: this functionality is not currently available in the official
-     * protobuf release, and it is not used for type URLs beginning with
-     * type.googleapis.com.
-     * Schemes other than `http`, `https` (or the empty scheme) might be
-     * used with implementation specific semantics.
-     * </pre>
-     *
-     * <code>string type_url = 1;</code>
-     * @return The typeUrl.
-     */
-    @java.lang.Override
-    public java.lang.String getTypeUrl() {
-      return instance.getTypeUrl();
-    }
-    /**
-     * <pre>
-     * A URL/resource name that uniquely identifies the type of the serialized
-     * protocol buffer message. This string must contain at least
-     * one "/" character. The last segment of the URL's path must represent
-     * the fully qualified name of the type (as in
-     * `path/google.protobuf.Duration`). The name should be in a canonical form
-     * (e.g., leading "." is not accepted).
-     * In practice, teams usually precompile into the binary all types that they
-     * expect it to use in the context of Any. However, for URLs which use the
-     * scheme `http`, `https`, or no scheme, one can optionally set up a type
-     * server that maps type URLs to message definitions as follows:
-     * * If no scheme is provided, `https` is assumed.
-     * * An HTTP GET on the URL must yield a [google.protobuf.Type][]
-     *   value in binary format, or produce an error.
-     * * Applications are allowed to cache lookup results based on the
-     *   URL, or have them precompiled into a binary to avoid any
-     *   lookup. Therefore, binary compatibility needs to be preserved
-     *   on changes to types. (Use versioned type names to manage
-     *   breaking changes.)
-     * Note: this functionality is not currently available in the official
-     * protobuf release, and it is not used for type URLs beginning with
-     * type.googleapis.com.
-     * Schemes other than `http`, `https` (or the empty scheme) might be
-     * used with implementation specific semantics.
-     * </pre>
-     *
-     * <code>string type_url = 1;</code>
-     * @return The bytes for typeUrl.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getTypeUrlBytes() {
-      return instance.getTypeUrlBytes();
-    }
-    /**
-     * <pre>
-     * A URL/resource name that uniquely identifies the type of the serialized
-     * protocol buffer message. This string must contain at least
-     * one "/" character. The last segment of the URL's path must represent
-     * the fully qualified name of the type (as in
-     * `path/google.protobuf.Duration`). The name should be in a canonical form
-     * (e.g., leading "." is not accepted).
-     * In practice, teams usually precompile into the binary all types that they
-     * expect it to use in the context of Any. However, for URLs which use the
-     * scheme `http`, `https`, or no scheme, one can optionally set up a type
-     * server that maps type URLs to message definitions as follows:
-     * * If no scheme is provided, `https` is assumed.
-     * * An HTTP GET on the URL must yield a [google.protobuf.Type][]
-     *   value in binary format, or produce an error.
-     * * Applications are allowed to cache lookup results based on the
-     *   URL, or have them precompiled into a binary to avoid any
-     *   lookup. Therefore, binary compatibility needs to be preserved
-     *   on changes to types. (Use versioned type names to manage
-     *   breaking changes.)
-     * Note: this functionality is not currently available in the official
-     * protobuf release, and it is not used for type URLs beginning with
-     * type.googleapis.com.
-     * Schemes other than `http`, `https` (or the empty scheme) might be
-     * used with implementation specific semantics.
-     * </pre>
-     *
-     * <code>string type_url = 1;</code>
-     * @param value The typeUrl to set.
-     * @return This builder for chaining.
-     */
-    public Builder setTypeUrl(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.setTypeUrl(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * A URL/resource name that uniquely identifies the type of the serialized
-     * protocol buffer message. This string must contain at least
-     * one "/" character. The last segment of the URL's path must represent
-     * the fully qualified name of the type (as in
-     * `path/google.protobuf.Duration`). The name should be in a canonical form
-     * (e.g., leading "." is not accepted).
-     * In practice, teams usually precompile into the binary all types that they
-     * expect it to use in the context of Any. However, for URLs which use the
-     * scheme `http`, `https`, or no scheme, one can optionally set up a type
-     * server that maps type URLs to message definitions as follows:
-     * * If no scheme is provided, `https` is assumed.
-     * * An HTTP GET on the URL must yield a [google.protobuf.Type][]
-     *   value in binary format, or produce an error.
-     * * Applications are allowed to cache lookup results based on the
-     *   URL, or have them precompiled into a binary to avoid any
-     *   lookup. Therefore, binary compatibility needs to be preserved
-     *   on changes to types. (Use versioned type names to manage
-     *   breaking changes.)
-     * Note: this functionality is not currently available in the official
-     * protobuf release, and it is not used for type URLs beginning with
-     * type.googleapis.com.
-     * Schemes other than `http`, `https` (or the empty scheme) might be
-     * used with implementation specific semantics.
-     * </pre>
-     *
-     * <code>string type_url = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearTypeUrl() {
-      copyOnWrite();
-      instance.clearTypeUrl();
-      return this;
-    }
-    /**
-     * <pre>
-     * A URL/resource name that uniquely identifies the type of the serialized
-     * protocol buffer message. This string must contain at least
-     * one "/" character. The last segment of the URL's path must represent
-     * the fully qualified name of the type (as in
-     * `path/google.protobuf.Duration`). The name should be in a canonical form
-     * (e.g., leading "." is not accepted).
-     * In practice, teams usually precompile into the binary all types that they
-     * expect it to use in the context of Any. However, for URLs which use the
-     * scheme `http`, `https`, or no scheme, one can optionally set up a type
-     * server that maps type URLs to message definitions as follows:
-     * * If no scheme is provided, `https` is assumed.
-     * * An HTTP GET on the URL must yield a [google.protobuf.Type][]
-     *   value in binary format, or produce an error.
-     * * Applications are allowed to cache lookup results based on the
-     *   URL, or have them precompiled into a binary to avoid any
-     *   lookup. Therefore, binary compatibility needs to be preserved
-     *   on changes to types. (Use versioned type names to manage
-     *   breaking changes.)
-     * Note: this functionality is not currently available in the official
-     * protobuf release, and it is not used for type URLs beginning with
-     * type.googleapis.com.
-     * Schemes other than `http`, `https` (or the empty scheme) might be
-     * used with implementation specific semantics.
-     * </pre>
-     *
-     * <code>string type_url = 1;</code>
-     * @param value The bytes for typeUrl to set.
-     * @return This builder for chaining.
-     */
-    public Builder setTypeUrlBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setTypeUrlBytes(value);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * Must be a valid serialized protocol buffer of the above specified type.
-     * </pre>
-     *
-     * <code>bytes value = 2;</code>
-     * @return The value.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getValue() {
-      return instance.getValue();
-    }
-    /**
-     * <pre>
-     * Must be a valid serialized protocol buffer of the above specified type.
-     * </pre>
-     *
-     * <code>bytes value = 2;</code>
-     * @param value The value to set.
-     * @return This builder for chaining.
-     */
-    public Builder setValue(com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Must be a valid serialized protocol buffer of the above specified type.
-     * </pre>
-     *
-     * <code>bytes value = 2;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearValue() {
-      copyOnWrite();
-      instance.clearValue();
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.Any)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.Any();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "typeUrl_",
-            "value_",
-          };
-          java.lang.String info =
-              "\u0000\u0002\u0000\u0000\u0001\u0002\u0002\u0000\u0000\u0000\u0001\u0208\u0002\n" +
-              "";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.Any> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.Any.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.Any>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.Any)
-  private static final com.google.protobuf.Any DEFAULT_INSTANCE;
-  static {
-    Any defaultInstance = new Any();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      Any.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.Any getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<Any> PARSER;
-
-  public static com.google.protobuf.Parser<Any> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/AnyOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/AnyOrBuilder.java
deleted file mode 100644
index 5fcd84c..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/AnyOrBuilder.java
+++ /dev/null
@@ -1,83 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/any.proto
-
-package com.google.protobuf;
-
-public interface AnyOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.Any)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * A URL/resource name that uniquely identifies the type of the serialized
-   * protocol buffer message. This string must contain at least
-   * one "/" character. The last segment of the URL's path must represent
-   * the fully qualified name of the type (as in
-   * `path/google.protobuf.Duration`). The name should be in a canonical form
-   * (e.g., leading "." is not accepted).
-   * In practice, teams usually precompile into the binary all types that they
-   * expect it to use in the context of Any. However, for URLs which use the
-   * scheme `http`, `https`, or no scheme, one can optionally set up a type
-   * server that maps type URLs to message definitions as follows:
-   * * If no scheme is provided, `https` is assumed.
-   * * An HTTP GET on the URL must yield a [google.protobuf.Type][]
-   *   value in binary format, or produce an error.
-   * * Applications are allowed to cache lookup results based on the
-   *   URL, or have them precompiled into a binary to avoid any
-   *   lookup. Therefore, binary compatibility needs to be preserved
-   *   on changes to types. (Use versioned type names to manage
-   *   breaking changes.)
-   * Note: this functionality is not currently available in the official
-   * protobuf release, and it is not used for type URLs beginning with
-   * type.googleapis.com.
-   * Schemes other than `http`, `https` (or the empty scheme) might be
-   * used with implementation specific semantics.
-   * </pre>
-   *
-   * <code>string type_url = 1;</code>
-   * @return The typeUrl.
-   */
-  java.lang.String getTypeUrl();
-  /**
-   * <pre>
-   * A URL/resource name that uniquely identifies the type of the serialized
-   * protocol buffer message. This string must contain at least
-   * one "/" character. The last segment of the URL's path must represent
-   * the fully qualified name of the type (as in
-   * `path/google.protobuf.Duration`). The name should be in a canonical form
-   * (e.g., leading "." is not accepted).
-   * In practice, teams usually precompile into the binary all types that they
-   * expect it to use in the context of Any. However, for URLs which use the
-   * scheme `http`, `https`, or no scheme, one can optionally set up a type
-   * server that maps type URLs to message definitions as follows:
-   * * If no scheme is provided, `https` is assumed.
-   * * An HTTP GET on the URL must yield a [google.protobuf.Type][]
-   *   value in binary format, or produce an error.
-   * * Applications are allowed to cache lookup results based on the
-   *   URL, or have them precompiled into a binary to avoid any
-   *   lookup. Therefore, binary compatibility needs to be preserved
-   *   on changes to types. (Use versioned type names to manage
-   *   breaking changes.)
-   * Note: this functionality is not currently available in the official
-   * protobuf release, and it is not used for type URLs beginning with
-   * type.googleapis.com.
-   * Schemes other than `http`, `https` (or the empty scheme) might be
-   * used with implementation specific semantics.
-   * </pre>
-   *
-   * <code>string type_url = 1;</code>
-   * @return The bytes for typeUrl.
-   */
-  com.google.protobuf.ByteString
-      getTypeUrlBytes();
-
-  /**
-   * <pre>
-   * Must be a valid serialized protocol buffer of the above specified type.
-   * </pre>
-   *
-   * <code>bytes value = 2;</code>
-   * @return The value.
-   */
-  com.google.protobuf.ByteString getValue();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/AnyProto.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/AnyProto.java
deleted file mode 100644
index f6dc68b..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/AnyProto.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/any.proto
-
-package com.google.protobuf;
-
-public final class AnyProto {
-  private AnyProto() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Api.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Api.java
deleted file mode 100644
index 00be720..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Api.java
+++ /dev/null
@@ -1,1803 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/api.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * Api is a light-weight descriptor for an API Interface.
- * Interfaces are also described as "protocol buffer services" in some contexts,
- * such as by the "service" keyword in a .proto file, but they are different
- * from API Services, which represent a concrete implementation of an interface
- * as opposed to simply a description of methods and bindings. They are also
- * sometimes simply referred to as "APIs" in other contexts, such as the name of
- * this message itself. See https://cloud.google.com/apis/design/glossary for
- * detailed terminology.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.Api}
- */
-public  final class Api extends
-    com.google.protobuf.GeneratedMessageLite<
-        Api, Api.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.Api)
-    ApiOrBuilder {
-  private Api() {
-    name_ = "";
-    methods_ = emptyProtobufList();
-    options_ = emptyProtobufList();
-    version_ = "";
-    mixins_ = emptyProtobufList();
-  }
-  public static final int NAME_FIELD_NUMBER = 1;
-  private java.lang.String name_;
-  /**
-   * <pre>
-   * The fully qualified name of this interface, including package name
-   * followed by the interface's simple name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The name.
-   */
-  @java.lang.Override
-  public java.lang.String getName() {
-    return name_;
-  }
-  /**
-   * <pre>
-   * The fully qualified name of this interface, including package name
-   * followed by the interface's simple name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The bytes for name.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getNameBytes() {
-    return com.google.protobuf.ByteString.copyFromUtf8(name_);
-  }
-  /**
-   * <pre>
-   * The fully qualified name of this interface, including package name
-   * followed by the interface's simple name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @param value The name to set.
-   */
-  private void setName(
-      java.lang.String value) {
-    value.getClass();
-  
-    name_ = value;
-  }
-  /**
-   * <pre>
-   * The fully qualified name of this interface, including package name
-   * followed by the interface's simple name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   */
-  private void clearName() {
-    
-    name_ = getDefaultInstance().getName();
-  }
-  /**
-   * <pre>
-   * The fully qualified name of this interface, including package name
-   * followed by the interface's simple name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @param value The bytes for name to set.
-   */
-  private void setNameBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    name_ = value.toStringUtf8();
-    
-  }
-
-  public static final int METHODS_FIELD_NUMBER = 2;
-  private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Method> methods_;
-  /**
-   * <pre>
-   * The methods of this interface, in unspecified order.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Method methods = 2;</code>
-   */
-  @java.lang.Override
-  public java.util.List<com.google.protobuf.Method> getMethodsList() {
-    return methods_;
-  }
-  /**
-   * <pre>
-   * The methods of this interface, in unspecified order.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Method methods = 2;</code>
-   */
-  public java.util.List<? extends com.google.protobuf.MethodOrBuilder> 
-      getMethodsOrBuilderList() {
-    return methods_;
-  }
-  /**
-   * <pre>
-   * The methods of this interface, in unspecified order.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Method methods = 2;</code>
-   */
-  @java.lang.Override
-  public int getMethodsCount() {
-    return methods_.size();
-  }
-  /**
-   * <pre>
-   * The methods of this interface, in unspecified order.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Method methods = 2;</code>
-   */
-  @java.lang.Override
-  public com.google.protobuf.Method getMethods(int index) {
-    return methods_.get(index);
-  }
-  /**
-   * <pre>
-   * The methods of this interface, in unspecified order.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Method methods = 2;</code>
-   */
-  public com.google.protobuf.MethodOrBuilder getMethodsOrBuilder(
-      int index) {
-    return methods_.get(index);
-  }
-  private void ensureMethodsIsMutable() {
-    com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Method> tmp = methods_;
-    if (!tmp.isModifiable()) {
-      methods_ =
-          com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-     }
-  }
-
-  /**
-   * <pre>
-   * The methods of this interface, in unspecified order.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Method methods = 2;</code>
-   */
-  private void setMethods(
-      int index, com.google.protobuf.Method value) {
-    value.getClass();
-  ensureMethodsIsMutable();
-    methods_.set(index, value);
-  }
-  /**
-   * <pre>
-   * The methods of this interface, in unspecified order.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Method methods = 2;</code>
-   */
-  private void addMethods(com.google.protobuf.Method value) {
-    value.getClass();
-  ensureMethodsIsMutable();
-    methods_.add(value);
-  }
-  /**
-   * <pre>
-   * The methods of this interface, in unspecified order.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Method methods = 2;</code>
-   */
-  private void addMethods(
-      int index, com.google.protobuf.Method value) {
-    value.getClass();
-  ensureMethodsIsMutable();
-    methods_.add(index, value);
-  }
-  /**
-   * <pre>
-   * The methods of this interface, in unspecified order.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Method methods = 2;</code>
-   */
-  private void addAllMethods(
-      java.lang.Iterable<? extends com.google.protobuf.Method> values) {
-    ensureMethodsIsMutable();
-    com.google.protobuf.AbstractMessageLite.addAll(
-        values, methods_);
-  }
-  /**
-   * <pre>
-   * The methods of this interface, in unspecified order.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Method methods = 2;</code>
-   */
-  private void clearMethods() {
-    methods_ = emptyProtobufList();
-  }
-  /**
-   * <pre>
-   * The methods of this interface, in unspecified order.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Method methods = 2;</code>
-   */
-  private void removeMethods(int index) {
-    ensureMethodsIsMutable();
-    methods_.remove(index);
-  }
-
-  public static final int OPTIONS_FIELD_NUMBER = 3;
-  private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Option> options_;
-  /**
-   * <pre>
-   * Any metadata attached to the interface.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  @java.lang.Override
-  public java.util.List<com.google.protobuf.Option> getOptionsList() {
-    return options_;
-  }
-  /**
-   * <pre>
-   * Any metadata attached to the interface.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  public java.util.List<? extends com.google.protobuf.OptionOrBuilder> 
-      getOptionsOrBuilderList() {
-    return options_;
-  }
-  /**
-   * <pre>
-   * Any metadata attached to the interface.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  @java.lang.Override
-  public int getOptionsCount() {
-    return options_.size();
-  }
-  /**
-   * <pre>
-   * Any metadata attached to the interface.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  @java.lang.Override
-  public com.google.protobuf.Option getOptions(int index) {
-    return options_.get(index);
-  }
-  /**
-   * <pre>
-   * Any metadata attached to the interface.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  public com.google.protobuf.OptionOrBuilder getOptionsOrBuilder(
-      int index) {
-    return options_.get(index);
-  }
-  private void ensureOptionsIsMutable() {
-    com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Option> tmp = options_;
-    if (!tmp.isModifiable()) {
-      options_ =
-          com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-     }
-  }
-
-  /**
-   * <pre>
-   * Any metadata attached to the interface.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  private void setOptions(
-      int index, com.google.protobuf.Option value) {
-    value.getClass();
-  ensureOptionsIsMutable();
-    options_.set(index, value);
-  }
-  /**
-   * <pre>
-   * Any metadata attached to the interface.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  private void addOptions(com.google.protobuf.Option value) {
-    value.getClass();
-  ensureOptionsIsMutable();
-    options_.add(value);
-  }
-  /**
-   * <pre>
-   * Any metadata attached to the interface.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  private void addOptions(
-      int index, com.google.protobuf.Option value) {
-    value.getClass();
-  ensureOptionsIsMutable();
-    options_.add(index, value);
-  }
-  /**
-   * <pre>
-   * Any metadata attached to the interface.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  private void addAllOptions(
-      java.lang.Iterable<? extends com.google.protobuf.Option> values) {
-    ensureOptionsIsMutable();
-    com.google.protobuf.AbstractMessageLite.addAll(
-        values, options_);
-  }
-  /**
-   * <pre>
-   * Any metadata attached to the interface.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  private void clearOptions() {
-    options_ = emptyProtobufList();
-  }
-  /**
-   * <pre>
-   * Any metadata attached to the interface.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  private void removeOptions(int index) {
-    ensureOptionsIsMutable();
-    options_.remove(index);
-  }
-
-  public static final int VERSION_FIELD_NUMBER = 4;
-  private java.lang.String version_;
-  /**
-   * <pre>
-   * A version string for this interface. If specified, must have the form
-   * `major-version.minor-version`, as in `1.10`. If the minor version is
-   * omitted, it defaults to zero. If the entire version field is empty, the
-   * major version is derived from the package name, as outlined below. If the
-   * field is not empty, the version in the package name will be verified to be
-   * consistent with what is provided here.
-   * The versioning schema uses [semantic
-   * versioning](http://semver.org) where the major version number
-   * indicates a breaking change and the minor version an additive,
-   * non-breaking change. Both version numbers are signals to users
-   * what to expect from different versions, and should be carefully
-   * chosen based on the product plan.
-   * The major version is also reflected in the package name of the
-   * interface, which must end in `v&lt;major-version&gt;`, as in
-   * `google.feature.v1`. For major versions 0 and 1, the suffix can
-   * be omitted. Zero major versions must only be used for
-   * experimental, non-GA interfaces.
-   * </pre>
-   *
-   * <code>string version = 4;</code>
-   * @return The version.
-   */
-  @java.lang.Override
-  public java.lang.String getVersion() {
-    return version_;
-  }
-  /**
-   * <pre>
-   * A version string for this interface. If specified, must have the form
-   * `major-version.minor-version`, as in `1.10`. If the minor version is
-   * omitted, it defaults to zero. If the entire version field is empty, the
-   * major version is derived from the package name, as outlined below. If the
-   * field is not empty, the version in the package name will be verified to be
-   * consistent with what is provided here.
-   * The versioning schema uses [semantic
-   * versioning](http://semver.org) where the major version number
-   * indicates a breaking change and the minor version an additive,
-   * non-breaking change. Both version numbers are signals to users
-   * what to expect from different versions, and should be carefully
-   * chosen based on the product plan.
-   * The major version is also reflected in the package name of the
-   * interface, which must end in `v&lt;major-version&gt;`, as in
-   * `google.feature.v1`. For major versions 0 and 1, the suffix can
-   * be omitted. Zero major versions must only be used for
-   * experimental, non-GA interfaces.
-   * </pre>
-   *
-   * <code>string version = 4;</code>
-   * @return The bytes for version.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getVersionBytes() {
-    return com.google.protobuf.ByteString.copyFromUtf8(version_);
-  }
-  /**
-   * <pre>
-   * A version string for this interface. If specified, must have the form
-   * `major-version.minor-version`, as in `1.10`. If the minor version is
-   * omitted, it defaults to zero. If the entire version field is empty, the
-   * major version is derived from the package name, as outlined below. If the
-   * field is not empty, the version in the package name will be verified to be
-   * consistent with what is provided here.
-   * The versioning schema uses [semantic
-   * versioning](http://semver.org) where the major version number
-   * indicates a breaking change and the minor version an additive,
-   * non-breaking change. Both version numbers are signals to users
-   * what to expect from different versions, and should be carefully
-   * chosen based on the product plan.
-   * The major version is also reflected in the package name of the
-   * interface, which must end in `v&lt;major-version&gt;`, as in
-   * `google.feature.v1`. For major versions 0 and 1, the suffix can
-   * be omitted. Zero major versions must only be used for
-   * experimental, non-GA interfaces.
-   * </pre>
-   *
-   * <code>string version = 4;</code>
-   * @param value The version to set.
-   */
-  private void setVersion(
-      java.lang.String value) {
-    value.getClass();
-  
-    version_ = value;
-  }
-  /**
-   * <pre>
-   * A version string for this interface. If specified, must have the form
-   * `major-version.minor-version`, as in `1.10`. If the minor version is
-   * omitted, it defaults to zero. If the entire version field is empty, the
-   * major version is derived from the package name, as outlined below. If the
-   * field is not empty, the version in the package name will be verified to be
-   * consistent with what is provided here.
-   * The versioning schema uses [semantic
-   * versioning](http://semver.org) where the major version number
-   * indicates a breaking change and the minor version an additive,
-   * non-breaking change. Both version numbers are signals to users
-   * what to expect from different versions, and should be carefully
-   * chosen based on the product plan.
-   * The major version is also reflected in the package name of the
-   * interface, which must end in `v&lt;major-version&gt;`, as in
-   * `google.feature.v1`. For major versions 0 and 1, the suffix can
-   * be omitted. Zero major versions must only be used for
-   * experimental, non-GA interfaces.
-   * </pre>
-   *
-   * <code>string version = 4;</code>
-   */
-  private void clearVersion() {
-    
-    version_ = getDefaultInstance().getVersion();
-  }
-  /**
-   * <pre>
-   * A version string for this interface. If specified, must have the form
-   * `major-version.minor-version`, as in `1.10`. If the minor version is
-   * omitted, it defaults to zero. If the entire version field is empty, the
-   * major version is derived from the package name, as outlined below. If the
-   * field is not empty, the version in the package name will be verified to be
-   * consistent with what is provided here.
-   * The versioning schema uses [semantic
-   * versioning](http://semver.org) where the major version number
-   * indicates a breaking change and the minor version an additive,
-   * non-breaking change. Both version numbers are signals to users
-   * what to expect from different versions, and should be carefully
-   * chosen based on the product plan.
-   * The major version is also reflected in the package name of the
-   * interface, which must end in `v&lt;major-version&gt;`, as in
-   * `google.feature.v1`. For major versions 0 and 1, the suffix can
-   * be omitted. Zero major versions must only be used for
-   * experimental, non-GA interfaces.
-   * </pre>
-   *
-   * <code>string version = 4;</code>
-   * @param value The bytes for version to set.
-   */
-  private void setVersionBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    version_ = value.toStringUtf8();
-    
-  }
-
-  public static final int SOURCE_CONTEXT_FIELD_NUMBER = 5;
-  private com.google.protobuf.SourceContext sourceContext_;
-  /**
-   * <pre>
-   * Source context for the protocol buffer service represented by this
-   * message.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 5;</code>
-   */
-  @java.lang.Override
-  public boolean hasSourceContext() {
-    return sourceContext_ != null;
-  }
-  /**
-   * <pre>
-   * Source context for the protocol buffer service represented by this
-   * message.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 5;</code>
-   */
-  @java.lang.Override
-  public com.google.protobuf.SourceContext getSourceContext() {
-    return sourceContext_ == null ? com.google.protobuf.SourceContext.getDefaultInstance() : sourceContext_;
-  }
-  /**
-   * <pre>
-   * Source context for the protocol buffer service represented by this
-   * message.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 5;</code>
-   */
-  private void setSourceContext(com.google.protobuf.SourceContext value) {
-    value.getClass();
-  sourceContext_ = value;
-    
-    }
-  /**
-   * <pre>
-   * Source context for the protocol buffer service represented by this
-   * message.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 5;</code>
-   */
-  @java.lang.SuppressWarnings({"ReferenceEquality"})
-  private void mergeSourceContext(com.google.protobuf.SourceContext value) {
-    value.getClass();
-  if (sourceContext_ != null &&
-        sourceContext_ != com.google.protobuf.SourceContext.getDefaultInstance()) {
-      sourceContext_ =
-        com.google.protobuf.SourceContext.newBuilder(sourceContext_).mergeFrom(value).buildPartial();
-    } else {
-      sourceContext_ = value;
-    }
-    
-  }
-  /**
-   * <pre>
-   * Source context for the protocol buffer service represented by this
-   * message.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 5;</code>
-   */
-  private void clearSourceContext() {  sourceContext_ = null;
-    
-  }
-
-  public static final int MIXINS_FIELD_NUMBER = 6;
-  private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Mixin> mixins_;
-  /**
-   * <pre>
-   * Included interfaces. See [Mixin][].
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-   */
-  @java.lang.Override
-  public java.util.List<com.google.protobuf.Mixin> getMixinsList() {
-    return mixins_;
-  }
-  /**
-   * <pre>
-   * Included interfaces. See [Mixin][].
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-   */
-  public java.util.List<? extends com.google.protobuf.MixinOrBuilder> 
-      getMixinsOrBuilderList() {
-    return mixins_;
-  }
-  /**
-   * <pre>
-   * Included interfaces. See [Mixin][].
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-   */
-  @java.lang.Override
-  public int getMixinsCount() {
-    return mixins_.size();
-  }
-  /**
-   * <pre>
-   * Included interfaces. See [Mixin][].
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-   */
-  @java.lang.Override
-  public com.google.protobuf.Mixin getMixins(int index) {
-    return mixins_.get(index);
-  }
-  /**
-   * <pre>
-   * Included interfaces. See [Mixin][].
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-   */
-  public com.google.protobuf.MixinOrBuilder getMixinsOrBuilder(
-      int index) {
-    return mixins_.get(index);
-  }
-  private void ensureMixinsIsMutable() {
-    com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Mixin> tmp = mixins_;
-    if (!tmp.isModifiable()) {
-      mixins_ =
-          com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-     }
-  }
-
-  /**
-   * <pre>
-   * Included interfaces. See [Mixin][].
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-   */
-  private void setMixins(
-      int index, com.google.protobuf.Mixin value) {
-    value.getClass();
-  ensureMixinsIsMutable();
-    mixins_.set(index, value);
-  }
-  /**
-   * <pre>
-   * Included interfaces. See [Mixin][].
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-   */
-  private void addMixins(com.google.protobuf.Mixin value) {
-    value.getClass();
-  ensureMixinsIsMutable();
-    mixins_.add(value);
-  }
-  /**
-   * <pre>
-   * Included interfaces. See [Mixin][].
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-   */
-  private void addMixins(
-      int index, com.google.protobuf.Mixin value) {
-    value.getClass();
-  ensureMixinsIsMutable();
-    mixins_.add(index, value);
-  }
-  /**
-   * <pre>
-   * Included interfaces. See [Mixin][].
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-   */
-  private void addAllMixins(
-      java.lang.Iterable<? extends com.google.protobuf.Mixin> values) {
-    ensureMixinsIsMutable();
-    com.google.protobuf.AbstractMessageLite.addAll(
-        values, mixins_);
-  }
-  /**
-   * <pre>
-   * Included interfaces. See [Mixin][].
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-   */
-  private void clearMixins() {
-    mixins_ = emptyProtobufList();
-  }
-  /**
-   * <pre>
-   * Included interfaces. See [Mixin][].
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-   */
-  private void removeMixins(int index) {
-    ensureMixinsIsMutable();
-    mixins_.remove(index);
-  }
-
-  public static final int SYNTAX_FIELD_NUMBER = 7;
-  private int syntax_;
-  /**
-   * <pre>
-   * The source syntax of the service.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 7;</code>
-   * @return The enum numeric value on the wire for syntax.
-   */
-  @java.lang.Override
-  public int getSyntaxValue() {
-    return syntax_;
-  }
-  /**
-   * <pre>
-   * The source syntax of the service.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 7;</code>
-   * @return The syntax.
-   */
-  @java.lang.Override
-  public com.google.protobuf.Syntax getSyntax() {
-    com.google.protobuf.Syntax result = com.google.protobuf.Syntax.forNumber(syntax_);
-    return result == null ? com.google.protobuf.Syntax.UNRECOGNIZED : result;
-  }
-  /**
-   * <pre>
-   * The source syntax of the service.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 7;</code>
-   * @param value The enum numeric value on the wire for syntax to set.
-   */
-  private void setSyntaxValue(int value) {
-      syntax_ = value;
-  }
-  /**
-   * <pre>
-   * The source syntax of the service.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 7;</code>
-   * @param value The syntax to set.
-   */
-  private void setSyntax(com.google.protobuf.Syntax value) {
-    syntax_ = value.getNumber();
-    
-  }
-  /**
-   * <pre>
-   * The source syntax of the service.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 7;</code>
-   */
-  private void clearSyntax() {
-    
-    syntax_ = 0;
-  }
-
-  public static com.google.protobuf.Api parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Api parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Api parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Api parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Api parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Api parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Api parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Api parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Api parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Api parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Api parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Api parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.Api prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * Api is a light-weight descriptor for an API Interface.
-   * Interfaces are also described as "protocol buffer services" in some contexts,
-   * such as by the "service" keyword in a .proto file, but they are different
-   * from API Services, which represent a concrete implementation of an interface
-   * as opposed to simply a description of methods and bindings. They are also
-   * sometimes simply referred to as "APIs" in other contexts, such as the name of
-   * this message itself. See https://cloud.google.com/apis/design/glossary for
-   * detailed terminology.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.Api}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.Api, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.Api)
-      com.google.protobuf.ApiOrBuilder {
-    // Construct using com.google.protobuf.Api.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * The fully qualified name of this interface, including package name
-     * followed by the interface's simple name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return The name.
-     */
-    @java.lang.Override
-    public java.lang.String getName() {
-      return instance.getName();
-    }
-    /**
-     * <pre>
-     * The fully qualified name of this interface, including package name
-     * followed by the interface's simple name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return The bytes for name.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getNameBytes() {
-      return instance.getNameBytes();
-    }
-    /**
-     * <pre>
-     * The fully qualified name of this interface, including package name
-     * followed by the interface's simple name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @param value The name to set.
-     * @return This builder for chaining.
-     */
-    public Builder setName(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.setName(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The fully qualified name of this interface, including package name
-     * followed by the interface's simple name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearName() {
-      copyOnWrite();
-      instance.clearName();
-      return this;
-    }
-    /**
-     * <pre>
-     * The fully qualified name of this interface, including package name
-     * followed by the interface's simple name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @param value The bytes for name to set.
-     * @return This builder for chaining.
-     */
-    public Builder setNameBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setNameBytes(value);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The methods of this interface, in unspecified order.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Method methods = 2;</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.Method> getMethodsList() {
-      return java.util.Collections.unmodifiableList(
-          instance.getMethodsList());
-    }
-    /**
-     * <pre>
-     * The methods of this interface, in unspecified order.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Method methods = 2;</code>
-     */
-    @java.lang.Override
-    public int getMethodsCount() {
-      return instance.getMethodsCount();
-    }/**
-     * <pre>
-     * The methods of this interface, in unspecified order.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Method methods = 2;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.Method getMethods(int index) {
-      return instance.getMethods(index);
-    }
-    /**
-     * <pre>
-     * The methods of this interface, in unspecified order.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Method methods = 2;</code>
-     */
-    public Builder setMethods(
-        int index, com.google.protobuf.Method value) {
-      copyOnWrite();
-      instance.setMethods(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The methods of this interface, in unspecified order.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Method methods = 2;</code>
-     */
-    public Builder setMethods(
-        int index, com.google.protobuf.Method.Builder builderForValue) {
-      copyOnWrite();
-      instance.setMethods(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * The methods of this interface, in unspecified order.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Method methods = 2;</code>
-     */
-    public Builder addMethods(com.google.protobuf.Method value) {
-      copyOnWrite();
-      instance.addMethods(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The methods of this interface, in unspecified order.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Method methods = 2;</code>
-     */
-    public Builder addMethods(
-        int index, com.google.protobuf.Method value) {
-      copyOnWrite();
-      instance.addMethods(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The methods of this interface, in unspecified order.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Method methods = 2;</code>
-     */
-    public Builder addMethods(
-        com.google.protobuf.Method.Builder builderForValue) {
-      copyOnWrite();
-      instance.addMethods(builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * The methods of this interface, in unspecified order.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Method methods = 2;</code>
-     */
-    public Builder addMethods(
-        int index, com.google.protobuf.Method.Builder builderForValue) {
-      copyOnWrite();
-      instance.addMethods(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * The methods of this interface, in unspecified order.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Method methods = 2;</code>
-     */
-    public Builder addAllMethods(
-        java.lang.Iterable<? extends com.google.protobuf.Method> values) {
-      copyOnWrite();
-      instance.addAllMethods(values);
-      return this;
-    }
-    /**
-     * <pre>
-     * The methods of this interface, in unspecified order.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Method methods = 2;</code>
-     */
-    public Builder clearMethods() {
-      copyOnWrite();
-      instance.clearMethods();
-      return this;
-    }
-    /**
-     * <pre>
-     * The methods of this interface, in unspecified order.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Method methods = 2;</code>
-     */
-    public Builder removeMethods(int index) {
-      copyOnWrite();
-      instance.removeMethods(index);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * Any metadata attached to the interface.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.Option> getOptionsList() {
-      return java.util.Collections.unmodifiableList(
-          instance.getOptionsList());
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the interface.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    @java.lang.Override
-    public int getOptionsCount() {
-      return instance.getOptionsCount();
-    }/**
-     * <pre>
-     * Any metadata attached to the interface.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.Option getOptions(int index) {
-      return instance.getOptions(index);
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the interface.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder setOptions(
-        int index, com.google.protobuf.Option value) {
-      copyOnWrite();
-      instance.setOptions(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the interface.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder setOptions(
-        int index, com.google.protobuf.Option.Builder builderForValue) {
-      copyOnWrite();
-      instance.setOptions(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the interface.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder addOptions(com.google.protobuf.Option value) {
-      copyOnWrite();
-      instance.addOptions(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the interface.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder addOptions(
-        int index, com.google.protobuf.Option value) {
-      copyOnWrite();
-      instance.addOptions(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the interface.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder addOptions(
-        com.google.protobuf.Option.Builder builderForValue) {
-      copyOnWrite();
-      instance.addOptions(builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the interface.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder addOptions(
-        int index, com.google.protobuf.Option.Builder builderForValue) {
-      copyOnWrite();
-      instance.addOptions(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the interface.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder addAllOptions(
-        java.lang.Iterable<? extends com.google.protobuf.Option> values) {
-      copyOnWrite();
-      instance.addAllOptions(values);
-      return this;
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the interface.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder clearOptions() {
-      copyOnWrite();
-      instance.clearOptions();
-      return this;
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the interface.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder removeOptions(int index) {
-      copyOnWrite();
-      instance.removeOptions(index);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * A version string for this interface. If specified, must have the form
-     * `major-version.minor-version`, as in `1.10`. If the minor version is
-     * omitted, it defaults to zero. If the entire version field is empty, the
-     * major version is derived from the package name, as outlined below. If the
-     * field is not empty, the version in the package name will be verified to be
-     * consistent with what is provided here.
-     * The versioning schema uses [semantic
-     * versioning](http://semver.org) where the major version number
-     * indicates a breaking change and the minor version an additive,
-     * non-breaking change. Both version numbers are signals to users
-     * what to expect from different versions, and should be carefully
-     * chosen based on the product plan.
-     * The major version is also reflected in the package name of the
-     * interface, which must end in `v&lt;major-version&gt;`, as in
-     * `google.feature.v1`. For major versions 0 and 1, the suffix can
-     * be omitted. Zero major versions must only be used for
-     * experimental, non-GA interfaces.
-     * </pre>
-     *
-     * <code>string version = 4;</code>
-     * @return The version.
-     */
-    @java.lang.Override
-    public java.lang.String getVersion() {
-      return instance.getVersion();
-    }
-    /**
-     * <pre>
-     * A version string for this interface. If specified, must have the form
-     * `major-version.minor-version`, as in `1.10`. If the minor version is
-     * omitted, it defaults to zero. If the entire version field is empty, the
-     * major version is derived from the package name, as outlined below. If the
-     * field is not empty, the version in the package name will be verified to be
-     * consistent with what is provided here.
-     * The versioning schema uses [semantic
-     * versioning](http://semver.org) where the major version number
-     * indicates a breaking change and the minor version an additive,
-     * non-breaking change. Both version numbers are signals to users
-     * what to expect from different versions, and should be carefully
-     * chosen based on the product plan.
-     * The major version is also reflected in the package name of the
-     * interface, which must end in `v&lt;major-version&gt;`, as in
-     * `google.feature.v1`. For major versions 0 and 1, the suffix can
-     * be omitted. Zero major versions must only be used for
-     * experimental, non-GA interfaces.
-     * </pre>
-     *
-     * <code>string version = 4;</code>
-     * @return The bytes for version.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getVersionBytes() {
-      return instance.getVersionBytes();
-    }
-    /**
-     * <pre>
-     * A version string for this interface. If specified, must have the form
-     * `major-version.minor-version`, as in `1.10`. If the minor version is
-     * omitted, it defaults to zero. If the entire version field is empty, the
-     * major version is derived from the package name, as outlined below. If the
-     * field is not empty, the version in the package name will be verified to be
-     * consistent with what is provided here.
-     * The versioning schema uses [semantic
-     * versioning](http://semver.org) where the major version number
-     * indicates a breaking change and the minor version an additive,
-     * non-breaking change. Both version numbers are signals to users
-     * what to expect from different versions, and should be carefully
-     * chosen based on the product plan.
-     * The major version is also reflected in the package name of the
-     * interface, which must end in `v&lt;major-version&gt;`, as in
-     * `google.feature.v1`. For major versions 0 and 1, the suffix can
-     * be omitted. Zero major versions must only be used for
-     * experimental, non-GA interfaces.
-     * </pre>
-     *
-     * <code>string version = 4;</code>
-     * @param value The version to set.
-     * @return This builder for chaining.
-     */
-    public Builder setVersion(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.setVersion(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * A version string for this interface. If specified, must have the form
-     * `major-version.minor-version`, as in `1.10`. If the minor version is
-     * omitted, it defaults to zero. If the entire version field is empty, the
-     * major version is derived from the package name, as outlined below. If the
-     * field is not empty, the version in the package name will be verified to be
-     * consistent with what is provided here.
-     * The versioning schema uses [semantic
-     * versioning](http://semver.org) where the major version number
-     * indicates a breaking change and the minor version an additive,
-     * non-breaking change. Both version numbers are signals to users
-     * what to expect from different versions, and should be carefully
-     * chosen based on the product plan.
-     * The major version is also reflected in the package name of the
-     * interface, which must end in `v&lt;major-version&gt;`, as in
-     * `google.feature.v1`. For major versions 0 and 1, the suffix can
-     * be omitted. Zero major versions must only be used for
-     * experimental, non-GA interfaces.
-     * </pre>
-     *
-     * <code>string version = 4;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearVersion() {
-      copyOnWrite();
-      instance.clearVersion();
-      return this;
-    }
-    /**
-     * <pre>
-     * A version string for this interface. If specified, must have the form
-     * `major-version.minor-version`, as in `1.10`. If the minor version is
-     * omitted, it defaults to zero. If the entire version field is empty, the
-     * major version is derived from the package name, as outlined below. If the
-     * field is not empty, the version in the package name will be verified to be
-     * consistent with what is provided here.
-     * The versioning schema uses [semantic
-     * versioning](http://semver.org) where the major version number
-     * indicates a breaking change and the minor version an additive,
-     * non-breaking change. Both version numbers are signals to users
-     * what to expect from different versions, and should be carefully
-     * chosen based on the product plan.
-     * The major version is also reflected in the package name of the
-     * interface, which must end in `v&lt;major-version&gt;`, as in
-     * `google.feature.v1`. For major versions 0 and 1, the suffix can
-     * be omitted. Zero major versions must only be used for
-     * experimental, non-GA interfaces.
-     * </pre>
-     *
-     * <code>string version = 4;</code>
-     * @param value The bytes for version to set.
-     * @return This builder for chaining.
-     */
-    public Builder setVersionBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setVersionBytes(value);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * Source context for the protocol buffer service represented by this
-     * message.
-     * </pre>
-     *
-     * <code>.google.protobuf.SourceContext source_context = 5;</code>
-     */
-    @java.lang.Override
-    public boolean hasSourceContext() {
-      return instance.hasSourceContext();
-    }
-    /**
-     * <pre>
-     * Source context for the protocol buffer service represented by this
-     * message.
-     * </pre>
-     *
-     * <code>.google.protobuf.SourceContext source_context = 5;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.SourceContext getSourceContext() {
-      return instance.getSourceContext();
-    }
-    /**
-     * <pre>
-     * Source context for the protocol buffer service represented by this
-     * message.
-     * </pre>
-     *
-     * <code>.google.protobuf.SourceContext source_context = 5;</code>
-     */
-    public Builder setSourceContext(com.google.protobuf.SourceContext value) {
-      copyOnWrite();
-      instance.setSourceContext(value);
-      return this;
-      }
-    /**
-     * <pre>
-     * Source context for the protocol buffer service represented by this
-     * message.
-     * </pre>
-     *
-     * <code>.google.protobuf.SourceContext source_context = 5;</code>
-     */
-    public Builder setSourceContext(
-        com.google.protobuf.SourceContext.Builder builderForValue) {
-      copyOnWrite();
-      instance.setSourceContext(builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Source context for the protocol buffer service represented by this
-     * message.
-     * </pre>
-     *
-     * <code>.google.protobuf.SourceContext source_context = 5;</code>
-     */
-    public Builder mergeSourceContext(com.google.protobuf.SourceContext value) {
-      copyOnWrite();
-      instance.mergeSourceContext(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Source context for the protocol buffer service represented by this
-     * message.
-     * </pre>
-     *
-     * <code>.google.protobuf.SourceContext source_context = 5;</code>
-     */
-    public Builder clearSourceContext() {  copyOnWrite();
-      instance.clearSourceContext();
-      return this;
-    }
-
-    /**
-     * <pre>
-     * Included interfaces. See [Mixin][].
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.Mixin> getMixinsList() {
-      return java.util.Collections.unmodifiableList(
-          instance.getMixinsList());
-    }
-    /**
-     * <pre>
-     * Included interfaces. See [Mixin][].
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-     */
-    @java.lang.Override
-    public int getMixinsCount() {
-      return instance.getMixinsCount();
-    }/**
-     * <pre>
-     * Included interfaces. See [Mixin][].
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.Mixin getMixins(int index) {
-      return instance.getMixins(index);
-    }
-    /**
-     * <pre>
-     * Included interfaces. See [Mixin][].
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-     */
-    public Builder setMixins(
-        int index, com.google.protobuf.Mixin value) {
-      copyOnWrite();
-      instance.setMixins(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Included interfaces. See [Mixin][].
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-     */
-    public Builder setMixins(
-        int index, com.google.protobuf.Mixin.Builder builderForValue) {
-      copyOnWrite();
-      instance.setMixins(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Included interfaces. See [Mixin][].
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-     */
-    public Builder addMixins(com.google.protobuf.Mixin value) {
-      copyOnWrite();
-      instance.addMixins(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Included interfaces. See [Mixin][].
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-     */
-    public Builder addMixins(
-        int index, com.google.protobuf.Mixin value) {
-      copyOnWrite();
-      instance.addMixins(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Included interfaces. See [Mixin][].
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-     */
-    public Builder addMixins(
-        com.google.protobuf.Mixin.Builder builderForValue) {
-      copyOnWrite();
-      instance.addMixins(builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Included interfaces. See [Mixin][].
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-     */
-    public Builder addMixins(
-        int index, com.google.protobuf.Mixin.Builder builderForValue) {
-      copyOnWrite();
-      instance.addMixins(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Included interfaces. See [Mixin][].
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-     */
-    public Builder addAllMixins(
-        java.lang.Iterable<? extends com.google.protobuf.Mixin> values) {
-      copyOnWrite();
-      instance.addAllMixins(values);
-      return this;
-    }
-    /**
-     * <pre>
-     * Included interfaces. See [Mixin][].
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-     */
-    public Builder clearMixins() {
-      copyOnWrite();
-      instance.clearMixins();
-      return this;
-    }
-    /**
-     * <pre>
-     * Included interfaces. See [Mixin][].
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-     */
-    public Builder removeMixins(int index) {
-      copyOnWrite();
-      instance.removeMixins(index);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The source syntax of the service.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 7;</code>
-     * @return The enum numeric value on the wire for syntax.
-     */
-    @java.lang.Override
-    public int getSyntaxValue() {
-      return instance.getSyntaxValue();
-    }
-    /**
-     * <pre>
-     * The source syntax of the service.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 7;</code>
-     * @param value The syntax to set.
-     * @return This builder for chaining.
-     */
-    public Builder setSyntaxValue(int value) {
-      copyOnWrite();
-      instance.setSyntaxValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The source syntax of the service.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 7;</code>
-     * @return The syntax.
-     */
-    @java.lang.Override
-    public com.google.protobuf.Syntax getSyntax() {
-      return instance.getSyntax();
-    }
-    /**
-     * <pre>
-     * The source syntax of the service.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 7;</code>
-     * @param value The enum numeric value on the wire for syntax to set.
-     * @return This builder for chaining.
-     */
-    public Builder setSyntax(com.google.protobuf.Syntax value) {
-      copyOnWrite();
-      instance.setSyntax(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The source syntax of the service.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 7;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearSyntax() {
-      copyOnWrite();
-      instance.clearSyntax();
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.Api)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.Api();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "name_",
-            "methods_",
-            com.google.protobuf.Method.class,
-            "options_",
-            com.google.protobuf.Option.class,
-            "version_",
-            "sourceContext_",
-            "mixins_",
-            com.google.protobuf.Mixin.class,
-            "syntax_",
-          };
-          java.lang.String info =
-              "\u0000\u0007\u0000\u0000\u0001\u0007\u0007\u0000\u0003\u0000\u0001\u0208\u0002\u001b" +
-              "\u0003\u001b\u0004\u0208\u0005\t\u0006\u001b\u0007\f";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.Api> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.Api.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.Api>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.Api)
-  private static final com.google.protobuf.Api DEFAULT_INSTANCE;
-  static {
-    Api defaultInstance = new Api();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      Api.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.Api getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<Api> PARSER;
-
-  public static com.google.protobuf.Parser<Api> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ApiOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ApiOrBuilder.java
deleted file mode 100644
index e663aa9..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ApiOrBuilder.java
+++ /dev/null
@@ -1,201 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/api.proto
-
-package com.google.protobuf;
-
-public interface ApiOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.Api)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * The fully qualified name of this interface, including package name
-   * followed by the interface's simple name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The name.
-   */
-  java.lang.String getName();
-  /**
-   * <pre>
-   * The fully qualified name of this interface, including package name
-   * followed by the interface's simple name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The bytes for name.
-   */
-  com.google.protobuf.ByteString
-      getNameBytes();
-
-  /**
-   * <pre>
-   * The methods of this interface, in unspecified order.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Method methods = 2;</code>
-   */
-  java.util.List<com.google.protobuf.Method> 
-      getMethodsList();
-  /**
-   * <pre>
-   * The methods of this interface, in unspecified order.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Method methods = 2;</code>
-   */
-  com.google.protobuf.Method getMethods(int index);
-  /**
-   * <pre>
-   * The methods of this interface, in unspecified order.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Method methods = 2;</code>
-   */
-  int getMethodsCount();
-
-  /**
-   * <pre>
-   * Any metadata attached to the interface.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  java.util.List<com.google.protobuf.Option> 
-      getOptionsList();
-  /**
-   * <pre>
-   * Any metadata attached to the interface.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  com.google.protobuf.Option getOptions(int index);
-  /**
-   * <pre>
-   * Any metadata attached to the interface.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  int getOptionsCount();
-
-  /**
-   * <pre>
-   * A version string for this interface. If specified, must have the form
-   * `major-version.minor-version`, as in `1.10`. If the minor version is
-   * omitted, it defaults to zero. If the entire version field is empty, the
-   * major version is derived from the package name, as outlined below. If the
-   * field is not empty, the version in the package name will be verified to be
-   * consistent with what is provided here.
-   * The versioning schema uses [semantic
-   * versioning](http://semver.org) where the major version number
-   * indicates a breaking change and the minor version an additive,
-   * non-breaking change. Both version numbers are signals to users
-   * what to expect from different versions, and should be carefully
-   * chosen based on the product plan.
-   * The major version is also reflected in the package name of the
-   * interface, which must end in `v&lt;major-version&gt;`, as in
-   * `google.feature.v1`. For major versions 0 and 1, the suffix can
-   * be omitted. Zero major versions must only be used for
-   * experimental, non-GA interfaces.
-   * </pre>
-   *
-   * <code>string version = 4;</code>
-   * @return The version.
-   */
-  java.lang.String getVersion();
-  /**
-   * <pre>
-   * A version string for this interface. If specified, must have the form
-   * `major-version.minor-version`, as in `1.10`. If the minor version is
-   * omitted, it defaults to zero. If the entire version field is empty, the
-   * major version is derived from the package name, as outlined below. If the
-   * field is not empty, the version in the package name will be verified to be
-   * consistent with what is provided here.
-   * The versioning schema uses [semantic
-   * versioning](http://semver.org) where the major version number
-   * indicates a breaking change and the minor version an additive,
-   * non-breaking change. Both version numbers are signals to users
-   * what to expect from different versions, and should be carefully
-   * chosen based on the product plan.
-   * The major version is also reflected in the package name of the
-   * interface, which must end in `v&lt;major-version&gt;`, as in
-   * `google.feature.v1`. For major versions 0 and 1, the suffix can
-   * be omitted. Zero major versions must only be used for
-   * experimental, non-GA interfaces.
-   * </pre>
-   *
-   * <code>string version = 4;</code>
-   * @return The bytes for version.
-   */
-  com.google.protobuf.ByteString
-      getVersionBytes();
-
-  /**
-   * <pre>
-   * Source context for the protocol buffer service represented by this
-   * message.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 5;</code>
-   * @return Whether the sourceContext field is set.
-   */
-  boolean hasSourceContext();
-  /**
-   * <pre>
-   * Source context for the protocol buffer service represented by this
-   * message.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 5;</code>
-   * @return The sourceContext.
-   */
-  com.google.protobuf.SourceContext getSourceContext();
-
-  /**
-   * <pre>
-   * Included interfaces. See [Mixin][].
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-   */
-  java.util.List<com.google.protobuf.Mixin> 
-      getMixinsList();
-  /**
-   * <pre>
-   * Included interfaces. See [Mixin][].
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-   */
-  com.google.protobuf.Mixin getMixins(int index);
-  /**
-   * <pre>
-   * Included interfaces. See [Mixin][].
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Mixin mixins = 6;</code>
-   */
-  int getMixinsCount();
-
-  /**
-   * <pre>
-   * The source syntax of the service.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 7;</code>
-   * @return The enum numeric value on the wire for syntax.
-   */
-  int getSyntaxValue();
-  /**
-   * <pre>
-   * The source syntax of the service.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 7;</code>
-   * @return The syntax.
-   */
-  com.google.protobuf.Syntax getSyntax();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ApiProto.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ApiProto.java
deleted file mode 100644
index 79a9b3d..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ApiProto.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/api.proto
-
-package com.google.protobuf;
-
-public final class ApiProto {
-  private ApiProto() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ArrayDecoders.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ArrayDecoders.java
deleted file mode 100644
index 1217e11..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ArrayDecoders.java
+++ /dev/null
@@ -1,1076 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.MessageSchema.getMutableUnknownFields;
-
-import com.google.protobuf.Internal.ProtobufList;
-import java.io.IOException;
-
-/**
- * Helper functions to decode protobuf wire format from a byte array.
- *
- * <p>Note that these functions don't do boundary check on the byte array but instead rely on Java
- * VM to check it. That means parsing routines utilizing these functions must catch
- * IndexOutOfBoundsException and convert it to protobuf's InvalidProtocolBufferException when
- * crossing protobuf public API boundaries.
- */
-final class ArrayDecoders {
-  /**
-   * A helper used to return multiple values in a Java function. Java doesn't natively support
-   * returning multiple values in a function. Creating a new Object to hold the return values will
-   * be too expensive. Instead, we pass a Registers instance to functions that want to return
-   * multiple values and let the function set the return value in this Registers instance instead.
-   *
-   * <p>TODO(xiaofeng): This could be merged into CodedInputStream or CodedInputStreamReader which
-   * is already being passed through all the parsing routines.
-   */
-  static final class Registers {
-    public int int1;
-    public long long1;
-    public Object object1;
-    public final ExtensionRegistryLite extensionRegistry;
-
-    Registers() {
-      this.extensionRegistry = ExtensionRegistryLite.getEmptyRegistry();
-    }
-
-    Registers(ExtensionRegistryLite extensionRegistry) {
-      if (extensionRegistry == null) {
-        throw new NullPointerException();
-      }
-      this.extensionRegistry = extensionRegistry;
-    }
-  }
-
-  /**
-   * Decodes a varint. Returns the position after the varint. The decoded varint is stored in
-   * registers.int1.
-   */
-  static int decodeVarint32(byte[] data, int position, Registers registers) {
-    int value = data[position++];
-    if (value >= 0) {
-      registers.int1 = value;
-      return position;
-    }
-    return decodeVarint32(value, data, position, registers);
-  }
-
-  /** Like decodeVarint32 except that the first byte is already read. */
-  static int decodeVarint32(int firstByte, byte[] data, int position, Registers registers) {
-    int value = firstByte & 0x7F;
-    final byte b2 = data[position++];
-    if (b2 >= 0) {
-      registers.int1 = value | ((int) b2 << 7);
-      return position;
-    }
-    value |= (b2 & 0x7F) << 7;
-
-    final byte b3 = data[position++];
-    if (b3 >= 0) {
-      registers.int1 = value | ((int) b3 << 14);
-      return position;
-    }
-    value |= (b3 & 0x7F) << 14;
-
-    final byte b4 = data[position++];
-    if (b4 >= 0) {
-      registers.int1 = value | ((int) b4 << 21);
-      return position;
-    }
-    value |= (b4 & 0x7F) << 21;
-
-    final byte b5 = data[position++];
-    if (b5 >= 0) {
-      registers.int1 = value | ((int) b5 << 28);
-      return position;
-    }
-    value |= (b5 & 0x7F) << 28;
-
-    while (data[position++] < 0) {}
-
-    registers.int1 = value;
-    return position;
-  }
-
-  /**
-   * Decodes a varint. Returns the position after the varint. The decoded varint is stored in
-   * registers.long1.
-   */
-  static int decodeVarint64(byte[] data, int position, Registers registers) {
-    long value = data[position++];
-    if (value >= 0) {
-      registers.long1 = value;
-      return position;
-    } else {
-      return decodeVarint64(value, data, position, registers);
-    }
-  }
-
-  /** Like decodeVarint64 except that the first byte is already read. */
-  static int decodeVarint64(long firstByte, byte[] data, int position, Registers registers) {
-    long value = firstByte & 0x7F;
-    byte next = data[position++];
-    int shift = 7;
-    value |= (long) (next & 0x7F) << 7;
-    while (next < 0) {
-      next = data[position++];
-      shift += 7;
-      value |= (long) (next & 0x7F) << shift;
-    }
-    registers.long1 = value;
-    return position;
-  }
-
-  /** Decodes and returns a fixed32 value. */
-  static int decodeFixed32(byte[] data, int position) {
-    return (data[position] & 0xff)
-        | ((data[position + 1] & 0xff) << 8)
-        | ((data[position + 2] & 0xff) << 16)
-        | ((data[position + 3] & 0xff) << 24);
-  }
-
-  /** Decodes and returns a fixed64 value. */
-  static long decodeFixed64(byte[] data, int position) {
-    return (data[position] & 0xffL)
-        | ((data[position + 1] & 0xffL) << 8)
-        | ((data[position + 2] & 0xffL) << 16)
-        | ((data[position + 3] & 0xffL) << 24)
-        | ((data[position + 4] & 0xffL) << 32)
-        | ((data[position + 5] & 0xffL) << 40)
-        | ((data[position + 6] & 0xffL) << 48)
-        | ((data[position + 7] & 0xffL) << 56);
-  }
-
-  /** Decodes and returns a double value. */
-  static double decodeDouble(byte[] data, int position) {
-    return Double.longBitsToDouble(decodeFixed64(data, position));
-  }
-
-  /** Decodes and returns a float value. */
-  static float decodeFloat(byte[] data, int position) {
-    return Float.intBitsToFloat(decodeFixed32(data, position));
-  }
-
-  /** Decodes a string value. */
-  static int decodeString(byte[] data, int position, Registers registers)
-      throws InvalidProtocolBufferException {
-    position = decodeVarint32(data, position, registers);
-    final int length = registers.int1;
-    if (length < 0) {
-      throw InvalidProtocolBufferException.negativeSize();
-    } else if (length == 0) {
-      registers.object1 = "";
-      return position;
-    } else {
-      registers.object1 = new String(data, position, length, Internal.UTF_8);
-      return position + length;
-    }
-  }
-
-  /** Decodes a string value with utf8 check. */
-  static int decodeStringRequireUtf8(byte[] data, int position, Registers registers)
-      throws InvalidProtocolBufferException {
-    position = decodeVarint32(data, position, registers);
-    final int length = registers.int1;
-    if (length < 0) {
-      throw InvalidProtocolBufferException.negativeSize();
-    } else if (length == 0) {
-      registers.object1 = "";
-      return position;
-    } else {
-      registers.object1 = Utf8.decodeUtf8(data, position, length);
-      return position + length;
-    }
-  }
-
-  /** Decodes a bytes value. */
-  static int decodeBytes(byte[] data, int position, Registers registers)
-      throws InvalidProtocolBufferException {
-    position = decodeVarint32(data, position, registers);
-    final int length = registers.int1;
-    if (length < 0) {
-      throw InvalidProtocolBufferException.negativeSize();
-    } else if (length > data.length - position) {
-      throw InvalidProtocolBufferException.truncatedMessage();
-    } else if (length == 0) {
-      registers.object1 = ByteString.EMPTY;
-      return position;
-    } else {
-      registers.object1 = ByteString.copyFrom(data, position, length);
-      return position + length;
-    }
-  }
-
-  /** Decodes a message value. */
-  @SuppressWarnings({"unchecked", "rawtypes"})
-  static int decodeMessageField(
-      Schema schema, byte[] data, int position, int limit, Registers registers) throws IOException {
-    int length = data[position++];
-    if (length < 0) {
-      position = decodeVarint32(length, data, position, registers);
-      length = registers.int1;
-    }
-    if (length < 0 || length > limit - position) {
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-    Object result = schema.newInstance();
-    schema.mergeFrom(result, data, position, position + length, registers);
-    schema.makeImmutable(result);
-    registers.object1 = result;
-    return position + length;
-  }
-
-  /** Decodes a group value. */
-  @SuppressWarnings({"unchecked", "rawtypes"})
-  static int decodeGroupField(
-      Schema schema, byte[] data, int position, int limit, int endGroup, Registers registers)
-      throws IOException {
-    // A group field must has a MessageSchema (the only other subclass of Schema is MessageSetSchema
-    // and it can't be used in group fields).
-    final MessageSchema messageSchema = (MessageSchema) schema;
-    Object result = messageSchema.newInstance();
-    // It's OK to directly use parseProto2Message since proto3 doesn't have group.
-    final int endPosition =
-        messageSchema.parseProto2Message(result, data, position, limit, endGroup, registers);
-    messageSchema.makeImmutable(result);
-    registers.object1 = result;
-    return endPosition;
-  }
-
-  /** Decodes a repeated 32-bit varint field. Returns the position after all read values. */
-  static int decodeVarint32List(
-      int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) {
-    final IntArrayList output = (IntArrayList) list;
-    position = decodeVarint32(data, position, registers);
-    output.addInt(registers.int1);
-    while (position < limit) {
-      int nextPosition = decodeVarint32(data, position, registers);
-      if (tag != registers.int1) {
-        break;
-      }
-      position = decodeVarint32(data, nextPosition, registers);
-      output.addInt(registers.int1);
-    }
-    return position;
-  }
-
-  /** Decodes a repeated 64-bit varint field. Returns the position after all read values. */
-  static int decodeVarint64List(
-      int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) {
-    final LongArrayList output = (LongArrayList) list;
-    position = decodeVarint64(data, position, registers);
-    output.addLong(registers.long1);
-    while (position < limit) {
-      int nextPosition = decodeVarint32(data, position, registers);
-      if (tag != registers.int1) {
-        break;
-      }
-      position = decodeVarint64(data, nextPosition, registers);
-      output.addLong(registers.long1);
-    }
-    return position;
-  }
-
-  /** Decodes a repeated fixed32 field. Returns the position after all read values. */
-  static int decodeFixed32List(
-      int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) {
-    final IntArrayList output = (IntArrayList) list;
-    output.addInt(decodeFixed32(data, position));
-    position += 4;
-    while (position < limit) {
-      int nextPosition = decodeVarint32(data, position, registers);
-      if (tag != registers.int1) {
-        break;
-      }
-      output.addInt(decodeFixed32(data, nextPosition));
-      position = nextPosition + 4;
-    }
-    return position;
-  }
-
-  /** Decodes a repeated fixed64 field. Returns the position after all read values. */
-  static int decodeFixed64List(
-      int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) {
-    final LongArrayList output = (LongArrayList) list;
-    output.addLong(decodeFixed64(data, position));
-    position += 8;
-    while (position < limit) {
-      int nextPosition = decodeVarint32(data, position, registers);
-      if (tag != registers.int1) {
-        break;
-      }
-      output.addLong(decodeFixed64(data, nextPosition));
-      position = nextPosition + 8;
-    }
-    return position;
-  }
-
-  /** Decodes a repeated float field. Returns the position after all read values. */
-  static int decodeFloatList(
-      int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) {
-    final FloatArrayList output = (FloatArrayList) list;
-    output.addFloat(decodeFloat(data, position));
-    position += 4;
-    while (position < limit) {
-      int nextPosition = decodeVarint32(data, position, registers);
-      if (tag != registers.int1) {
-        break;
-      }
-      output.addFloat(decodeFloat(data, nextPosition));
-      position = nextPosition + 4;
-    }
-    return position;
-  }
-
-  /** Decodes a repeated double field. Returns the position after all read values. */
-  static int decodeDoubleList(
-      int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) {
-    final DoubleArrayList output = (DoubleArrayList) list;
-    output.addDouble(decodeDouble(data, position));
-    position += 8;
-    while (position < limit) {
-      int nextPosition = decodeVarint32(data, position, registers);
-      if (tag != registers.int1) {
-        break;
-      }
-      output.addDouble(decodeDouble(data, nextPosition));
-      position = nextPosition + 8;
-    }
-    return position;
-  }
-
-  /** Decodes a repeated boolean field. Returns the position after all read values. */
-  static int decodeBoolList(
-      int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) {
-    final BooleanArrayList output = (BooleanArrayList) list;
-    position = decodeVarint64(data, position, registers);
-    output.addBoolean(registers.long1 != 0);
-    while (position < limit) {
-      int nextPosition = decodeVarint32(data, position, registers);
-      if (tag != registers.int1) {
-        break;
-      }
-      position = decodeVarint64(data, nextPosition, registers);
-      output.addBoolean(registers.long1 != 0);
-    }
-    return position;
-  }
-
-  /** Decodes a repeated sint32 field. Returns the position after all read values. */
-  static int decodeSInt32List(
-      int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) {
-    final IntArrayList output = (IntArrayList) list;
-    position = decodeVarint32(data, position, registers);
-    output.addInt(CodedInputStream.decodeZigZag32(registers.int1));
-    while (position < limit) {
-      int nextPosition = decodeVarint32(data, position, registers);
-      if (tag != registers.int1) {
-        break;
-      }
-      position = decodeVarint32(data, nextPosition, registers);
-      output.addInt(CodedInputStream.decodeZigZag32(registers.int1));
-    }
-    return position;
-  }
-
-  /** Decodes a repeated sint64 field. Returns the position after all read values. */
-  static int decodeSInt64List(
-      int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) {
-    final LongArrayList output = (LongArrayList) list;
-    position = decodeVarint64(data, position, registers);
-    output.addLong(CodedInputStream.decodeZigZag64(registers.long1));
-    while (position < limit) {
-      int nextPosition = decodeVarint32(data, position, registers);
-      if (tag != registers.int1) {
-        break;
-      }
-      position = decodeVarint64(data, nextPosition, registers);
-      output.addLong(CodedInputStream.decodeZigZag64(registers.long1));
-    }
-    return position;
-  }
-
-  /** Decodes a packed 32-bit varint field. Returns the position after all read values. */
-  static int decodePackedVarint32List(
-      byte[] data, int position, ProtobufList<?> list, Registers registers) throws IOException {
-    final IntArrayList output = (IntArrayList) list;
-    position = decodeVarint32(data, position, registers);
-    final int fieldLimit = position + registers.int1;
-    while (position < fieldLimit) {
-      position = decodeVarint32(data, position, registers);
-      output.addInt(registers.int1);
-    }
-    if (position != fieldLimit) {
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-    return position;
-  }
-
-  /** Decodes a packed 64-bit varint field. Returns the position after all read values. */
-  static int decodePackedVarint64List(
-      byte[] data, int position, ProtobufList<?> list, Registers registers) throws IOException {
-    final LongArrayList output = (LongArrayList) list;
-    position = decodeVarint32(data, position, registers);
-    final int fieldLimit = position + registers.int1;
-    while (position < fieldLimit) {
-      position = decodeVarint64(data, position, registers);
-      output.addLong(registers.long1);
-    }
-    if (position != fieldLimit) {
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-    return position;
-  }
-
-  /** Decodes a packed fixed32 field. Returns the position after all read values. */
-  static int decodePackedFixed32List(
-      byte[] data, int position, ProtobufList<?> list, Registers registers) throws IOException {
-    final IntArrayList output = (IntArrayList) list;
-    position = decodeVarint32(data, position, registers);
-    final int fieldLimit = position + registers.int1;
-    while (position < fieldLimit) {
-      output.addInt(decodeFixed32(data, position));
-      position += 4;
-    }
-    if (position != fieldLimit) {
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-    return position;
-  }
-
-  /** Decodes a packed fixed64 field. Returns the position after all read values. */
-  static int decodePackedFixed64List(
-      byte[] data, int position, ProtobufList<?> list, Registers registers) throws IOException {
-    final LongArrayList output = (LongArrayList) list;
-    position = decodeVarint32(data, position, registers);
-    final int fieldLimit = position + registers.int1;
-    while (position < fieldLimit) {
-      output.addLong(decodeFixed64(data, position));
-      position += 8;
-    }
-    if (position != fieldLimit) {
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-    return position;
-  }
-
-  /** Decodes a packed float field. Returns the position after all read values. */
-  static int decodePackedFloatList(
-      byte[] data, int position, ProtobufList<?> list, Registers registers) throws IOException {
-    final FloatArrayList output = (FloatArrayList) list;
-    position = decodeVarint32(data, position, registers);
-    final int fieldLimit = position + registers.int1;
-    while (position < fieldLimit) {
-      output.addFloat(decodeFloat(data, position));
-      position += 4;
-    }
-    if (position != fieldLimit) {
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-    return position;
-  }
-
-  /** Decodes a packed double field. Returns the position after all read values. */
-  static int decodePackedDoubleList(
-      byte[] data, int position, ProtobufList<?> list, Registers registers) throws IOException {
-    final DoubleArrayList output = (DoubleArrayList) list;
-    position = decodeVarint32(data, position, registers);
-    final int fieldLimit = position + registers.int1;
-    while (position < fieldLimit) {
-      output.addDouble(decodeDouble(data, position));
-      position += 8;
-    }
-    if (position != fieldLimit) {
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-    return position;
-  }
-
-  /** Decodes a packed boolean field. Returns the position after all read values. */
-  static int decodePackedBoolList(
-      byte[] data, int position, ProtobufList<?> list, Registers registers) throws IOException {
-    final BooleanArrayList output = (BooleanArrayList) list;
-    position = decodeVarint32(data, position, registers);
-    final int fieldLimit = position + registers.int1;
-    while (position < fieldLimit) {
-      position = decodeVarint64(data, position, registers);
-      output.addBoolean(registers.long1 != 0);
-    }
-    if (position != fieldLimit) {
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-    return position;
-  }
-
-  /** Decodes a packed sint32 field. Returns the position after all read values. */
-  static int decodePackedSInt32List(
-      byte[] data, int position, ProtobufList<?> list, Registers registers) throws IOException {
-    final IntArrayList output = (IntArrayList) list;
-    position = decodeVarint32(data, position, registers);
-    final int fieldLimit = position + registers.int1;
-    while (position < fieldLimit) {
-      position = decodeVarint32(data, position, registers);
-      output.addInt(CodedInputStream.decodeZigZag32(registers.int1));
-    }
-    if (position != fieldLimit) {
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-    return position;
-  }
-
-  /** Decodes a packed sint64 field. Returns the position after all read values. */
-  @SuppressWarnings("unchecked")
-  static int decodePackedSInt64List(
-      byte[] data, int position, ProtobufList<?> list, Registers registers) throws IOException {
-    final LongArrayList output = (LongArrayList) list;
-    position = decodeVarint32(data, position, registers);
-    final int fieldLimit = position + registers.int1;
-    while (position < fieldLimit) {
-      position = decodeVarint64(data, position, registers);
-      output.addLong(CodedInputStream.decodeZigZag64(registers.long1));
-    }
-    if (position != fieldLimit) {
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-    return position;
-  }
-
-  /** Decodes a repeated string field. Returns the position after all read values. */
-  @SuppressWarnings("unchecked")
-  static int decodeStringList(
-      int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers)
-      throws InvalidProtocolBufferException {
-    final ProtobufList<String> output = (ProtobufList<String>) list;
-    position = decodeVarint32(data, position, registers);
-    final int length = registers.int1;
-    if (length < 0) {
-      throw InvalidProtocolBufferException.negativeSize();
-    } else if (length == 0) {
-      output.add("");
-    } else {
-      String value = new String(data, position, length, Internal.UTF_8);
-      output.add(value);
-      position += length;
-    }
-    while (position < limit) {
-      int nextPosition = decodeVarint32(data, position, registers);
-      if (tag != registers.int1) {
-        break;
-      }
-      position = decodeVarint32(data, nextPosition, registers);
-      final int nextLength = registers.int1;
-      if (nextLength < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      } else if (nextLength == 0) {
-        output.add("");
-      } else {
-        String value = new String(data, position, nextLength, Internal.UTF_8);
-        output.add(value);
-        position += nextLength;
-      }
-    }
-    return position;
-  }
-
-  /**
-   * Decodes a repeated string field with utf8 check. Returns the position after all read values.
-   */
-  @SuppressWarnings("unchecked")
-  static int decodeStringListRequireUtf8(
-      int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers)
-      throws InvalidProtocolBufferException {
-    final ProtobufList<String> output = (ProtobufList<String>) list;
-    position = decodeVarint32(data, position, registers);
-    final int length = registers.int1;
-    if (length < 0) {
-      throw InvalidProtocolBufferException.negativeSize();
-    } else if (length == 0) {
-      output.add("");
-    } else {
-      if (!Utf8.isValidUtf8(data, position, position + length)) {
-        throw InvalidProtocolBufferException.invalidUtf8();
-      }
-      String value = new String(data, position, length, Internal.UTF_8);
-      output.add(value);
-      position += length;
-    }
-    while (position < limit) {
-      int nextPosition = decodeVarint32(data, position, registers);
-      if (tag != registers.int1) {
-        break;
-      }
-      position = decodeVarint32(data, nextPosition, registers);
-      final int nextLength = registers.int1;
-      if (nextLength < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      } else if (nextLength == 0) {
-        output.add("");
-      } else {
-        if (!Utf8.isValidUtf8(data, position, position + nextLength)) {
-          throw InvalidProtocolBufferException.invalidUtf8();
-        }
-        String value = new String(data, position, nextLength, Internal.UTF_8);
-        output.add(value);
-        position += nextLength;
-      }
-    }
-    return position;
-  }
-
-  /** Decodes a repeated bytes field. Returns the position after all read values. */
-  @SuppressWarnings("unchecked")
-  static int decodeBytesList(
-      int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers)
-      throws InvalidProtocolBufferException {
-    final ProtobufList<ByteString> output = (ProtobufList<ByteString>) list;
-    position = decodeVarint32(data, position, registers);
-    final int length = registers.int1;
-    if (length < 0) {
-      throw InvalidProtocolBufferException.negativeSize();
-    } else if (length > data.length - position) {
-      throw InvalidProtocolBufferException.truncatedMessage();
-    } else if (length == 0) {
-      output.add(ByteString.EMPTY);
-    } else {
-      output.add(ByteString.copyFrom(data, position, length));
-      position += length;
-    }
-    while (position < limit) {
-      int nextPosition = decodeVarint32(data, position, registers);
-      if (tag != registers.int1) {
-        break;
-      }
-      position = decodeVarint32(data, nextPosition, registers);
-      final int nextLength = registers.int1;
-      if (nextLength < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      } else if (nextLength > data.length - position) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      } else if (nextLength == 0) {
-        output.add(ByteString.EMPTY);
-      } else {
-        output.add(ByteString.copyFrom(data, position, nextLength));
-        position += nextLength;
-      }
-    }
-    return position;
-  }
-
-  /**
-   * Decodes a repeated message field
-   *
-   * @return The position of after read all messages
-   */
-  @SuppressWarnings({"unchecked"})
-  static int decodeMessageList(
-      Schema<?> schema,
-      int tag,
-      byte[] data,
-      int position,
-      int limit,
-      ProtobufList<?> list,
-      Registers registers)
-      throws IOException {
-    final ProtobufList<Object> output = (ProtobufList<Object>) list;
-    position = decodeMessageField(schema, data, position, limit, registers);
-    output.add(registers.object1);
-    while (position < limit) {
-      int nextPosition = decodeVarint32(data, position, registers);
-      if (tag != registers.int1) {
-        break;
-      }
-      position = decodeMessageField(schema, data, nextPosition, limit, registers);
-      output.add(registers.object1);
-    }
-    return position;
-  }
-
-  /**
-   * Decodes a repeated group field
-   *
-   * @return The position of after read all groups
-   */
-  @SuppressWarnings({"unchecked", "rawtypes"})
-  static int decodeGroupList(
-      Schema schema,
-      int tag,
-      byte[] data,
-      int position,
-      int limit,
-      ProtobufList<?> list,
-      Registers registers)
-      throws IOException {
-    final ProtobufList<Object> output = (ProtobufList<Object>) list;
-    final int endgroup = (tag & ~0x7) | WireFormat.WIRETYPE_END_GROUP;
-    position = decodeGroupField(schema, data, position, limit, endgroup, registers);
-    output.add(registers.object1);
-    while (position < limit) {
-      int nextPosition = decodeVarint32(data, position, registers);
-      if (tag != registers.int1) {
-        break;
-      }
-      position = decodeGroupField(schema, data, nextPosition, limit, endgroup, registers);
-      output.add(registers.object1);
-    }
-    return position;
-  }
-
-  static int decodeExtensionOrUnknownField(
-      int tag, byte[] data, int position, int limit,
-      Object message,
-      MessageLite defaultInstance,
-      UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite> unknownFieldSchema,
-      Registers registers)
-      throws IOException {
-    final int number = tag >>> 3;
-    GeneratedMessageLite.GeneratedExtension extension =
-        registers.extensionRegistry.findLiteExtensionByNumber(defaultInstance, number);
-    if (extension == null) {
-      return decodeUnknownField(
-          tag, data, position, limit, getMutableUnknownFields(message), registers);
-    } else  {
-      ((GeneratedMessageLite.ExtendableMessage<?, ?>) message).ensureExtensionsAreMutable();
-      return decodeExtension(
-          tag, data, position, limit, (GeneratedMessageLite.ExtendableMessage) message,
-          extension, unknownFieldSchema, registers);
-    }
-  }
-
-  static int decodeExtension(
-      int tag,
-      byte[] data,
-      int position,
-      int limit,
-      GeneratedMessageLite.ExtendableMessage<?, ?> message,
-      GeneratedMessageLite.GeneratedExtension<?, ?> extension,
-      UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite> unknownFieldSchema,
-      Registers registers)
-      throws IOException {
-    final FieldSet<GeneratedMessageLite.ExtensionDescriptor> extensions = message.extensions;
-    final int fieldNumber = tag >>> 3;
-    if (extension.descriptor.isRepeated() && extension.descriptor.isPacked()) {
-      switch (extension.getLiteType()) {
-        case DOUBLE:
-        {
-          DoubleArrayList list = new DoubleArrayList();
-          position = decodePackedDoubleList(data, position, list, registers);
-          extensions.setField(extension.descriptor, list);
-          break;
-        }
-        case FLOAT:
-        {
-          FloatArrayList list = new FloatArrayList();
-          position = decodePackedFloatList(data, position, list, registers);
-          extensions.setField(extension.descriptor, list);
-          break;
-        }
-        case INT64:
-        case UINT64:
-        {
-          LongArrayList list = new LongArrayList();
-          position = decodePackedVarint64List(data, position, list, registers);
-          extensions.setField(extension.descriptor, list);
-          break;
-        }
-        case INT32:
-        case UINT32:
-        {
-          IntArrayList list = new IntArrayList();
-          position = decodePackedVarint32List(data, position, list, registers);
-          extensions.setField(extension.descriptor, list);
-          break;
-        }
-        case FIXED64:
-        case SFIXED64:
-        {
-          LongArrayList list = new LongArrayList();
-          position = decodePackedFixed64List(data, position, list, registers);
-          extensions.setField(extension.descriptor, list);
-          break;
-        }
-        case FIXED32:
-        case SFIXED32:
-        {
-          IntArrayList list = new IntArrayList();
-          position = decodePackedFixed32List(data, position, list, registers);
-          extensions.setField(extension.descriptor, list);
-          break;
-        }
-        case BOOL:
-        {
-          BooleanArrayList list = new BooleanArrayList();
-          position = decodePackedBoolList(data, position, list, registers);
-          extensions.setField(extension.descriptor, list);
-          break;
-        }
-        case SINT32:
-        {
-          IntArrayList list = new IntArrayList();
-          position = decodePackedSInt32List(data, position, list, registers);
-          extensions.setField(extension.descriptor, list);
-          break;
-        }
-        case SINT64:
-        {
-          LongArrayList list = new LongArrayList();
-          position = decodePackedSInt64List(data, position, list, registers);
-          extensions.setField(extension.descriptor, list);
-          break;
-        }
-        case ENUM:
-        {
-          IntArrayList list = new IntArrayList();
-          position = decodePackedVarint32List(data, position, list, registers);
-          UnknownFieldSetLite unknownFields = message.unknownFields;
-          if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
-            unknownFields = null;
-          }
-          unknownFields =
-              SchemaUtil.filterUnknownEnumList(
-                  fieldNumber,
-                  list,
-                  extension.descriptor.getEnumType(),
-                  unknownFields,
-                  unknownFieldSchema);
-          if (unknownFields != null) {
-            message.unknownFields = unknownFields;
-          }
-          extensions.setField(extension.descriptor, list);
-          break;
-        }
-        default:
-          throw new IllegalStateException(
-              "Type cannot be packed: " + extension.descriptor.getLiteType());
-      }
-    } else {
-      Object value = null;
-      // Enum is a special case because unknown enum values will be put into UnknownFieldSetLite.
-      if (extension.getLiteType() == WireFormat.FieldType.ENUM) {
-        position = decodeVarint32(data, position, registers);
-        Object enumValue = extension.descriptor.getEnumType().findValueByNumber(registers.int1);
-        if (enumValue == null) {
-          UnknownFieldSetLite unknownFields = ((GeneratedMessageLite) message).unknownFields;
-          if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
-            unknownFields = UnknownFieldSetLite.newInstance();
-            ((GeneratedMessageLite) message).unknownFields = unknownFields;
-          }
-          SchemaUtil.storeUnknownEnum(
-              fieldNumber, registers.int1, unknownFields, unknownFieldSchema);
-          return position;
-        }
-        // Note, we store the integer value instead of the actual enum object in FieldSet.
-        // This is also different from full-runtime where we store EnumValueDescriptor.
-        value = registers.int1;
-      } else {
-        switch (extension.getLiteType()) {
-          case DOUBLE:
-            value = decodeDouble(data, position);
-            position += 8;
-            break;
-          case FLOAT:
-            value = decodeFloat(data, position);
-            position += 4;
-            break;
-          case INT64:
-          case UINT64:
-            position = decodeVarint64(data, position, registers);
-            value = registers.long1;
-            break;
-          case INT32:
-          case UINT32:
-            position = decodeVarint32(data, position, registers);
-            value = registers.int1;
-            break;
-          case FIXED64:
-          case SFIXED64:
-            value = decodeFixed64(data, position);
-            position += 8;
-            break;
-          case FIXED32:
-          case SFIXED32:
-            value = decodeFixed32(data, position);
-            position += 4;
-            break;
-          case BOOL:
-            position = decodeVarint64(data, position, registers);
-            value = (registers.long1 != 0);
-            break;
-          case BYTES:
-            position = decodeBytes(data, position, registers);
-            value = registers.object1;
-            break;
-          case SINT32:
-            position = decodeVarint32(data, position, registers);
-            value = CodedInputStream.decodeZigZag32(registers.int1);
-            break;
-          case SINT64:
-            position = decodeVarint64(data, position, registers);
-            value = CodedInputStream.decodeZigZag64(registers.long1);
-            break;
-          case STRING:
-            position = decodeString(data, position, registers);
-            value = registers.object1;
-            break;
-          case GROUP:
-            final int endTag = (fieldNumber << 3) | WireFormat.WIRETYPE_END_GROUP;
-            position = decodeGroupField(
-                Protobuf.getInstance().schemaFor(extension.getMessageDefaultInstance().getClass()),
-                data, position, limit, endTag, registers);
-            value = registers.object1;
-            break;
-
-          case MESSAGE:
-            position = decodeMessageField(
-                Protobuf.getInstance().schemaFor(extension.getMessageDefaultInstance().getClass()),
-                data, position, limit, registers);
-            value = registers.object1;
-            break;
-
-          case ENUM:
-            throw new IllegalStateException("Shouldn't reach here.");
-        }
-      }
-      if (extension.isRepeated()) {
-        extensions.addRepeatedField(extension.descriptor, value);
-      } else {
-        switch (extension.getLiteType()) {
-          case MESSAGE:
-          case GROUP:
-            Object oldValue = extensions.getField(extension.descriptor);
-            if (oldValue != null) {
-              value = Internal.mergeMessage(oldValue, value);
-            }
-            break;
-          default:
-            break;
-        }
-        extensions.setField(extension.descriptor, value);
-      }
-    }
-    return position;
-  }
-
-  /** Decodes an unknown field. */
-  static int decodeUnknownField(
-      int tag,
-      byte[] data,
-      int position,
-      int limit,
-      UnknownFieldSetLite unknownFields,
-      Registers registers)
-      throws InvalidProtocolBufferException {
-    if (WireFormat.getTagFieldNumber(tag) == 0) {
-      throw InvalidProtocolBufferException.invalidTag();
-    }
-    switch (WireFormat.getTagWireType(tag)) {
-      case WireFormat.WIRETYPE_VARINT:
-        position = decodeVarint64(data, position, registers);
-        unknownFields.storeField(tag, registers.long1);
-        return position;
-      case WireFormat.WIRETYPE_FIXED32:
-        unknownFields.storeField(tag, decodeFixed32(data, position));
-        return position + 4;
-      case WireFormat.WIRETYPE_FIXED64:
-        unknownFields.storeField(tag, decodeFixed64(data, position));
-        return position + 8;
-      case WireFormat.WIRETYPE_LENGTH_DELIMITED:
-        position = decodeVarint32(data, position, registers);
-        final int length = registers.int1;
-        if (length < 0) {
-          throw InvalidProtocolBufferException.negativeSize();
-        } else if (length > data.length - position) {
-          throw InvalidProtocolBufferException.truncatedMessage();
-        } else if (length == 0) {
-          unknownFields.storeField(tag, ByteString.EMPTY);
-        } else {
-          unknownFields.storeField(tag, ByteString.copyFrom(data, position, length));
-        }
-        return position + length;
-      case WireFormat.WIRETYPE_START_GROUP:
-        final UnknownFieldSetLite child = UnknownFieldSetLite.newInstance();
-        final int endGroup = (tag & ~0x7) | WireFormat.WIRETYPE_END_GROUP;
-        int lastTag = 0;
-        while (position < limit) {
-          position = decodeVarint32(data, position, registers);
-          lastTag = registers.int1;
-          if (lastTag == endGroup) {
-            break;
-          }
-          position = decodeUnknownField(lastTag, data, position, limit, child, registers);
-        }
-        if (position > limit || lastTag != endGroup) {
-          throw InvalidProtocolBufferException.parseFailure();
-        }
-        unknownFields.storeField(tag, child);
-        return position;
-      default:
-        throw InvalidProtocolBufferException.invalidTag();
-    }
-  }
-
-  /** Skips an unknown field. */
-  static int skipField(int tag, byte[] data, int position, int limit, Registers registers)
-      throws InvalidProtocolBufferException {
-    if (WireFormat.getTagFieldNumber(tag) == 0) {
-      throw InvalidProtocolBufferException.invalidTag();
-    }
-    switch (WireFormat.getTagWireType(tag)) {
-      case WireFormat.WIRETYPE_VARINT:
-        position = decodeVarint64(data, position, registers);
-        return position;
-      case WireFormat.WIRETYPE_FIXED32:
-        return position + 4;
-      case WireFormat.WIRETYPE_FIXED64:
-        return position + 8;
-      case WireFormat.WIRETYPE_LENGTH_DELIMITED:
-        position = decodeVarint32(data, position, registers);
-        return position + registers.int1;
-      case WireFormat.WIRETYPE_START_GROUP:
-        final int endGroup = (tag & ~0x7) | WireFormat.WIRETYPE_END_GROUP;
-        int lastTag = 0;
-        while (position < limit) {
-          position = decodeVarint32(data, position, registers);
-          lastTag = registers.int1;
-          if (lastTag == endGroup) {
-            break;
-          }
-          position = skipField(lastTag, data, position, limit, registers);
-        }
-        if (position > limit || lastTag != endGroup) {
-          throw InvalidProtocolBufferException.parseFailure();
-        }
-        return position;
-      default:
-        throw InvalidProtocolBufferException.invalidTag();
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/BinaryReader.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/BinaryReader.java
deleted file mode 100644
index d64574c..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/BinaryReader.java
+++ /dev/null
@@ -1,1729 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.WireFormat.FIXED32_SIZE;
-import static com.google.protobuf.WireFormat.FIXED64_SIZE;
-import static com.google.protobuf.WireFormat.WIRETYPE_END_GROUP;
-import static com.google.protobuf.WireFormat.WIRETYPE_FIXED32;
-import static com.google.protobuf.WireFormat.WIRETYPE_FIXED64;
-import static com.google.protobuf.WireFormat.WIRETYPE_LENGTH_DELIMITED;
-import static com.google.protobuf.WireFormat.WIRETYPE_START_GROUP;
-import static com.google.protobuf.WireFormat.WIRETYPE_VARINT;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A {@link Reader} that reads from a buffer containing a message serialized with the binary
- * protocol.
- */
-@ExperimentalApi
-abstract class BinaryReader implements Reader {
-  private static final int FIXED32_MULTIPLE_MASK = FIXED32_SIZE - 1;
-  private static final int FIXED64_MULTIPLE_MASK = FIXED64_SIZE - 1;
-
-  /**
-   * Creates a new reader using the given {@code buffer} as input.
-   *
-   * @param buffer the input buffer. The buffer (including position, limit, etc.) will not be
-   *     modified. To increment the buffer position after the read completes, use the value returned
-   *     by {@link #getTotalBytesRead()}.
-   * @param bufferIsImmutable if {@code true} the reader assumes that the content of {@code buffer}
-   *     will never change and any allocated {@link ByteString} instances will by directly wrap
-   *     slices of {@code buffer}.
-   * @return the reader
-   */
-  public static BinaryReader newInstance(ByteBuffer buffer, boolean bufferIsImmutable) {
-    if (buffer.hasArray()) {
-      // TODO(nathanmittler): Add support for unsafe operations.
-      return new SafeHeapReader(buffer, bufferIsImmutable);
-    }
-    // TODO(nathanmittler): Add support for direct buffers
-    throw new IllegalArgumentException("Direct buffers not yet supported");
-  }
-
-  /** Only allow subclassing for inner classes. */
-  private BinaryReader() {}
-
-  /** Returns the total number of bytes read so far from the input buffer. */
-  public abstract int getTotalBytesRead();
-
-  @Override
-  public boolean shouldDiscardUnknownFields() {
-    return false;
-  }
-
-  /**
-   * A {@link BinaryReader} implementation that operates on a heap {@link ByteBuffer}. Uses only
-   * safe operations on the underlying array.
-   */
-  private static final class SafeHeapReader extends BinaryReader {
-    private final boolean bufferIsImmutable;
-    private final byte[] buffer;
-    private int pos;
-    private final int initialPos;
-    private int limit;
-    private int tag;
-    private int endGroupTag;
-
-    public SafeHeapReader(ByteBuffer bytebuf, boolean bufferIsImmutable) {
-      this.bufferIsImmutable = bufferIsImmutable;
-      buffer = bytebuf.array();
-      initialPos = pos = bytebuf.arrayOffset() + bytebuf.position();
-      limit = bytebuf.arrayOffset() + bytebuf.limit();
-    }
-
-    private boolean isAtEnd() {
-      return pos == limit;
-    }
-
-    @Override
-    public int getTotalBytesRead() {
-      return pos - initialPos;
-    }
-
-    @Override
-    public int getFieldNumber() throws IOException {
-      if (isAtEnd()) {
-        return Reader.READ_DONE;
-      }
-      tag = readVarint32();
-      if (tag == endGroupTag) {
-        return Reader.READ_DONE;
-      }
-      return WireFormat.getTagFieldNumber(tag);
-    }
-
-    @Override
-    public int getTag() {
-      return tag;
-    }
-
-    @Override
-    public boolean skipField() throws IOException {
-      if (isAtEnd() || tag == endGroupTag) {
-        return false;
-      }
-
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_VARINT:
-          skipVarint();
-          return true;
-        case WIRETYPE_FIXED64:
-          skipBytes(FIXED64_SIZE);
-          return true;
-        case WIRETYPE_LENGTH_DELIMITED:
-          skipBytes(readVarint32());
-          return true;
-        case WIRETYPE_FIXED32:
-          skipBytes(FIXED32_SIZE);
-          return true;
-        case WIRETYPE_START_GROUP:
-          skipGroup();
-          return true;
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-
-    @Override
-    public double readDouble() throws IOException {
-      requireWireType(WIRETYPE_FIXED64);
-      return Double.longBitsToDouble(readLittleEndian64());
-    }
-
-    @Override
-    public float readFloat() throws IOException {
-      requireWireType(WIRETYPE_FIXED32);
-      return Float.intBitsToFloat(readLittleEndian32());
-    }
-
-    @Override
-    public long readUInt64() throws IOException {
-      requireWireType(WIRETYPE_VARINT);
-      return readVarint64();
-    }
-
-    @Override
-    public long readInt64() throws IOException {
-      requireWireType(WIRETYPE_VARINT);
-      return readVarint64();
-    }
-
-    @Override
-    public int readInt32() throws IOException {
-      requireWireType(WIRETYPE_VARINT);
-      return readVarint32();
-    }
-
-    @Override
-    public long readFixed64() throws IOException {
-      requireWireType(WIRETYPE_FIXED64);
-      return readLittleEndian64();
-    }
-
-    @Override
-    public int readFixed32() throws IOException {
-      requireWireType(WIRETYPE_FIXED32);
-      return readLittleEndian32();
-    }
-
-    @Override
-    public boolean readBool() throws IOException {
-      requireWireType(WIRETYPE_VARINT);
-      return readVarint32() != 0;
-    }
-
-    @Override
-    public String readString() throws IOException {
-      return readStringInternal(false);
-    }
-
-    @Override
-    public String readStringRequireUtf8() throws IOException {
-      return readStringInternal(true);
-    }
-
-    public String readStringInternal(boolean requireUtf8) throws IOException {
-      requireWireType(WIRETYPE_LENGTH_DELIMITED);
-      final int size = readVarint32();
-      if (size == 0) {
-        return "";
-      }
-
-      requireBytes(size);
-      if (requireUtf8 && !Utf8.isValidUtf8(buffer, pos, pos + size)) {
-        throw InvalidProtocolBufferException.invalidUtf8();
-      }
-      String result = new String(buffer, pos, size, Internal.UTF_8);
-      pos += size;
-      return result;
-    }
-
-    @Override
-    public <T> T readMessage(Class<T> clazz, ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      requireWireType(WIRETYPE_LENGTH_DELIMITED);
-      return readMessage(Protobuf.getInstance().schemaFor(clazz), extensionRegistry);
-    }
-
-    @Override
-    public <T> T readMessageBySchemaWithCheck(
-        Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException {
-      requireWireType(WIRETYPE_LENGTH_DELIMITED);
-      return readMessage(schema, extensionRegistry);
-    }
-
-    private <T> T readMessage(Schema<T> schema, ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      int size = readVarint32();
-      requireBytes(size);
-
-      // Update the limit.
-      int prevLimit = limit;
-      int newLimit = pos + size;
-      limit = newLimit;
-
-      try {
-        // Allocate and read the message.
-        T message = schema.newInstance();
-        schema.mergeFrom(message, this, extensionRegistry);
-        schema.makeImmutable(message);
-
-        if (pos != newLimit) {
-          throw InvalidProtocolBufferException.parseFailure();
-        }
-        return message;
-      } finally {
-        // Restore the limit.
-        limit = prevLimit;
-      }
-    }
-
-    @Override
-    public <T> T readGroup(Class<T> clazz, ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      requireWireType(WIRETYPE_START_GROUP);
-      return readGroup(Protobuf.getInstance().schemaFor(clazz), extensionRegistry);
-    }
-
-    @Override
-    public <T> T readGroupBySchemaWithCheck(
-        Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException {
-      requireWireType(WIRETYPE_START_GROUP);
-      return readGroup(schema, extensionRegistry);
-    }
-
-    private <T> T readGroup(Schema<T> schema, ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      int prevEndGroupTag = endGroupTag;
-      endGroupTag = WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WIRETYPE_END_GROUP);
-
-      try {
-        // Allocate and read the message.
-        T message = schema.newInstance();
-        schema.mergeFrom(message, this, extensionRegistry);
-        schema.makeImmutable(message);
-
-        if (tag != endGroupTag) {
-          throw InvalidProtocolBufferException.parseFailure();
-        }
-        return message;
-      } finally {
-        // Restore the old end group tag.
-        endGroupTag = prevEndGroupTag;
-      }
-    }
-
-    @Override
-    public ByteString readBytes() throws IOException {
-      requireWireType(WIRETYPE_LENGTH_DELIMITED);
-      int size = readVarint32();
-      if (size == 0) {
-        return ByteString.EMPTY;
-      }
-
-      requireBytes(size);
-      ByteString bytes =
-          bufferIsImmutable
-              ? ByteString.wrap(buffer, pos, size)
-              : ByteString.copyFrom(buffer, pos, size);
-      pos += size;
-      return bytes;
-    }
-
-    @Override
-    public int readUInt32() throws IOException {
-      requireWireType(WIRETYPE_VARINT);
-      return readVarint32();
-    }
-
-    @Override
-    public int readEnum() throws IOException {
-      requireWireType(WIRETYPE_VARINT);
-      return readVarint32();
-    }
-
-    @Override
-    public int readSFixed32() throws IOException {
-      requireWireType(WIRETYPE_FIXED32);
-      return readLittleEndian32();
-    }
-
-    @Override
-    public long readSFixed64() throws IOException {
-      requireWireType(WIRETYPE_FIXED64);
-      return readLittleEndian64();
-    }
-
-    @Override
-    public int readSInt32() throws IOException {
-      requireWireType(WIRETYPE_VARINT);
-      return CodedInputStream.decodeZigZag32(readVarint32());
-    }
-
-    @Override
-    public long readSInt64() throws IOException {
-      requireWireType(WIRETYPE_VARINT);
-      return CodedInputStream.decodeZigZag64(readVarint64());
-    }
-
-    @Override
-    public void readDoubleList(List<Double> target) throws IOException {
-      if (target instanceof DoubleArrayList) {
-        DoubleArrayList plist = (DoubleArrayList) target;
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            verifyPackedFixed64Length(bytes);
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              plist.addDouble(Double.longBitsToDouble(readLittleEndian64_NoCheck()));
-            }
-            break;
-          case WIRETYPE_FIXED64:
-            while (true) {
-              plist.addDouble(readDouble());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      } else {
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            verifyPackedFixed64Length(bytes);
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              target.add(Double.longBitsToDouble(readLittleEndian64_NoCheck()));
-            }
-            break;
-          case WIRETYPE_FIXED64:
-            while (true) {
-              target.add(readDouble());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      }
-    }
-
-    @Override
-    public void readFloatList(List<Float> target) throws IOException {
-      if (target instanceof FloatArrayList) {
-        FloatArrayList plist = (FloatArrayList) target;
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            verifyPackedFixed32Length(bytes);
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              plist.addFloat(Float.intBitsToFloat(readLittleEndian32_NoCheck()));
-            }
-            break;
-          case WIRETYPE_FIXED32:
-            while (true) {
-              plist.addFloat(readFloat());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      } else {
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            verifyPackedFixed32Length(bytes);
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              target.add(Float.intBitsToFloat(readLittleEndian32_NoCheck()));
-            }
-            break;
-          case WIRETYPE_FIXED32:
-            while (true) {
-              target.add(readFloat());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      }
-    }
-
-    @Override
-    public void readUInt64List(List<Long> target) throws IOException {
-      if (target instanceof LongArrayList) {
-        LongArrayList plist = (LongArrayList) target;
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              plist.addLong(readVarint64());
-            }
-            requirePosition(fieldEndPos);
-            break;
-          case WIRETYPE_VARINT:
-            while (true) {
-              plist.addLong(readUInt64());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      } else {
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              target.add(readVarint64());
-            }
-            requirePosition(fieldEndPos);
-            break;
-          case WIRETYPE_VARINT:
-            while (true) {
-              target.add(readUInt64());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      }
-    }
-
-    @Override
-    public void readInt64List(List<Long> target) throws IOException {
-      if (target instanceof LongArrayList) {
-        LongArrayList plist = (LongArrayList) target;
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              plist.addLong(readVarint64());
-            }
-            requirePosition(fieldEndPos);
-            break;
-          case WIRETYPE_VARINT:
-            while (true) {
-              plist.addLong(readInt64());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      } else {
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              target.add(readVarint64());
-            }
-            requirePosition(fieldEndPos);
-            break;
-          case WIRETYPE_VARINT:
-            while (true) {
-              target.add(readInt64());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      }
-    }
-
-    @Override
-    public void readInt32List(List<Integer> target) throws IOException {
-      if (target instanceof IntArrayList) {
-        IntArrayList plist = (IntArrayList) target;
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              plist.addInt(readVarint32());
-            }
-            requirePosition(fieldEndPos);
-            break;
-          case WIRETYPE_VARINT:
-            while (true) {
-              plist.addInt(readInt32());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      } else {
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              target.add(readVarint32());
-            }
-            requirePosition(fieldEndPos);
-            break;
-          case WIRETYPE_VARINT:
-            while (true) {
-              target.add(readInt32());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      }
-    }
-
-    @Override
-    public void readFixed64List(List<Long> target) throws IOException {
-      if (target instanceof LongArrayList) {
-        LongArrayList plist = (LongArrayList) target;
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            verifyPackedFixed64Length(bytes);
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              plist.addLong(readLittleEndian64_NoCheck());
-            }
-            break;
-          case WIRETYPE_FIXED64:
-            while (true) {
-              plist.addLong(readFixed64());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      } else {
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            verifyPackedFixed64Length(bytes);
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              target.add(readLittleEndian64_NoCheck());
-            }
-            break;
-          case WIRETYPE_FIXED64:
-            while (true) {
-              target.add(readFixed64());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      }
-    }
-
-    @Override
-    public void readFixed32List(List<Integer> target) throws IOException {
-      if (target instanceof IntArrayList) {
-        IntArrayList plist = (IntArrayList) target;
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            verifyPackedFixed32Length(bytes);
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              plist.addInt(readLittleEndian32_NoCheck());
-            }
-            break;
-          case WIRETYPE_FIXED32:
-            while (true) {
-              plist.addInt(readFixed32());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      } else {
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            verifyPackedFixed32Length(bytes);
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              target.add(readLittleEndian32_NoCheck());
-            }
-            break;
-          case WIRETYPE_FIXED32:
-            while (true) {
-              target.add(readFixed32());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      }
-    }
-
-    @Override
-    public void readBoolList(List<Boolean> target) throws IOException {
-      if (target instanceof BooleanArrayList) {
-        BooleanArrayList plist = (BooleanArrayList) target;
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              plist.addBoolean(readVarint32() != 0);
-            }
-            requirePosition(fieldEndPos);
-            break;
-          case WIRETYPE_VARINT:
-            while (true) {
-              plist.addBoolean(readBool());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      } else {
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              target.add(readVarint32() != 0);
-            }
-            requirePosition(fieldEndPos);
-            break;
-          case WIRETYPE_VARINT:
-            while (true) {
-              target.add(readBool());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      }
-    }
-
-    @Override
-    public void readStringList(List<String> target) throws IOException {
-      readStringListInternal(target, false);
-    }
-
-    @Override
-    public void readStringListRequireUtf8(List<String> target) throws IOException {
-      readStringListInternal(target, true);
-    }
-
-    public void readStringListInternal(List<String> target, boolean requireUtf8)
-        throws IOException {
-      if (WireFormat.getTagWireType(tag) != WIRETYPE_LENGTH_DELIMITED) {
-        throw InvalidProtocolBufferException.invalidWireType();
-      }
-
-      if (target instanceof LazyStringList && !requireUtf8) {
-        LazyStringList lazyList = (LazyStringList) target;
-        while (true) {
-          lazyList.add(readBytes());
-
-          if (isAtEnd()) {
-            return;
-          }
-          int prevPos = pos;
-          int nextTag = readVarint32();
-          if (nextTag != tag) {
-            // We've reached the end of the repeated field. Rewind the buffer position to before
-            // the new tag.
-            pos = prevPos;
-            return;
-          }
-        }
-      } else {
-        while (true) {
-          target.add(readStringInternal(requireUtf8));
-
-          if (isAtEnd()) {
-            return;
-          }
-          int prevPos = pos;
-          int nextTag = readVarint32();
-          if (nextTag != tag) {
-            // We've reached the end of the repeated field. Rewind the buffer position to before
-            // the new tag.
-            pos = prevPos;
-            return;
-          }
-        }
-      }
-    }
-
-    @Override
-    public <T> void readMessageList(
-        List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      final Schema<T> schema = Protobuf.getInstance().schemaFor(targetType);
-      readMessageList(target, schema, extensionRegistry);
-    }
-
-    @Override
-    public <T> void readMessageList(
-        List<T> target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      if (WireFormat.getTagWireType(tag) != WIRETYPE_LENGTH_DELIMITED) {
-        throw InvalidProtocolBufferException.invalidWireType();
-      }
-      final int listTag = tag;
-      while (true) {
-        target.add(readMessage(schema, extensionRegistry));
-
-        if (isAtEnd()) {
-          return;
-        }
-        int prevPos = pos;
-        int nextTag = readVarint32();
-        if (nextTag != listTag) {
-          // We've reached the end of the repeated field. Rewind the buffer position to before
-          // the new tag.
-          pos = prevPos;
-          return;
-        }
-      }
-    }
-
-    @Override
-    public <T> void readGroupList(
-        List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      final Schema<T> schema = Protobuf.getInstance().schemaFor(targetType);
-      readGroupList(target, schema, extensionRegistry);
-    }
-
-    @Override
-    public <T> void readGroupList(
-        List<T> target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      if (WireFormat.getTagWireType(tag) != WIRETYPE_START_GROUP) {
-        throw InvalidProtocolBufferException.invalidWireType();
-      }
-      final int listTag = tag;
-      while (true) {
-        target.add(readGroup(schema, extensionRegistry));
-
-        if (isAtEnd()) {
-          return;
-        }
-        int prevPos = pos;
-        int nextTag = readVarint32();
-        if (nextTag != listTag) {
-          // We've reached the end of the repeated field. Rewind the buffer position to before
-          // the new tag.
-          pos = prevPos;
-          return;
-        }
-      }
-    }
-
-    @Override
-    public void readBytesList(List<ByteString> target) throws IOException {
-      if (WireFormat.getTagWireType(tag) != WIRETYPE_LENGTH_DELIMITED) {
-        throw InvalidProtocolBufferException.invalidWireType();
-      }
-
-      while (true) {
-        target.add(readBytes());
-
-        if (isAtEnd()) {
-          return;
-        }
-        int prevPos = pos;
-        int nextTag = readVarint32();
-        if (nextTag != tag) {
-          // We've reached the end of the repeated field. Rewind the buffer position to before
-          // the new tag.
-          pos = prevPos;
-          return;
-        }
-      }
-    }
-
-    @Override
-    public void readUInt32List(List<Integer> target) throws IOException {
-      if (target instanceof IntArrayList) {
-        IntArrayList plist = (IntArrayList) target;
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              plist.addInt(readVarint32());
-            }
-            break;
-          case WIRETYPE_VARINT:
-            while (true) {
-              plist.addInt(readUInt32());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      } else {
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              target.add(readVarint32());
-            }
-            break;
-          case WIRETYPE_VARINT:
-            while (true) {
-              target.add(readUInt32());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      }
-    }
-
-    @Override
-    public void readEnumList(List<Integer> target) throws IOException {
-      if (target instanceof IntArrayList) {
-        IntArrayList plist = (IntArrayList) target;
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              plist.addInt(readVarint32());
-            }
-            break;
-          case WIRETYPE_VARINT:
-            while (true) {
-              plist.addInt(readEnum());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      } else {
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              target.add(readVarint32());
-            }
-            break;
-          case WIRETYPE_VARINT:
-            while (true) {
-              target.add(readEnum());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      }
-    }
-
-    @Override
-    public void readSFixed32List(List<Integer> target) throws IOException {
-      if (target instanceof IntArrayList) {
-        IntArrayList plist = (IntArrayList) target;
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            verifyPackedFixed32Length(bytes);
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              plist.addInt(readLittleEndian32_NoCheck());
-            }
-            break;
-          case WIRETYPE_FIXED32:
-            while (true) {
-              plist.addInt(readSFixed32());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      } else {
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            verifyPackedFixed32Length(bytes);
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              target.add(readLittleEndian32_NoCheck());
-            }
-            break;
-          case WIRETYPE_FIXED32:
-            while (true) {
-              target.add(readSFixed32());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      }
-    }
-
-    @Override
-    public void readSFixed64List(List<Long> target) throws IOException {
-      if (target instanceof LongArrayList) {
-        LongArrayList plist = (LongArrayList) target;
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            verifyPackedFixed64Length(bytes);
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              plist.addLong(readLittleEndian64_NoCheck());
-            }
-            break;
-          case WIRETYPE_FIXED64:
-            while (true) {
-              plist.addLong(readSFixed64());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      } else {
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            verifyPackedFixed64Length(bytes);
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              target.add(readLittleEndian64_NoCheck());
-            }
-            break;
-          case WIRETYPE_FIXED64:
-            while (true) {
-              target.add(readSFixed64());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      }
-    }
-
-    @Override
-    public void readSInt32List(List<Integer> target) throws IOException {
-      if (target instanceof IntArrayList) {
-        IntArrayList plist = (IntArrayList) target;
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              plist.addInt(CodedInputStream.decodeZigZag32(readVarint32()));
-            }
-            break;
-          case WIRETYPE_VARINT:
-            while (true) {
-              plist.addInt(readSInt32());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      } else {
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              target.add(CodedInputStream.decodeZigZag32(readVarint32()));
-            }
-            break;
-          case WIRETYPE_VARINT:
-            while (true) {
-              target.add(readSInt32());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      }
-    }
-
-    @Override
-    public void readSInt64List(List<Long> target) throws IOException {
-      if (target instanceof LongArrayList) {
-        LongArrayList plist = (LongArrayList) target;
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              plist.addLong(CodedInputStream.decodeZigZag64(readVarint64()));
-            }
-            break;
-          case WIRETYPE_VARINT:
-            while (true) {
-              plist.addLong(readSInt64());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      } else {
-        switch (WireFormat.getTagWireType(tag)) {
-          case WIRETYPE_LENGTH_DELIMITED:
-            final int bytes = readVarint32();
-            final int fieldEndPos = pos + bytes;
-            while (pos < fieldEndPos) {
-              target.add(CodedInputStream.decodeZigZag64(readVarint64()));
-            }
-            break;
-          case WIRETYPE_VARINT:
-            while (true) {
-              target.add(readSInt64());
-
-              if (isAtEnd()) {
-                return;
-              }
-              int prevPos = pos;
-              int nextTag = readVarint32();
-              if (nextTag != tag) {
-                // We've reached the end of the repeated field. Rewind the buffer position to before
-                // the new tag.
-                pos = prevPos;
-                return;
-              }
-            }
-          default:
-            throw InvalidProtocolBufferException.invalidWireType();
-        }
-      }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public <K, V> void readMap(
-        Map<K, V> target,
-        MapEntryLite.Metadata<K, V> metadata,
-        ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      requireWireType(WIRETYPE_LENGTH_DELIMITED);
-      int size = readVarint32();
-      requireBytes(size);
-
-      // Update the limit.
-      int prevLimit = limit;
-      int newLimit = pos + size;
-      limit = newLimit;
-
-      try {
-        K key = metadata.defaultKey;
-        V value = metadata.defaultValue;
-        while (true) {
-          int number = getFieldNumber();
-          if (number == READ_DONE) {
-            break;
-          }
-          try {
-            switch (number) {
-              case 1:
-                key = (K) readField(metadata.keyType, null, null);
-                break;
-              case 2:
-                value =
-                    (V)
-                        readField(
-                            metadata.valueType,
-                            metadata.defaultValue.getClass(),
-                            extensionRegistry);
-                break;
-              default:
-                if (!skipField()) {
-                  throw new InvalidProtocolBufferException("Unable to parse map entry.");
-                }
-                break;
-            }
-          } catch (InvalidProtocolBufferException.InvalidWireTypeException ignore) {
-            // the type doesn't match, skip the field.
-            if (!skipField()) {
-              throw new InvalidProtocolBufferException("Unable to parse map entry.");
-            }
-          }
-        }
-        target.put(key, value);
-      } finally {
-        // Restore the limit.
-        limit = prevLimit;
-      }
-    }
-
-    private Object readField(
-        WireFormat.FieldType fieldType,
-        Class<?> messageType,
-        ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      switch (fieldType) {
-        case BOOL:
-          return readBool();
-        case BYTES:
-          return readBytes();
-        case DOUBLE:
-          return readDouble();
-        case ENUM:
-          return readEnum();
-        case FIXED32:
-          return readFixed32();
-        case FIXED64:
-          return readFixed64();
-        case FLOAT:
-          return readFloat();
-        case INT32:
-          return readInt32();
-        case INT64:
-          return readInt64();
-        case MESSAGE:
-          return readMessage(messageType, extensionRegistry);
-        case SFIXED32:
-          return readSFixed32();
-        case SFIXED64:
-          return readSFixed64();
-        case SINT32:
-          return readSInt32();
-        case SINT64:
-          return readSInt64();
-        case STRING:
-          return readStringRequireUtf8();
-        case UINT32:
-          return readUInt32();
-        case UINT64:
-          return readUInt64();
-        default:
-          throw new RuntimeException("unsupported field type.");
-      }
-    }
-
-    /** Read a raw Varint from the stream. If larger than 32 bits, discard the upper bits. */
-    private int readVarint32() throws IOException {
-      // See implementation notes for readRawVarint64
-      int i = pos;
-
-      if (limit == pos) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-
-      int x;
-      if ((x = buffer[i++]) >= 0) {
-        pos = i;
-        return x;
-      } else if (limit - i < 9) {
-        return (int) readVarint64SlowPath();
-      } else if ((x ^= (buffer[i++] << 7)) < 0) {
-        x ^= (~0 << 7);
-      } else if ((x ^= (buffer[i++] << 14)) >= 0) {
-        x ^= (~0 << 7) ^ (~0 << 14);
-      } else if ((x ^= (buffer[i++] << 21)) < 0) {
-        x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
-      } else {
-        int y = buffer[i++];
-        x ^= y << 28;
-        x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
-        if (y < 0
-            && buffer[i++] < 0
-            && buffer[i++] < 0
-            && buffer[i++] < 0
-            && buffer[i++] < 0
-            && buffer[i++] < 0) {
-          throw InvalidProtocolBufferException.malformedVarint();
-        }
-      }
-      pos = i;
-      return x;
-    }
-
-    public long readVarint64() throws IOException {
-      // Implementation notes:
-      //
-      // Optimized for one-byte values, expected to be common.
-      // The particular code below was selected from various candidates
-      // empirically, by winning VarintBenchmark.
-      //
-      // Sign extension of (signed) Java bytes is usually a nuisance, but
-      // we exploit it here to more easily obtain the sign of bytes read.
-      // Instead of cleaning up the sign extension bits by masking eagerly,
-      // we delay until we find the final (positive) byte, when we clear all
-      // accumulated bits with one xor.  We depend on javac to constant fold.
-      int i = pos;
-
-      if (limit == i) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-
-      final byte[] buffer = this.buffer;
-      long x;
-      int y;
-      if ((y = buffer[i++]) >= 0) {
-        pos = i;
-        return y;
-      } else if (limit - i < 9) {
-        return readVarint64SlowPath();
-      } else if ((y ^= (buffer[i++] << 7)) < 0) {
-        x = y ^ (~0 << 7);
-      } else if ((y ^= (buffer[i++] << 14)) >= 0) {
-        x = y ^ ((~0 << 7) ^ (~0 << 14));
-      } else if ((y ^= (buffer[i++] << 21)) < 0) {
-        x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
-      } else if ((x = y ^ ((long) buffer[i++] << 28)) >= 0L) {
-        x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
-      } else if ((x ^= ((long) buffer[i++] << 35)) < 0L) {
-        x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
-      } else if ((x ^= ((long) buffer[i++] << 42)) >= 0L) {
-        x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
-      } else if ((x ^= ((long) buffer[i++] << 49)) < 0L) {
-        x ^=
-            (~0L << 7)
-                ^ (~0L << 14)
-                ^ (~0L << 21)
-                ^ (~0L << 28)
-                ^ (~0L << 35)
-                ^ (~0L << 42)
-                ^ (~0L << 49);
-      } else {
-        x ^= ((long) buffer[i++] << 56);
-        x ^=
-            (~0L << 7)
-                ^ (~0L << 14)
-                ^ (~0L << 21)
-                ^ (~0L << 28)
-                ^ (~0L << 35)
-                ^ (~0L << 42)
-                ^ (~0L << 49)
-                ^ (~0L << 56);
-        if (x < 0L) {
-          if (buffer[i++] < 0L) {
-            throw InvalidProtocolBufferException.malformedVarint();
-          }
-        }
-      }
-      pos = i;
-      return x;
-    }
-
-    private long readVarint64SlowPath() throws IOException {
-      long result = 0;
-      for (int shift = 0; shift < 64; shift += 7) {
-        final byte b = readByte();
-        result |= (long) (b & 0x7F) << shift;
-        if ((b & 0x80) == 0) {
-          return result;
-        }
-      }
-      throw InvalidProtocolBufferException.malformedVarint();
-    }
-
-    private byte readByte() throws IOException {
-      if (pos == limit) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-      return buffer[pos++];
-    }
-
-    private int readLittleEndian32() throws IOException {
-      requireBytes(FIXED32_SIZE);
-      return readLittleEndian32_NoCheck();
-    }
-
-    private long readLittleEndian64() throws IOException {
-      requireBytes(FIXED64_SIZE);
-      return readLittleEndian64_NoCheck();
-    }
-
-    private int readLittleEndian32_NoCheck() {
-      int p = pos;
-      final byte[] buffer = this.buffer;
-      pos = p + FIXED32_SIZE;
-      return (((buffer[p] & 0xff))
-          | ((buffer[p + 1] & 0xff) << 8)
-          | ((buffer[p + 2] & 0xff) << 16)
-          | ((buffer[p + 3] & 0xff) << 24));
-    }
-
-    private long readLittleEndian64_NoCheck() {
-      int p = pos;
-      final byte[] buffer = this.buffer;
-      pos = p + FIXED64_SIZE;
-      return (((buffer[p] & 0xffL))
-          | ((buffer[p + 1] & 0xffL) << 8)
-          | ((buffer[p + 2] & 0xffL) << 16)
-          | ((buffer[p + 3] & 0xffL) << 24)
-          | ((buffer[p + 4] & 0xffL) << 32)
-          | ((buffer[p + 5] & 0xffL) << 40)
-          | ((buffer[p + 6] & 0xffL) << 48)
-          | ((buffer[p + 7] & 0xffL) << 56));
-    }
-
-    private void skipVarint() throws IOException {
-      if (limit - pos >= 10) {
-        final byte[] buffer = this.buffer;
-        int p = pos;
-        for (int i = 0; i < 10; i++) {
-          if (buffer[p++] >= 0) {
-            pos = p;
-            return;
-          }
-        }
-      }
-      skipVarintSlowPath();
-    }
-
-    private void skipVarintSlowPath() throws IOException {
-      for (int i = 0; i < 10; i++) {
-        if (readByte() >= 0) {
-          return;
-        }
-      }
-      throw InvalidProtocolBufferException.malformedVarint();
-    }
-
-    private void skipBytes(final int size) throws IOException {
-      requireBytes(size);
-
-      pos += size;
-    }
-
-    private void skipGroup() throws IOException {
-      int prevEndGroupTag = endGroupTag;
-      endGroupTag = WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WIRETYPE_END_GROUP);
-      while (true) {
-        if (getFieldNumber() == READ_DONE || !skipField()) {
-          break;
-        }
-      }
-      if (tag != endGroupTag) {
-        throw InvalidProtocolBufferException.parseFailure();
-      }
-      endGroupTag = prevEndGroupTag;
-    }
-
-    private void requireBytes(int size) throws IOException {
-      if (size < 0 || size > (limit - pos)) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-    }
-
-    private void requireWireType(int requiredWireType) throws IOException {
-      if (WireFormat.getTagWireType(tag) != requiredWireType) {
-        throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-
-    private void verifyPackedFixed64Length(int bytes) throws IOException {
-      requireBytes(bytes);
-      if ((bytes & FIXED64_MULTIPLE_MASK) != 0) {
-        // Require that the number of bytes be a multiple of 8.
-        throw InvalidProtocolBufferException.parseFailure();
-      }
-    }
-
-    private void verifyPackedFixed32Length(int bytes) throws IOException {
-      requireBytes(bytes);
-      if ((bytes & FIXED32_MULTIPLE_MASK) != 0) {
-        // Require that the number of bytes be a multiple of 4.
-        throw InvalidProtocolBufferException.parseFailure();
-      }
-    }
-
-    private void requirePosition(int expectedPosition) throws IOException {
-      if (pos != expectedPosition) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/BinaryWriter.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/BinaryWriter.java
deleted file mode 100644
index 94259ec..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/BinaryWriter.java
+++ /dev/null
@@ -1,3071 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.Internal.checkNotNull;
-import static com.google.protobuf.WireFormat.FIXED32_SIZE;
-import static com.google.protobuf.WireFormat.FIXED64_SIZE;
-import static com.google.protobuf.WireFormat.MAX_VARINT32_SIZE;
-import static com.google.protobuf.WireFormat.MAX_VARINT64_SIZE;
-import static com.google.protobuf.WireFormat.MESSAGE_SET_ITEM;
-import static com.google.protobuf.WireFormat.MESSAGE_SET_MESSAGE;
-import static com.google.protobuf.WireFormat.MESSAGE_SET_TYPE_ID;
-import static com.google.protobuf.WireFormat.WIRETYPE_END_GROUP;
-import static com.google.protobuf.WireFormat.WIRETYPE_FIXED32;
-import static com.google.protobuf.WireFormat.WIRETYPE_FIXED64;
-import static com.google.protobuf.WireFormat.WIRETYPE_LENGTH_DELIMITED;
-import static com.google.protobuf.WireFormat.WIRETYPE_START_GROUP;
-import static com.google.protobuf.WireFormat.WIRETYPE_VARINT;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.ArrayDeque;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-
-/**
- * A protobuf writer that serializes messages in their binary form. Messages are serialized in
- * reverse in order to avoid calculating the serialized size of each nested message. Since the
- * message size is not known in advance, the writer employs a strategy of chunking and buffer
- * chaining. Buffers are allocated as-needed by a provided {@link BufferAllocator}. Once writing is
- * finished, the application can access the buffers in forward-writing order by calling {@link
- * #complete()}.
- *
- * <p>Once {@link #complete()} has been called, the writer can not be reused for additional writes.
- * The {@link #getTotalBytesWritten()} will continue to reflect the total of the write and will not
- * be reset.
- */
-@ExperimentalApi
-abstract class BinaryWriter extends ByteOutput implements Writer {
-  public static final int DEFAULT_CHUNK_SIZE = 4096;
-
-  private final BufferAllocator alloc;
-  private final int chunkSize;
-
-  final ArrayDeque<AllocatedBuffer> buffers = new ArrayDeque<AllocatedBuffer>(4);
-  int totalDoneBytes;
-
-  /**
-   * Creates a new {@link BinaryWriter} that will allocate heap buffers of {@link
-   * #DEFAULT_CHUNK_SIZE} as necessary.
-   */
-  public static BinaryWriter newHeapInstance(BufferAllocator alloc) {
-    return newHeapInstance(alloc, DEFAULT_CHUNK_SIZE);
-  }
-
-  /**
-   * Creates a new {@link BinaryWriter} that will allocate heap buffers of {@code chunkSize} as
-   * necessary.
-   */
-  public static BinaryWriter newHeapInstance(BufferAllocator alloc, int chunkSize) {
-    return isUnsafeHeapSupported()
-        ? newUnsafeHeapInstance(alloc, chunkSize)
-        : newSafeHeapInstance(alloc, chunkSize);
-  }
-
-  /**
-   * Creates a new {@link BinaryWriter} that will allocate direct (i.e. non-heap) buffers of {@link
-   * #DEFAULT_CHUNK_SIZE} as necessary.
-   */
-  public static BinaryWriter newDirectInstance(BufferAllocator alloc) {
-    return newDirectInstance(alloc, DEFAULT_CHUNK_SIZE);
-  }
-
-  /**
-   * Creates a new {@link BinaryWriter} that will allocate direct (i.e. non-heap) buffers of {@code
-   * chunkSize} as necessary.
-   */
-  public static BinaryWriter newDirectInstance(BufferAllocator alloc, int chunkSize) {
-    return isUnsafeDirectSupported()
-        ? newUnsafeDirectInstance(alloc, chunkSize)
-        : newSafeDirectInstance(alloc, chunkSize);
-  }
-
-  static boolean isUnsafeHeapSupported() {
-    return UnsafeHeapWriter.isSupported();
-  }
-
-  static boolean isUnsafeDirectSupported() {
-    return UnsafeDirectWriter.isSupported();
-  }
-
-  static BinaryWriter newSafeHeapInstance(BufferAllocator alloc, int chunkSize) {
-    return new SafeHeapWriter(alloc, chunkSize);
-  }
-
-  static BinaryWriter newUnsafeHeapInstance(BufferAllocator alloc, int chunkSize) {
-    if (!isUnsafeHeapSupported()) {
-      throw new UnsupportedOperationException("Unsafe operations not supported");
-    }
-    return new UnsafeHeapWriter(alloc, chunkSize);
-  }
-
-  static BinaryWriter newSafeDirectInstance(BufferAllocator alloc, int chunkSize) {
-    return new SafeDirectWriter(alloc, chunkSize);
-  }
-
-  static BinaryWriter newUnsafeDirectInstance(BufferAllocator alloc, int chunkSize) {
-    if (!isUnsafeDirectSupported()) {
-      throw new UnsupportedOperationException("Unsafe operations not supported");
-    }
-    return new UnsafeDirectWriter(alloc, chunkSize);
-  }
-
-  /** Only allow subclassing for inner classes. */
-  private BinaryWriter(BufferAllocator alloc, int chunkSize) {
-    if (chunkSize <= 0) {
-      throw new IllegalArgumentException("chunkSize must be > 0");
-    }
-    this.alloc = checkNotNull(alloc, "alloc");
-    this.chunkSize = chunkSize;
-  }
-
-  @Override
-  public final FieldOrder fieldOrder() {
-    return FieldOrder.DESCENDING;
-  }
-
-  /**
-   * Completes the write operation and returns a queue of {@link AllocatedBuffer} objects in
-   * forward-writing order. This method should only be called once.
-   *
-   * <p>After calling this method, the writer can not be reused. Create a new writer for future
-   * writes.
-   */
-  public final Queue<AllocatedBuffer> complete() {
-    finishCurrentBuffer();
-    return buffers;
-  }
-
-  @Override
-  public final void writeSFixed32(int fieldNumber, int value) throws IOException {
-    writeFixed32(fieldNumber, value);
-  }
-
-  @Override
-  public final void writeInt64(int fieldNumber, long value) throws IOException {
-    writeUInt64(fieldNumber, value);
-  }
-
-  @Override
-  public final void writeSFixed64(int fieldNumber, long value) throws IOException {
-    writeFixed64(fieldNumber, value);
-  }
-
-  @Override
-  public final void writeFloat(int fieldNumber, float value) throws IOException {
-    writeFixed32(fieldNumber, Float.floatToRawIntBits(value));
-  }
-
-  @Override
-  public final void writeDouble(int fieldNumber, double value) throws IOException {
-    writeFixed64(fieldNumber, Double.doubleToRawLongBits(value));
-  }
-
-  @Override
-  public final void writeEnum(int fieldNumber, int value) throws IOException {
-    writeInt32(fieldNumber, value);
-  }
-
-  @Override
-  public final void writeInt32List(int fieldNumber, List<Integer> list, boolean packed)
-      throws IOException {
-    if (list instanceof IntArrayList) {
-      writeInt32List_Internal(fieldNumber, (IntArrayList) list, packed);
-    } else {
-      writeInt32List_Internal(fieldNumber, list, packed);
-    }
-  }
-
-  private final void writeInt32List_Internal(int fieldNumber, List<Integer> list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT64_SIZE));
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeInt32(list.get(i));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeInt32(fieldNumber, list.get(i));
-      }
-    }
-  }
-
-  private final void writeInt32List_Internal(int fieldNumber, IntArrayList list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT64_SIZE));
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeInt32(list.getInt(i));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeInt32(fieldNumber, list.getInt(i));
-      }
-    }
-  }
-
-  @Override
-  public final void writeFixed32List(int fieldNumber, List<Integer> list, boolean packed)
-      throws IOException {
-    if (list instanceof IntArrayList) {
-      writeFixed32List_Internal(fieldNumber, (IntArrayList) list, packed);
-    } else {
-      writeFixed32List_Internal(fieldNumber, list, packed);
-    }
-  }
-
-  private final void writeFixed32List_Internal(int fieldNumber, List<Integer> list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * FIXED32_SIZE));
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeFixed32(list.get(i));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeFixed32(fieldNumber, list.get(i));
-      }
-    }
-  }
-
-  private final void writeFixed32List_Internal(int fieldNumber, IntArrayList list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * FIXED32_SIZE));
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeFixed32(list.getInt(i));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeFixed32(fieldNumber, list.getInt(i));
-      }
-    }
-  }
-
-  @Override
-  public final void writeInt64List(int fieldNumber, List<Long> list, boolean packed)
-      throws IOException {
-    writeUInt64List(fieldNumber, list, packed);
-  }
-
-  @Override
-  public final void writeUInt64List(int fieldNumber, List<Long> list, boolean packed)
-      throws IOException {
-    if (list instanceof LongArrayList) {
-      writeUInt64List_Internal(fieldNumber, (LongArrayList) list, packed);
-    } else {
-      writeUInt64List_Internal(fieldNumber, list, packed);
-    }
-  }
-
-  private final void writeUInt64List_Internal(int fieldNumber, List<Long> list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT64_SIZE));
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeVarint64(list.get(i));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeUInt64(fieldNumber, list.get(i));
-      }
-    }
-  }
-
-  private final void writeUInt64List_Internal(int fieldNumber, LongArrayList list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT64_SIZE));
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeVarint64(list.getLong(i));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeUInt64(fieldNumber, list.getLong(i));
-      }
-    }
-  }
-
-  @Override
-  public final void writeFixed64List(int fieldNumber, List<Long> list, boolean packed)
-      throws IOException {
-    if (list instanceof LongArrayList) {
-      writeFixed64List_Internal(fieldNumber, (LongArrayList) list, packed);
-    } else {
-      writeFixed64List_Internal(fieldNumber, list, packed);
-    }
-  }
-
-  private final void writeFixed64List_Internal(int fieldNumber, List<Long> list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * FIXED64_SIZE));
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeFixed64(list.get(i));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeFixed64(fieldNumber, list.get(i));
-      }
-    }
-  }
-
-  private final void writeFixed64List_Internal(int fieldNumber, LongArrayList list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * FIXED64_SIZE));
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeFixed64(list.getLong(i));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeFixed64(fieldNumber, list.getLong(i));
-      }
-    }
-  }
-
-  @Override
-  public final void writeFloatList(int fieldNumber, List<Float> list, boolean packed)
-      throws IOException {
-    if (list instanceof FloatArrayList) {
-      writeFloatList_Internal(fieldNumber, (FloatArrayList) list, packed);
-    } else {
-      writeFloatList_Internal(fieldNumber, list, packed);
-    }
-  }
-
-  private final void writeFloatList_Internal(int fieldNumber, List<Float> list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * FIXED32_SIZE));
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeFixed32(Float.floatToRawIntBits(list.get(i)));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeFloat(fieldNumber, list.get(i));
-      }
-    }
-  }
-
-  private final void writeFloatList_Internal(int fieldNumber, FloatArrayList list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * FIXED32_SIZE));
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeFixed32(Float.floatToRawIntBits(list.getFloat(i)));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeFloat(fieldNumber, list.getFloat(i));
-      }
-    }
-  }
-
-  @Override
-  public final void writeDoubleList(int fieldNumber, List<Double> list, boolean packed)
-      throws IOException {
-    if (list instanceof DoubleArrayList) {
-      writeDoubleList_Internal(fieldNumber, (DoubleArrayList) list, packed);
-    } else {
-      writeDoubleList_Internal(fieldNumber, list, packed);
-    }
-  }
-
-  private final void writeDoubleList_Internal(int fieldNumber, List<Double> list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * FIXED64_SIZE));
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeFixed64(Double.doubleToRawLongBits(list.get(i)));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeDouble(fieldNumber, list.get(i));
-      }
-    }
-  }
-
-  private final void writeDoubleList_Internal(int fieldNumber, DoubleArrayList list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * FIXED64_SIZE));
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeFixed64(Double.doubleToRawLongBits(list.getDouble(i)));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeDouble(fieldNumber, list.getDouble(i));
-      }
-    }
-  }
-
-  @Override
-  public final void writeEnumList(int fieldNumber, List<Integer> list, boolean packed)
-      throws IOException {
-    writeInt32List(fieldNumber, list, packed);
-  }
-
-  @Override
-  public final void writeBoolList(int fieldNumber, List<Boolean> list, boolean packed)
-      throws IOException {
-    if (list instanceof BooleanArrayList) {
-      writeBoolList_Internal(fieldNumber, (BooleanArrayList) list, packed);
-    } else {
-      writeBoolList_Internal(fieldNumber, list, packed);
-    }
-  }
-
-  private final void writeBoolList_Internal(int fieldNumber, List<Boolean> list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + list.size());
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeBool(list.get(i));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeBool(fieldNumber, list.get(i));
-      }
-    }
-  }
-
-  private final void writeBoolList_Internal(int fieldNumber, BooleanArrayList list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + list.size());
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeBool(list.getBoolean(i));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeBool(fieldNumber, list.getBoolean(i));
-      }
-    }
-  }
-
-  @Override
-  public final void writeStringList(int fieldNumber, List<String> list) throws IOException {
-    if (list instanceof LazyStringList) {
-      final LazyStringList lazyList = (LazyStringList) list;
-      for (int i = list.size() - 1; i >= 0; i--) {
-        writeLazyString(fieldNumber, lazyList.getRaw(i));
-      }
-    } else {
-      for (int i = list.size() - 1; i >= 0; i--) {
-        writeString(fieldNumber, list.get(i));
-      }
-    }
-  }
-
-  private void writeLazyString(int fieldNumber, Object value) throws IOException {
-    if (value instanceof String) {
-      writeString(fieldNumber, (String) value);
-    } else {
-      writeBytes(fieldNumber, (ByteString) value);
-    }
-  }
-
-  @Override
-  public final void writeBytesList(int fieldNumber, List<ByteString> list) throws IOException {
-    for (int i = list.size() - 1; i >= 0; i--) {
-      writeBytes(fieldNumber, list.get(i));
-    }
-  }
-
-  @Override
-  public final void writeUInt32List(int fieldNumber, List<Integer> list, boolean packed)
-      throws IOException {
-    if (list instanceof IntArrayList) {
-      writeUInt32List_Internal(fieldNumber, (IntArrayList) list, packed);
-    } else {
-      writeUInt32List_Internal(fieldNumber, list, packed);
-    }
-  }
-
-  private final void writeUInt32List_Internal(int fieldNumber, List<Integer> list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT32_SIZE));
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeVarint32(list.get(i));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeUInt32(fieldNumber, list.get(i));
-      }
-    }
-  }
-
-  private final void writeUInt32List_Internal(int fieldNumber, IntArrayList list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT32_SIZE));
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeVarint32(list.getInt(i));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeUInt32(fieldNumber, list.getInt(i));
-      }
-    }
-  }
-
-  @Override
-  public final void writeSFixed32List(int fieldNumber, List<Integer> list, boolean packed)
-      throws IOException {
-    writeFixed32List(fieldNumber, list, packed);
-  }
-
-  @Override
-  public final void writeSFixed64List(int fieldNumber, List<Long> list, boolean packed)
-      throws IOException {
-    writeFixed64List(fieldNumber, list, packed);
-  }
-
-  @Override
-  public final void writeSInt32List(int fieldNumber, List<Integer> list, boolean packed)
-      throws IOException {
-    if (list instanceof IntArrayList) {
-      writeSInt32List_Internal(fieldNumber, (IntArrayList) list, packed);
-    } else {
-      writeSInt32List_Internal(fieldNumber, list, packed);
-    }
-  }
-
-  private final void writeSInt32List_Internal(int fieldNumber, List<Integer> list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT32_SIZE));
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeSInt32(list.get(i));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeSInt32(fieldNumber, list.get(i));
-      }
-    }
-  }
-
-  private final void writeSInt32List_Internal(int fieldNumber, IntArrayList list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT32_SIZE));
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeSInt32(list.getInt(i));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeSInt32(fieldNumber, list.getInt(i));
-      }
-    }
-  }
-
-  @Override
-  public final void writeSInt64List(int fieldNumber, List<Long> list, boolean packed)
-      throws IOException {
-    if (list instanceof LongArrayList) {
-      writeSInt64List_Internal(fieldNumber, (LongArrayList) list, packed);
-    } else {
-      writeSInt64List_Internal(fieldNumber, list, packed);
-    }
-  }
-
-  private static final int MAP_KEY_NUMBER = 1;
-  private static final int MAP_VALUE_NUMBER = 2;
-
-  @Override
-  public <K, V> void writeMap(int fieldNumber, MapEntryLite.Metadata<K, V> metadata, Map<K, V> map)
-      throws IOException {
-    // TODO(liujisi): Reverse write those entries.
-    for (Map.Entry<K, V> entry : map.entrySet()) {
-      int prevBytes = getTotalBytesWritten();
-      writeMapEntryField(this, MAP_VALUE_NUMBER, metadata.valueType, entry.getValue());
-      writeMapEntryField(this, MAP_KEY_NUMBER, metadata.keyType, entry.getKey());
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    }
-  }
-
-  static final void writeMapEntryField(
-      Writer writer, int fieldNumber, WireFormat.FieldType fieldType, Object object)
-      throws IOException {
-    switch (fieldType) {
-      case BOOL:
-        writer.writeBool(fieldNumber, (Boolean) object);
-        break;
-      case FIXED32:
-        writer.writeFixed32(fieldNumber, (Integer) object);
-        break;
-      case FIXED64:
-        writer.writeFixed64(fieldNumber, (Long) object);
-        break;
-      case INT32:
-        writer.writeInt32(fieldNumber, (Integer) object);
-        break;
-      case INT64:
-        writer.writeInt64(fieldNumber, (Long) object);
-        break;
-      case SFIXED32:
-        writer.writeSFixed32(fieldNumber, (Integer) object);
-        break;
-      case SFIXED64:
-        writer.writeSFixed64(fieldNumber, (Long) object);
-        break;
-      case SINT32:
-        writer.writeSInt32(fieldNumber, (Integer) object);
-        break;
-      case SINT64:
-        writer.writeSInt64(fieldNumber, (Long) object);
-        break;
-      case STRING:
-        writer.writeString(fieldNumber, (String) object);
-        break;
-      case UINT32:
-        writer.writeUInt32(fieldNumber, (Integer) object);
-        break;
-      case UINT64:
-        writer.writeUInt64(fieldNumber, (Long) object);
-        break;
-      case FLOAT:
-        writer.writeFloat(fieldNumber, (Float) object);
-        break;
-      case DOUBLE:
-        writer.writeDouble(fieldNumber, (Double) object);
-        break;
-      case MESSAGE:
-        writer.writeMessage(fieldNumber, object);
-        break;
-      case BYTES:
-        writer.writeBytes(fieldNumber, (ByteString) object);
-        break;
-      case ENUM:
-        if (object instanceof Internal.EnumLite) {
-          writer.writeEnum(fieldNumber, ((Internal.EnumLite) object).getNumber());
-        } else if (object instanceof Integer) {
-          writer.writeEnum(fieldNumber, (Integer) object);
-        } else {
-          throw new IllegalArgumentException("Unexpected type for enum in map.");
-        }
-        break;
-      default:
-        throw new IllegalArgumentException("Unsupported map value type for: " + fieldType);
-    }
-  }
-
-  private final void writeSInt64List_Internal(int fieldNumber, List<Long> list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT64_SIZE));
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeSInt64(list.get(i));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeSInt64(fieldNumber, list.get(i));
-      }
-    }
-  }
-
-  private final void writeSInt64List_Internal(int fieldNumber, LongArrayList list, boolean packed)
-      throws IOException {
-    if (packed) {
-      requireSpace((MAX_VARINT32_SIZE * 2) + (list.size() * MAX_VARINT64_SIZE));
-      int prevBytes = getTotalBytesWritten();
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeSInt64(list.getLong(i));
-      }
-      int length = getTotalBytesWritten() - prevBytes;
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    } else {
-      for (int i = list.size() - 1; i >= 0; --i) {
-        writeSInt64(fieldNumber, list.getLong(i));
-      }
-    }
-  }
-
-  @Override
-  public final void writeMessageList(int fieldNumber, List<?> list) throws IOException {
-    for (int i = list.size() - 1; i >= 0; i--) {
-      writeMessage(fieldNumber, list.get(i));
-    }
-  }
-
-  @Override
-  public final void writeMessageList(int fieldNumber, List<?> list, Schema schema)
-      throws IOException {
-    for (int i = list.size() - 1; i >= 0; i--) {
-      writeMessage(fieldNumber, list.get(i), schema);
-    }
-  }
-
-  @Override
-  public final void writeGroupList(int fieldNumber, List<?> list) throws IOException {
-    for (int i = list.size() - 1; i >= 0; i--) {
-      writeGroup(fieldNumber, list.get(i));
-    }
-  }
-
-  @Override
-  public final void writeGroupList(int fieldNumber, List<?> list, Schema schema)
-      throws IOException {
-    for (int i = list.size() - 1; i >= 0; i--) {
-      writeGroup(fieldNumber, list.get(i), schema);
-    }
-  }
-
-  @Override
-  public final void writeMessageSetItem(int fieldNumber, Object value) throws IOException {
-    writeTag(MESSAGE_SET_ITEM, WIRETYPE_END_GROUP);
-    if (value instanceof ByteString) {
-      writeBytes(MESSAGE_SET_MESSAGE, (ByteString) value);
-    } else {
-      writeMessage(MESSAGE_SET_MESSAGE, value);
-    }
-    writeUInt32(MESSAGE_SET_TYPE_ID, fieldNumber);
-    writeTag(MESSAGE_SET_ITEM, WIRETYPE_START_GROUP);
-  }
-
-  final AllocatedBuffer newHeapBuffer() {
-    return alloc.allocateHeapBuffer(chunkSize);
-  }
-
-  final AllocatedBuffer newHeapBuffer(int capacity) {
-    return alloc.allocateHeapBuffer(Math.max(capacity, chunkSize));
-  }
-
-  final AllocatedBuffer newDirectBuffer() {
-    return alloc.allocateDirectBuffer(chunkSize);
-  }
-
-  final AllocatedBuffer newDirectBuffer(int capacity) {
-    return alloc.allocateDirectBuffer(Math.max(capacity, chunkSize));
-  }
-
-  /**
-   * Gets the total number of bytes that have been written. This will not be reset by a call to
-   * {@link #complete()}.
-   */
-  public abstract int getTotalBytesWritten();
-
-  abstract void requireSpace(int size);
-
-  abstract void finishCurrentBuffer();
-
-  abstract void writeTag(int fieldNumber, int wireType);
-
-  abstract void writeVarint32(int value);
-
-  abstract void writeInt32(int value);
-
-  abstract void writeSInt32(int value);
-
-  abstract void writeFixed32(int value);
-
-  abstract void writeVarint64(long value);
-
-  abstract void writeSInt64(long value);
-
-  abstract void writeFixed64(long value);
-
-  abstract void writeBool(boolean value);
-
-  abstract void writeString(String in);
-
-  /**
-   * Not using the version in CodedOutputStream due to the fact that benchmarks have shown a
-   * performance improvement when returning a byte (rather than an int).
-   */
-  private static byte computeUInt64SizeNoTag(long value) {
-    // handle two popular special cases up front ...
-    if ((value & (~0L << 7)) == 0L) {
-      // Byte 1
-      return 1;
-    }
-    if (value < 0L) {
-      // Byte 10
-      return 10;
-    }
-    // ... leaving us with 8 remaining, which we can divide and conquer
-    byte n = 2;
-    if ((value & (~0L << 35)) != 0L) {
-      // Byte 6-9
-      n += 4; // + (value >>> 63);
-      value >>>= 28;
-    }
-    if ((value & (~0L << 21)) != 0L) {
-      // Byte 4-5 or 8-9
-      n += 2;
-      value >>>= 14;
-    }
-    if ((value & (~0L << 14)) != 0L) {
-      // Byte 3 or 7
-      n += 1;
-    }
-    return n;
-  }
-
-  /** Writer that uses safe operations on target array. */
-  private static final class SafeHeapWriter extends BinaryWriter {
-    private AllocatedBuffer allocatedBuffer;
-    private byte[] buffer;
-    private int offset;
-    private int limit;
-    private int offsetMinusOne;
-    private int limitMinusOne;
-    private int pos;
-
-    SafeHeapWriter(BufferAllocator alloc, int chunkSize) {
-      super(alloc, chunkSize);
-      nextBuffer();
-    }
-
-    @Override
-    void finishCurrentBuffer() {
-      if (allocatedBuffer != null) {
-        totalDoneBytes += bytesWrittenToCurrentBuffer();
-        allocatedBuffer.position((pos - allocatedBuffer.arrayOffset()) + 1);
-        allocatedBuffer = null;
-        pos = 0;
-        limitMinusOne = 0;
-      }
-    }
-
-    private void nextBuffer() {
-      nextBuffer(newHeapBuffer());
-    }
-
-    private void nextBuffer(int capacity) {
-      nextBuffer(newHeapBuffer(capacity));
-    }
-
-    private void nextBuffer(AllocatedBuffer allocatedBuffer) {
-      if (!allocatedBuffer.hasArray()) {
-        throw new RuntimeException("Allocator returned non-heap buffer");
-      }
-
-      finishCurrentBuffer();
-
-      buffers.addFirst(allocatedBuffer);
-
-      this.allocatedBuffer = allocatedBuffer;
-      this.buffer = allocatedBuffer.array();
-      int arrayOffset = allocatedBuffer.arrayOffset();
-      this.limit = arrayOffset + allocatedBuffer.limit();
-      this.offset = arrayOffset + allocatedBuffer.position();
-      this.offsetMinusOne = offset - 1;
-      this.limitMinusOne = limit - 1;
-      this.pos = limitMinusOne;
-    }
-
-    @Override
-    public int getTotalBytesWritten() {
-      return totalDoneBytes + bytesWrittenToCurrentBuffer();
-    }
-
-    int bytesWrittenToCurrentBuffer() {
-      return limitMinusOne - pos;
-    }
-
-    int spaceLeft() {
-      return pos - offsetMinusOne;
-    }
-
-    @Override
-    public void writeUInt32(int fieldNumber, int value) throws IOException {
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeVarint32(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeInt32(int fieldNumber, int value) throws IOException {
-      requireSpace(MAX_VARINT32_SIZE + MAX_VARINT64_SIZE);
-      writeInt32(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeSInt32(int fieldNumber, int value) throws IOException {
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeSInt32(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeFixed32(int fieldNumber, int value) throws IOException {
-      requireSpace(MAX_VARINT32_SIZE + FIXED32_SIZE);
-      writeFixed32(value);
-      writeTag(fieldNumber, WIRETYPE_FIXED32);
-    }
-
-    @Override
-    public void writeUInt64(int fieldNumber, long value) throws IOException {
-      requireSpace(MAX_VARINT32_SIZE + MAX_VARINT64_SIZE);
-      writeVarint64(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeSInt64(int fieldNumber, long value) throws IOException {
-      requireSpace(MAX_VARINT32_SIZE + MAX_VARINT64_SIZE);
-      writeSInt64(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeFixed64(int fieldNumber, long value) throws IOException {
-      requireSpace(MAX_VARINT32_SIZE + FIXED64_SIZE);
-      writeFixed64(value);
-      writeTag(fieldNumber, WIRETYPE_FIXED64);
-    }
-
-    @Override
-    public void writeBool(int fieldNumber, boolean value) throws IOException {
-      requireSpace(MAX_VARINT32_SIZE + 1);
-      write((byte) (value ? 1 : 0));
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeString(int fieldNumber, String value) throws IOException {
-      int prevBytes = getTotalBytesWritten();
-      writeString(value);
-      int length = getTotalBytesWritten() - prevBytes;
-      requireSpace(2 * MAX_VARINT32_SIZE);
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    }
-
-    @Override
-    public void writeBytes(int fieldNumber, ByteString value) throws IOException {
-      try {
-        value.writeToReverse(this);
-      } catch (IOException e) {
-        // Should never happen since the writer does not throw.
-        throw new RuntimeException(e);
-      }
-
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeVarint32(value.size());
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    }
-
-    @Override
-    public void writeMessage(int fieldNumber, Object value) throws IOException {
-      int prevBytes = getTotalBytesWritten();
-      Protobuf.getInstance().writeTo(value, this);
-      int length = getTotalBytesWritten() - prevBytes;
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    }
-
-    @Override
-    public void writeMessage(int fieldNumber, Object value, Schema schema) throws IOException {
-      int prevBytes = getTotalBytesWritten();
-      schema.writeTo(value, this);
-      int length = getTotalBytesWritten() - prevBytes;
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    }
-
-    @Override
-    public void writeGroup(int fieldNumber, Object value) throws IOException {
-      writeTag(fieldNumber, WIRETYPE_END_GROUP);
-      Protobuf.getInstance().writeTo(value, this);
-      writeTag(fieldNumber, WIRETYPE_START_GROUP);
-    }
-
-    @Override
-    public void writeGroup(int fieldNumber, Object value, Schema schema) throws IOException {
-      writeTag(fieldNumber, WIRETYPE_END_GROUP);
-      schema.writeTo(value, this);
-      writeTag(fieldNumber, WIRETYPE_START_GROUP);
-    }
-
-    @Override
-    public void writeStartGroup(int fieldNumber) {
-      writeTag(fieldNumber, WIRETYPE_START_GROUP);
-    }
-
-    @Override
-    public void writeEndGroup(int fieldNumber) {
-      writeTag(fieldNumber, WIRETYPE_END_GROUP);
-    }
-
-    @Override
-    void writeInt32(int value) {
-      if (value >= 0) {
-        writeVarint32(value);
-      } else {
-        writeVarint64(value);
-      }
-    }
-
-    @Override
-    void writeSInt32(int value) {
-      writeVarint32(CodedOutputStream.encodeZigZag32(value));
-    }
-
-    @Override
-    void writeSInt64(long value) {
-      writeVarint64(CodedOutputStream.encodeZigZag64(value));
-    }
-
-    @Override
-    void writeBool(boolean value) {
-      write((byte) (value ? 1 : 0));
-    }
-
-    @Override
-    void writeTag(int fieldNumber, int wireType) {
-      writeVarint32(WireFormat.makeTag(fieldNumber, wireType));
-    }
-
-    @Override
-    void writeVarint32(int value) {
-      if ((value & (~0 << 7)) == 0) {
-        writeVarint32OneByte(value);
-      } else if ((value & (~0 << 14)) == 0) {
-        writeVarint32TwoBytes(value);
-      } else if ((value & (~0 << 21)) == 0) {
-        writeVarint32ThreeBytes(value);
-      } else if ((value & (~0 << 28)) == 0) {
-        writeVarint32FourBytes(value);
-      } else {
-        writeVarint32FiveBytes(value);
-      }
-    }
-
-    private void writeVarint32OneByte(int value) {
-      buffer[pos--] = (byte) value;
-    }
-
-    private void writeVarint32TwoBytes(int value) {
-      buffer[pos--] = (byte) (value >>> 7);
-      buffer[pos--] = (byte) ((value & 0x7F) | 0x80);
-    }
-
-    private void writeVarint32ThreeBytes(int value) {
-      buffer[pos--] = (byte) (value >>> 14);
-      buffer[pos--] = (byte) (((value >>> 7) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) ((value & 0x7F) | 0x80);
-    }
-
-    private void writeVarint32FourBytes(int value) {
-      buffer[pos--] = (byte) (value >>> 21);
-      buffer[pos--] = (byte) (((value >>> 14) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 7) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) ((value & 0x7F) | 0x80);
-    }
-
-    private void writeVarint32FiveBytes(int value) {
-      buffer[pos--] = (byte) (value >>> 28);
-      buffer[pos--] = (byte) (((value >>> 21) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 14) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 7) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) ((value & 0x7F) | 0x80);
-    }
-
-    @Override
-    void writeVarint64(long value) {
-      switch (computeUInt64SizeNoTag(value)) {
-        case 1:
-          writeVarint64OneByte(value);
-          break;
-        case 2:
-          writeVarint64TwoBytes(value);
-          break;
-        case 3:
-          writeVarint64ThreeBytes(value);
-          break;
-        case 4:
-          writeVarint64FourBytes(value);
-          break;
-        case 5:
-          writeVarint64FiveBytes(value);
-          break;
-        case 6:
-          writeVarint64SixBytes(value);
-          break;
-        case 7:
-          writeVarint64SevenBytes(value);
-          break;
-        case 8:
-          writeVarint64EightBytes(value);
-          break;
-        case 9:
-          writeVarint64NineBytes(value);
-          break;
-        case 10:
-          writeVarint64TenBytes(value);
-          break;
-      }
-    }
-
-    private void writeVarint64OneByte(long value) {
-      buffer[pos--] = (byte) value;
-    }
-
-    private void writeVarint64TwoBytes(long value) {
-      buffer[pos--] = (byte) (value >>> 7);
-      buffer[pos--] = (byte) (((int) value & 0x7F) | 0x80);
-    }
-
-    private void writeVarint64ThreeBytes(long value) {
-      buffer[pos--] = (byte) (((int) value) >>> 14);
-      buffer[pos--] = (byte) (((value >>> 7) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) ((value & 0x7F) | 0x80);
-    }
-
-    private void writeVarint64FourBytes(long value) {
-      buffer[pos--] = (byte) (value >>> 21);
-      buffer[pos--] = (byte) (((value >>> 14) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 7) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) ((value & 0x7F) | 0x80);
-    }
-
-    private void writeVarint64FiveBytes(long value) {
-      buffer[pos--] = (byte) (value >>> 28);
-      buffer[pos--] = (byte) (((value >>> 21) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 14) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 7) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) ((value & 0x7F) | 0x80);
-    }
-
-    private void writeVarint64SixBytes(long value) {
-      buffer[pos--] = (byte) (value >>> 35);
-      buffer[pos--] = (byte) (((value >>> 28) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 21) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 14) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 7) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) ((value & 0x7F) | 0x80);
-    }
-
-    private void writeVarint64SevenBytes(long value) {
-      buffer[pos--] = (byte) (value >>> 42);
-      buffer[pos--] = (byte) (((value >>> 35) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 28) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 21) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 14) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 7) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) ((value & 0x7F) | 0x80);
-    }
-
-    private void writeVarint64EightBytes(long value) {
-      buffer[pos--] = (byte) (value >>> 49);
-      buffer[pos--] = (byte) (((value >>> 42) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 35) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 28) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 21) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 14) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 7) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) ((value & 0x7F) | 0x80);
-    }
-
-    private void writeVarint64NineBytes(long value) {
-      buffer[pos--] = (byte) (value >>> 56);
-      buffer[pos--] = (byte) (((value >>> 49) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 42) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 35) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 28) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 21) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 14) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 7) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) ((value & 0x7F) | 0x80);
-    }
-
-    private void writeVarint64TenBytes(long value) {
-      buffer[pos--] = (byte) (value >>> 63);
-      buffer[pos--] = (byte) (((value >>> 56) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 49) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 42) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 35) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 28) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 21) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 14) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) (((value >>> 7) & 0x7F) | 0x80);
-      buffer[pos--] = (byte) ((value & 0x7F) | 0x80);
-    }
-
-    @Override
-    void writeFixed32(int value) {
-      buffer[pos--] = (byte) ((value >> 24) & 0xFF);
-      buffer[pos--] = (byte) ((value >> 16) & 0xFF);
-      buffer[pos--] = (byte) ((value >> 8) & 0xFF);
-      buffer[pos--] = (byte) (value & 0xFF);
-    }
-
-    @Override
-    void writeFixed64(long value) {
-      buffer[pos--] = (byte) ((int) (value >> 56) & 0xFF);
-      buffer[pos--] = (byte) ((int) (value >> 48) & 0xFF);
-      buffer[pos--] = (byte) ((int) (value >> 40) & 0xFF);
-      buffer[pos--] = (byte) ((int) (value >> 32) & 0xFF);
-      buffer[pos--] = (byte) ((int) (value >> 24) & 0xFF);
-      buffer[pos--] = (byte) ((int) (value >> 16) & 0xFF);
-      buffer[pos--] = (byte) ((int) (value >> 8) & 0xFF);
-      buffer[pos--] = (byte) ((int) (value) & 0xFF);
-    }
-
-    @Override
-    void writeString(String in) {
-      // Request enough space to write the ASCII string.
-      requireSpace(in.length());
-
-      // We know the buffer is big enough...
-      int i = in.length() - 1;
-      // Set pos to the start of the ASCII string.
-      pos -= i;
-      // Designed to take advantage of
-      // https://wiki.openjdk.java.net/display/HotSpotInternals/RangeCheckElimination
-      for (char c; i >= 0 && (c = in.charAt(i)) < 0x80; i--) {
-        buffer[pos + i] = (byte) c;
-      }
-      if (i == -1) {
-        // Move pos past the String.
-        pos -= 1;
-        return;
-      }
-      pos += i;
-      for (char c; i >= 0; i--) {
-        c = in.charAt(i);
-        if (c < 0x80 && pos > offsetMinusOne) {
-          buffer[pos--] = (byte) c;
-        } else if (c < 0x800 && pos > offset) { // 11 bits, two UTF-8 bytes
-          buffer[pos--] = (byte) (0x80 | (0x3F & c));
-          buffer[pos--] = (byte) ((0xF << 6) | (c >>> 6));
-        } else if ((c < Character.MIN_SURROGATE || Character.MAX_SURROGATE < c)
-            && pos > (offset + 1)) {
-          // Maximum single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
-          buffer[pos--] = (byte) (0x80 | (0x3F & c));
-          buffer[pos--] = (byte) (0x80 | (0x3F & (c >>> 6)));
-          buffer[pos--] = (byte) ((0xF << 5) | (c >>> 12));
-        } else if (pos > (offset + 2)) {
-          // Minimum code point represented by a surrogate pair is 0x10000, 17 bits,
-          // four UTF-8 bytes
-          char high = 0;
-          if (i == 0 || !Character.isSurrogatePair(high = in.charAt(i - 1), c)) {
-            throw new Utf8.UnpairedSurrogateException(i - 1, i);
-          }
-          i--;
-          int codePoint = Character.toCodePoint(high, c);
-          buffer[pos--] = (byte) (0x80 | (0x3F & codePoint));
-          buffer[pos--] = (byte) (0x80 | (0x3F & (codePoint >>> 6)));
-          buffer[pos--] = (byte) (0x80 | (0x3F & (codePoint >>> 12)));
-          buffer[pos--] = (byte) ((0xF << 4) | (codePoint >>> 18));
-        } else {
-          // Buffer is full - allocate a new one and revisit the current character.
-          requireSpace(i);
-          i++;
-        }
-      }
-    }
-
-    @Override
-    public void write(byte value) {
-      buffer[pos--] = value;
-    }
-
-    @Override
-    public void write(byte[] value, int offset, int length) {
-      if (spaceLeft() < length) {
-        nextBuffer(length);
-      }
-
-      pos -= length;
-      System.arraycopy(value, offset, buffer, pos + 1, length);
-    }
-
-    @Override
-    public void writeLazy(byte[] value, int offset, int length) {
-      if (spaceLeft() < length) {
-        // We consider the value to be immutable (likely the internals of a ByteString). Just
-        // wrap it in a Netty buffer and add it to the output buffer.
-        totalDoneBytes += length;
-        buffers.addFirst(AllocatedBuffer.wrap(value, offset, length));
-
-        // Advance the writer to the next buffer.
-        // TODO(nathanmittler): Consider slicing if space available above some threshold.
-        nextBuffer();
-        return;
-      }
-
-      pos -= length;
-      System.arraycopy(value, offset, buffer, pos + 1, length);
-    }
-
-    @Override
-    public void write(ByteBuffer value) {
-      int length = value.remaining();
-      if (spaceLeft() < length) {
-        nextBuffer(length);
-      }
-
-      pos -= length;
-      value.get(buffer, pos + 1, length);
-    }
-
-    @Override
-    public void writeLazy(ByteBuffer value) {
-      int length = value.remaining();
-      if (spaceLeft() < length) {
-        // We consider the value to be immutable (likely the internals of a ByteString). Just
-        // wrap it in a Netty buffer and add it to the output buffer.
-        totalDoneBytes += length;
-        buffers.addFirst(AllocatedBuffer.wrap(value));
-
-        // Advance the writer to the next buffer.
-        // TODO(nathanmittler): Consider slicing if space available above some threshold.
-        nextBuffer();
-      }
-
-      pos -= length;
-      value.get(buffer, pos + 1, length);
-    }
-
-    @Override
-    void requireSpace(int size) {
-      if (spaceLeft() < size) {
-        nextBuffer(size);
-      }
-    }
-  }
-
-  /** Writer that uses unsafe operations on a target array. */
-  private static final class UnsafeHeapWriter extends BinaryWriter {
-    private AllocatedBuffer allocatedBuffer;
-    private byte[] buffer;
-    private long offset;
-    private long limit;
-    private long offsetMinusOne;
-    private long limitMinusOne;
-    private long pos;
-
-    UnsafeHeapWriter(BufferAllocator alloc, int chunkSize) {
-      super(alloc, chunkSize);
-      nextBuffer();
-    }
-
-    /** Indicates whether the required unsafe operations are supported on this platform. */
-    static boolean isSupported() {
-      return UnsafeUtil.hasUnsafeArrayOperations();
-    }
-
-    @Override
-    void finishCurrentBuffer() {
-      if (allocatedBuffer != null) {
-        totalDoneBytes += bytesWrittenToCurrentBuffer();
-        allocatedBuffer.position((arrayPos() - allocatedBuffer.arrayOffset()) + 1);
-        allocatedBuffer = null;
-        pos = 0;
-        limitMinusOne = 0;
-      }
-    }
-
-    private int arrayPos() {
-      return (int) pos;
-    }
-
-    private void nextBuffer() {
-      nextBuffer(newHeapBuffer());
-    }
-
-    private void nextBuffer(int capacity) {
-      nextBuffer(newHeapBuffer(capacity));
-    }
-
-    private void nextBuffer(AllocatedBuffer allocatedBuffer) {
-      if (!allocatedBuffer.hasArray()) {
-        throw new RuntimeException("Allocator returned non-heap buffer");
-      }
-
-      finishCurrentBuffer();
-      buffers.addFirst(allocatedBuffer);
-
-      this.allocatedBuffer = allocatedBuffer;
-      this.buffer = allocatedBuffer.array();
-      int arrayOffset = allocatedBuffer.arrayOffset();
-      this.limit = arrayOffset + allocatedBuffer.limit();
-      this.offset = arrayOffset + allocatedBuffer.position();
-      this.offsetMinusOne = offset - 1;
-      this.limitMinusOne = limit - 1;
-      this.pos = limitMinusOne;
-    }
-
-    @Override
-    public int getTotalBytesWritten() {
-      return totalDoneBytes + bytesWrittenToCurrentBuffer();
-    }
-
-    int bytesWrittenToCurrentBuffer() {
-      return (int) (limitMinusOne - pos);
-    }
-
-    int spaceLeft() {
-      return (int) (pos - offsetMinusOne);
-    }
-
-    @Override
-    public void writeUInt32(int fieldNumber, int value) {
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeVarint32(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeInt32(int fieldNumber, int value) {
-      requireSpace(MAX_VARINT32_SIZE + MAX_VARINT64_SIZE);
-      writeInt32(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeSInt32(int fieldNumber, int value) {
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeSInt32(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeFixed32(int fieldNumber, int value) {
-      requireSpace(MAX_VARINT32_SIZE + FIXED32_SIZE);
-      writeFixed32(value);
-      writeTag(fieldNumber, WIRETYPE_FIXED32);
-    }
-
-    @Override
-    public void writeUInt64(int fieldNumber, long value) {
-      requireSpace(MAX_VARINT32_SIZE + MAX_VARINT64_SIZE);
-      writeVarint64(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeSInt64(int fieldNumber, long value) {
-      requireSpace(MAX_VARINT32_SIZE + MAX_VARINT64_SIZE);
-      writeSInt64(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeFixed64(int fieldNumber, long value) {
-      requireSpace(MAX_VARINT32_SIZE + FIXED64_SIZE);
-      writeFixed64(value);
-      writeTag(fieldNumber, WIRETYPE_FIXED64);
-    }
-
-    @Override
-    public void writeBool(int fieldNumber, boolean value) {
-      requireSpace(MAX_VARINT32_SIZE + 1);
-      write((byte) (value ? 1 : 0));
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeString(int fieldNumber, String value) {
-      int prevBytes = getTotalBytesWritten();
-      writeString(value);
-      int length = getTotalBytesWritten() - prevBytes;
-      requireSpace(2 * MAX_VARINT32_SIZE);
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    }
-
-    @Override
-    public void writeBytes(int fieldNumber, ByteString value) {
-      try {
-        value.writeToReverse(this);
-      } catch (IOException e) {
-        // Should never happen since the writer does not throw.
-        throw new RuntimeException(e);
-      }
-
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeVarint32(value.size());
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    }
-
-    @Override
-    public void writeMessage(int fieldNumber, Object value) throws IOException {
-      int prevBytes = getTotalBytesWritten();
-      Protobuf.getInstance().writeTo(value, this);
-      int length = getTotalBytesWritten() - prevBytes;
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    }
-
-    @Override
-    public void writeMessage(int fieldNumber, Object value, Schema schema) throws IOException {
-      int prevBytes = getTotalBytesWritten();
-      schema.writeTo(value, this);
-      int length = getTotalBytesWritten() - prevBytes;
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    }
-
-    @Override
-    public void writeGroup(int fieldNumber, Object value) throws IOException {
-      writeTag(fieldNumber, WIRETYPE_END_GROUP);
-      Protobuf.getInstance().writeTo(value, this);
-      writeTag(fieldNumber, WIRETYPE_START_GROUP);
-    }
-
-    @Override
-    public void writeGroup(int fieldNumber, Object value, Schema schema) throws IOException {
-      writeTag(fieldNumber, WIRETYPE_END_GROUP);
-      schema.writeTo(value, this);
-      writeTag(fieldNumber, WIRETYPE_START_GROUP);
-    }
-
-    @Override
-    public void writeStartGroup(int fieldNumber) {
-      writeTag(fieldNumber, WIRETYPE_START_GROUP);
-    }
-
-    @Override
-    public void writeEndGroup(int fieldNumber) {
-      writeTag(fieldNumber, WIRETYPE_END_GROUP);
-    }
-
-    @Override
-    void writeInt32(int value) {
-      if (value >= 0) {
-        writeVarint32(value);
-      } else {
-        writeVarint64(value);
-      }
-    }
-
-    @Override
-    void writeSInt32(int value) {
-      writeVarint32(CodedOutputStream.encodeZigZag32(value));
-    }
-
-    @Override
-    void writeSInt64(long value) {
-      writeVarint64(CodedOutputStream.encodeZigZag64(value));
-    }
-
-    @Override
-    void writeBool(boolean value) {
-      write((byte) (value ? 1 : 0));
-    }
-
-    @Override
-    void writeTag(int fieldNumber, int wireType) {
-      writeVarint32(WireFormat.makeTag(fieldNumber, wireType));
-    }
-
-    @Override
-    void writeVarint32(int value) {
-      if ((value & (~0 << 7)) == 0) {
-        writeVarint32OneByte(value);
-      } else if ((value & (~0 << 14)) == 0) {
-        writeVarint32TwoBytes(value);
-      } else if ((value & (~0 << 21)) == 0) {
-        writeVarint32ThreeBytes(value);
-      } else if ((value & (~0 << 28)) == 0) {
-        writeVarint32FourBytes(value);
-      } else {
-        writeVarint32FiveBytes(value);
-      }
-    }
-
-    private void writeVarint32OneByte(int value) {
-      UnsafeUtil.putByte(buffer, pos--, (byte) value);
-    }
-
-    private void writeVarint32TwoBytes(int value) {
-      UnsafeUtil.putByte(buffer, pos--, (byte) (value >>> 7));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint32ThreeBytes(int value) {
-      UnsafeUtil.putByte(buffer, pos--, (byte) (value >>> 14));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint32FourBytes(int value) {
-      UnsafeUtil.putByte(buffer, pos--, (byte) (value >>> 21));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 14) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint32FiveBytes(int value) {
-      UnsafeUtil.putByte(buffer, pos--, (byte) (value >>> 28));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 21) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 14) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    @Override
-    void writeVarint64(long value) {
-      switch (computeUInt64SizeNoTag(value)) {
-        case 1:
-          writeVarint64OneByte(value);
-          break;
-        case 2:
-          writeVarint64TwoBytes(value);
-          break;
-        case 3:
-          writeVarint64ThreeBytes(value);
-          break;
-        case 4:
-          writeVarint64FourBytes(value);
-          break;
-        case 5:
-          writeVarint64FiveBytes(value);
-          break;
-        case 6:
-          writeVarint64SixBytes(value);
-          break;
-        case 7:
-          writeVarint64SevenBytes(value);
-          break;
-        case 8:
-          writeVarint64EightBytes(value);
-          break;
-        case 9:
-          writeVarint64NineBytes(value);
-          break;
-        case 10:
-          writeVarint64TenBytes(value);
-          break;
-      }
-    }
-
-    private void writeVarint64OneByte(long value) {
-      UnsafeUtil.putByte(buffer, pos--, (byte) value);
-    }
-
-    private void writeVarint64TwoBytes(long value) {
-      UnsafeUtil.putByte(buffer, pos--, (byte) (value >>> 7));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((int) value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint64ThreeBytes(long value) {
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((int) value) >>> 14));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint64FourBytes(long value) {
-      UnsafeUtil.putByte(buffer, pos--, (byte) (value >>> 21));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 14) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint64FiveBytes(long value) {
-      UnsafeUtil.putByte(buffer, pos--, (byte) (value >>> 28));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 21) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 14) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint64SixBytes(long value) {
-      UnsafeUtil.putByte(buffer, pos--, (byte) (value >>> 35));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 28) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 21) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 14) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint64SevenBytes(long value) {
-      UnsafeUtil.putByte(buffer, pos--, (byte) (value >>> 42));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 35) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 28) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 21) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 14) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint64EightBytes(long value) {
-      UnsafeUtil.putByte(buffer, pos--, (byte) (value >>> 49));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 42) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 35) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 28) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 21) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 14) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint64NineBytes(long value) {
-      UnsafeUtil.putByte(buffer, pos--, (byte) (value >>> 56));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 49) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 42) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 35) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 28) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 21) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 14) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint64TenBytes(long value) {
-      UnsafeUtil.putByte(buffer, pos--, (byte) (value >>> 63));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 56) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 49) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 42) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 35) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 28) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 21) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 14) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    @Override
-    void writeFixed32(int value) {
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((value >> 24) & 0xFF));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((value >> 16) & 0xFF));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((value >> 8) & 0xFF));
-      UnsafeUtil.putByte(buffer, pos--, (byte) (value & 0xFF));
-    }
-
-    @Override
-    void writeFixed64(long value) {
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((int) (value >> 56) & 0xFF));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((int) (value >> 48) & 0xFF));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((int) (value >> 40) & 0xFF));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((int) (value >> 32) & 0xFF));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((int) (value >> 24) & 0xFF));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((int) (value >> 16) & 0xFF));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((int) (value >> 8) & 0xFF));
-      UnsafeUtil.putByte(buffer, pos--, (byte) ((int) (value) & 0xFF));
-    }
-
-    @Override
-    void writeString(String in) {
-      // Request enough space to write the ASCII string.
-      requireSpace(in.length());
-
-      // We know the buffer is big enough...
-      int i = in.length() - 1;
-      // Set pos to the start of the ASCII string.
-      // pos -= i;
-      // Designed to take advantage of
-      // https://wiki.openjdk.java.net/display/HotSpotInternals/RangeCheckElimination
-      for (char c; i >= 0 && (c = in.charAt(i)) < 0x80; i--) {
-        UnsafeUtil.putByte(buffer, pos--, (byte) c);
-      }
-      if (i == -1) {
-        // Move pos past the String.
-        return;
-      }
-      for (char c; i >= 0; i--) {
-        c = in.charAt(i);
-        if (c < 0x80 && pos > offsetMinusOne) {
-          UnsafeUtil.putByte(buffer, pos--, (byte) c);
-        } else if (c < 0x800 && pos > offset) { // 11 bits, two UTF-8 bytes
-          UnsafeUtil.putByte(buffer, pos--, (byte) (0x80 | (0x3F & c)));
-          UnsafeUtil.putByte(buffer, pos--, (byte) ((0xF << 6) | (c >>> 6)));
-        } else if ((c < Character.MIN_SURROGATE || Character.MAX_SURROGATE < c)
-            && pos > offset + 1) {
-          // Maximum single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
-          UnsafeUtil.putByte(buffer, pos--, (byte) (0x80 | (0x3F & c)));
-          UnsafeUtil.putByte(buffer, pos--, (byte) (0x80 | (0x3F & (c >>> 6))));
-          UnsafeUtil.putByte(buffer, pos--, (byte) ((0xF << 5) | (c >>> 12)));
-        } else if (pos > offset + 2) {
-          // Minimum code point represented by a surrogate pair is 0x10000, 17 bits,
-          // four UTF-8 bytes
-          final char high;
-          if (i == 0 || !Character.isSurrogatePair(high = in.charAt(i - 1), c)) {
-            throw new Utf8.UnpairedSurrogateException(i - 1, i);
-          }
-          i--;
-          int codePoint = Character.toCodePoint(high, c);
-          UnsafeUtil.putByte(buffer, pos--, (byte) (0x80 | (0x3F & codePoint)));
-          UnsafeUtil.putByte(buffer, pos--, (byte) (0x80 | (0x3F & (codePoint >>> 6))));
-          UnsafeUtil.putByte(buffer, pos--, (byte) (0x80 | (0x3F & (codePoint >>> 12))));
-          UnsafeUtil.putByte(buffer, pos--, (byte) ((0xF << 4) | (codePoint >>> 18)));
-        } else {
-          // Buffer is full - allocate a new one and revisit the current character.
-          requireSpace(i);
-          i++;
-        }
-      }
-    }
-
-    @Override
-    public void write(byte value) {
-      UnsafeUtil.putByte(buffer, pos--, value);
-    }
-
-    @Override
-    public void write(byte[] value, int offset, int length) {
-      if (offset < 0 || offset + length > value.length) {
-        throw new ArrayIndexOutOfBoundsException(
-            String.format("value.length=%d, offset=%d, length=%d", value.length, offset, length));
-      }
-      requireSpace(length);
-
-      pos -= length;
-      System.arraycopy(value, offset, buffer, arrayPos() + 1, length);
-    }
-
-    @Override
-    public void writeLazy(byte[] value, int offset, int length) {
-      if (offset < 0 || offset + length > value.length) {
-        throw new ArrayIndexOutOfBoundsException(
-            String.format("value.length=%d, offset=%d, length=%d", value.length, offset, length));
-      }
-      if (spaceLeft() < length) {
-        // We consider the value to be immutable (likely the internals of a ByteString). Just
-        // wrap it in a Netty buffer and add it to the output buffer.
-        totalDoneBytes += length;
-        buffers.addFirst(AllocatedBuffer.wrap(value, offset, length));
-
-        // Advance the writer to the next buffer.
-        // TODO(nathanmittler): Consider slicing if space available above some threshold.
-        nextBuffer();
-        return;
-      }
-
-      pos -= length;
-      System.arraycopy(value, offset, buffer, arrayPos() + 1, length);
-    }
-
-    @Override
-    public void write(ByteBuffer value) {
-      int length = value.remaining();
-      requireSpace(length);
-
-      pos -= length;
-      value.get(buffer, arrayPos() + 1, length);
-    }
-
-    @Override
-    public void writeLazy(ByteBuffer value) {
-      int length = value.remaining();
-      if (spaceLeft() < length) {
-        // We consider the value to be immutable (likely the internals of a ByteString). Just
-        // wrap it in a Netty buffer and add it to the output buffer.
-        totalDoneBytes += length;
-        buffers.addFirst(AllocatedBuffer.wrap(value));
-
-        // Advance the writer to the next buffer.
-        // TODO(nathanmittler): Consider slicing if space available above some threshold.
-        nextBuffer();
-      }
-
-      pos -= length;
-      value.get(buffer, arrayPos() + 1, length);
-    }
-
-    @Override
-    void requireSpace(int size) {
-      if (spaceLeft() < size) {
-        nextBuffer(size);
-      }
-    }
-  }
-
-  /** Writer that uses safe operations on a target {@link ByteBuffer}. */
-  private static final class SafeDirectWriter extends BinaryWriter {
-    private ByteBuffer buffer;
-    private int limitMinusOne;
-    private int pos;
-
-    SafeDirectWriter(BufferAllocator alloc, int chunkSize) {
-      super(alloc, chunkSize);
-      nextBuffer();
-    }
-
-    private void nextBuffer() {
-      nextBuffer(newDirectBuffer());
-    }
-
-    private void nextBuffer(int capacity) {
-      nextBuffer(newDirectBuffer(capacity));
-    }
-
-    private void nextBuffer(AllocatedBuffer allocatedBuffer) {
-      if (!allocatedBuffer.hasNioBuffer()) {
-        throw new RuntimeException("Allocated buffer does not have NIO buffer");
-      }
-      ByteBuffer nioBuffer = allocatedBuffer.nioBuffer();
-      if (!nioBuffer.isDirect()) {
-        throw new RuntimeException("Allocator returned non-direct buffer");
-      }
-
-      finishCurrentBuffer();
-      buffers.addFirst(allocatedBuffer);
-
-      buffer = nioBuffer;
-      buffer.limit(buffer.capacity());
-      buffer.position(0);
-      // Set byte order to little endian for fast writing of fixed 32/64.
-      buffer.order(ByteOrder.LITTLE_ENDIAN);
-
-      limitMinusOne = buffer.limit() - 1;
-      pos = limitMinusOne;
-    }
-
-    @Override
-    public int getTotalBytesWritten() {
-      return totalDoneBytes + bytesWrittenToCurrentBuffer();
-    }
-
-    private int bytesWrittenToCurrentBuffer() {
-      return limitMinusOne - pos;
-    }
-
-    private int spaceLeft() {
-      return pos + 1;
-    }
-
-    @Override
-    void finishCurrentBuffer() {
-      if (buffer != null) {
-        totalDoneBytes += bytesWrittenToCurrentBuffer();
-        // Update the indices on the netty buffer.
-        buffer.position(pos + 1);
-        buffer = null;
-        pos = 0;
-        limitMinusOne = 0;
-      }
-    }
-
-    @Override
-    public void writeUInt32(int fieldNumber, int value) {
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeVarint32(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeInt32(int fieldNumber, int value) {
-      requireSpace(MAX_VARINT32_SIZE + MAX_VARINT64_SIZE);
-      writeInt32(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeSInt32(int fieldNumber, int value) {
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeSInt32(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeFixed32(int fieldNumber, int value) {
-      requireSpace(MAX_VARINT32_SIZE + FIXED32_SIZE);
-      writeFixed32(value);
-      writeTag(fieldNumber, WIRETYPE_FIXED32);
-    }
-
-    @Override
-    public void writeUInt64(int fieldNumber, long value) {
-      requireSpace(MAX_VARINT32_SIZE + MAX_VARINT64_SIZE);
-      writeVarint64(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeSInt64(int fieldNumber, long value) {
-      requireSpace(MAX_VARINT32_SIZE + MAX_VARINT64_SIZE);
-      writeSInt64(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeFixed64(int fieldNumber, long value) {
-      requireSpace(MAX_VARINT32_SIZE + FIXED64_SIZE);
-      writeFixed64(value);
-      writeTag(fieldNumber, WIRETYPE_FIXED64);
-    }
-
-    @Override
-    public void writeBool(int fieldNumber, boolean value) {
-      requireSpace(MAX_VARINT32_SIZE + 1);
-      write((byte) (value ? 1 : 0));
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeString(int fieldNumber, String value) {
-      int prevBytes = getTotalBytesWritten();
-      writeString(value);
-      int length = getTotalBytesWritten() - prevBytes;
-      requireSpace(2 * MAX_VARINT32_SIZE);
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    }
-
-    @Override
-    public void writeBytes(int fieldNumber, ByteString value) {
-      try {
-        value.writeToReverse(this);
-      } catch (IOException e) {
-        // Should never happen since the writer does not throw.
-        throw new RuntimeException(e);
-      }
-
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeVarint32(value.size());
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    }
-
-    @Override
-    public void writeMessage(int fieldNumber, Object value) throws IOException {
-      int prevBytes = getTotalBytesWritten();
-      Protobuf.getInstance().writeTo(value, this);
-      int length = getTotalBytesWritten() - prevBytes;
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    }
-
-    @Override
-    public void writeMessage(int fieldNumber, Object value, Schema schema) throws IOException {
-      int prevBytes = getTotalBytesWritten();
-      schema.writeTo(value, this);
-      int length = getTotalBytesWritten() - prevBytes;
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    }
-
-    @Override
-    public void writeGroup(int fieldNumber, Object value) throws IOException {
-      writeTag(fieldNumber, WIRETYPE_END_GROUP);
-      Protobuf.getInstance().writeTo(value, this);
-      writeTag(fieldNumber, WIRETYPE_START_GROUP);
-    }
-
-    @Override
-    public void writeGroup(int fieldNumber, Object value, Schema schema) throws IOException {
-      writeTag(fieldNumber, WIRETYPE_END_GROUP);
-      schema.writeTo(value, this);
-      writeTag(fieldNumber, WIRETYPE_START_GROUP);
-    }
-
-    @Override
-    public void writeStartGroup(int fieldNumber) {
-      writeTag(fieldNumber, WIRETYPE_START_GROUP);
-    }
-
-    @Override
-    public void writeEndGroup(int fieldNumber) {
-      writeTag(fieldNumber, WIRETYPE_END_GROUP);
-    }
-
-    @Override
-    void writeInt32(int value) {
-      if (value >= 0) {
-        writeVarint32(value);
-      } else {
-        writeVarint64(value);
-      }
-    }
-
-    @Override
-    void writeSInt32(int value) {
-      writeVarint32(CodedOutputStream.encodeZigZag32(value));
-    }
-
-    @Override
-    void writeSInt64(long value) {
-      writeVarint64(CodedOutputStream.encodeZigZag64(value));
-    }
-
-    @Override
-    void writeBool(boolean value) {
-      write((byte) (value ? 1 : 0));
-    }
-
-    @Override
-    void writeTag(int fieldNumber, int wireType) {
-      writeVarint32(WireFormat.makeTag(fieldNumber, wireType));
-    }
-
-    @Override
-    void writeVarint32(int value) {
-      if ((value & (~0 << 7)) == 0) {
-        writeVarint32OneByte(value);
-      } else if ((value & (~0 << 14)) == 0) {
-        writeVarint32TwoBytes(value);
-      } else if ((value & (~0 << 21)) == 0) {
-        writeVarint32ThreeBytes(value);
-      } else if ((value & (~0 << 28)) == 0) {
-        writeVarint32FourBytes(value);
-      } else {
-        writeVarint32FiveBytes(value);
-      }
-    }
-
-    private void writeVarint32OneByte(int value) {
-      buffer.put(pos--, (byte) value);
-    }
-
-    private void writeVarint32TwoBytes(int value) {
-      // Byte order is little-endian.
-      pos -= 2;
-      buffer.putShort(pos + 1, (short) (((value & (0x7F << 7)) << 1) | ((value & 0x7F) | 0x80)));
-    }
-
-    private void writeVarint32ThreeBytes(int value) {
-      // Byte order is little-endian.
-      pos -= 3;
-      buffer.putInt(
-          pos,
-          ((value & (0x7F << 14)) << 10)
-              | (((value & (0x7F << 7)) | (0x80 << 7)) << 9)
-              | ((value & 0x7F) | 0x80) << 8);
-    }
-
-    private void writeVarint32FourBytes(int value) {
-      // Byte order is little-endian.
-      pos -= 4;
-      buffer.putInt(
-          pos + 1,
-          ((value & (0x7F << 21)) << 3)
-              | (((value & (0x7F << 14)) | (0x80 << 14)) << 2)
-              | (((value & (0x7F << 7)) | (0x80 << 7)) << 1)
-              | ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint32FiveBytes(int value) {
-      // Byte order is little-endian.
-      buffer.put(pos--, (byte) (value >>> 28));
-      pos -= 4;
-      buffer.putInt(
-          pos + 1,
-          ((((value >>> 21) & 0x7F) | 0x80) << 24)
-              | ((((value >>> 14) & 0x7F) | 0x80) << 16)
-              | ((((value >>> 7) & 0x7F) | 0x80) << 8)
-              | ((value & 0x7F) | 0x80));
-    }
-
-    @Override
-    void writeVarint64(long value) {
-      switch (computeUInt64SizeNoTag(value)) {
-        case 1:
-          writeVarint64OneByte(value);
-          break;
-        case 2:
-          writeVarint64TwoBytes(value);
-          break;
-        case 3:
-          writeVarint64ThreeBytes(value);
-          break;
-        case 4:
-          writeVarint64FourBytes(value);
-          break;
-        case 5:
-          writeVarint64FiveBytes(value);
-          break;
-        case 6:
-          writeVarint64SixBytes(value);
-          break;
-        case 7:
-          writeVarint64SevenBytes(value);
-          break;
-        case 8:
-          writeVarint64EightBytes(value);
-          break;
-        case 9:
-          writeVarint64NineBytes(value);
-          break;
-        case 10:
-          writeVarint64TenBytes(value);
-          break;
-      }
-    }
-
-    private void writeVarint64OneByte(long value) {
-      writeVarint32OneByte((int) value);
-    }
-
-    private void writeVarint64TwoBytes(long value) {
-      writeVarint32TwoBytes((int) value);
-    }
-
-    private void writeVarint64ThreeBytes(long value) {
-      writeVarint32ThreeBytes((int) value);
-    }
-
-    private void writeVarint64FourBytes(long value) {
-      writeVarint32FourBytes((int) value);
-    }
-
-    private void writeVarint64FiveBytes(long value) {
-      // Byte order is little-endian.
-      pos -= 5;
-      buffer.putLong(
-          pos - 2,
-          ((value & (0x7FL << 28)) << 28)
-              | (((value & (0x7F << 21)) | (0x80 << 21)) << 27)
-              | (((value & (0x7F << 14)) | (0x80 << 14)) << 26)
-              | (((value & (0x7F << 7)) | (0x80 << 7)) << 25)
-              | (((value & 0x7F) | 0x80)) << 24);
-    }
-
-    private void writeVarint64SixBytes(long value) {
-      // Byte order is little-endian.
-      pos -= 6;
-      buffer.putLong(
-          pos - 1,
-          ((value & (0x7FL << 35)) << 21)
-              | (((value & (0x7FL << 28)) | (0x80L << 28)) << 20)
-              | (((value & (0x7F << 21)) | (0x80 << 21)) << 19)
-              | (((value & (0x7F << 14)) | (0x80 << 14)) << 18)
-              | (((value & (0x7F << 7)) | (0x80 << 7)) << 17)
-              | (((value & 0x7F) | 0x80)) << 16);
-    }
-
-    private void writeVarint64SevenBytes(long value) {
-      // Byte order is little-endian.
-      pos -= 7;
-      buffer.putLong(
-          pos,
-          ((value & (0x7FL << 42)) << 14)
-              | (((value & (0x7FL << 35)) | (0x80L << 35)) << 13)
-              | (((value & (0x7FL << 28)) | (0x80L << 28)) << 12)
-              | (((value & (0x7F << 21)) | (0x80 << 21)) << 11)
-              | (((value & (0x7F << 14)) | (0x80 << 14)) << 10)
-              | (((value & (0x7F << 7)) | (0x80 << 7)) << 9)
-              | (((value & 0x7F) | 0x80)) << 8);
-    }
-
-    private void writeVarint64EightBytes(long value) {
-      // Byte order is little-endian.
-      pos -= 8;
-      buffer.putLong(
-          pos + 1,
-          ((value & (0x7FL << 49)) << 7)
-              | (((value & (0x7FL << 42)) | (0x80L << 42)) << 6)
-              | (((value & (0x7FL << 35)) | (0x80L << 35)) << 5)
-              | (((value & (0x7FL << 28)) | (0x80L << 28)) << 4)
-              | (((value & (0x7F << 21)) | (0x80 << 21)) << 3)
-              | (((value & (0x7F << 14)) | (0x80 << 14)) << 2)
-              | (((value & (0x7F << 7)) | (0x80 << 7)) << 1)
-              | ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint64EightBytesWithSign(long value) {
-      // Byte order is little-endian.
-      pos -= 8;
-      buffer.putLong(
-          pos + 1,
-          (((value & (0x7FL << 49)) | (0x80L << 49)) << 7)
-              | (((value & (0x7FL << 42)) | (0x80L << 42)) << 6)
-              | (((value & (0x7FL << 35)) | (0x80L << 35)) << 5)
-              | (((value & (0x7FL << 28)) | (0x80L << 28)) << 4)
-              | (((value & (0x7F << 21)) | (0x80 << 21)) << 3)
-              | (((value & (0x7F << 14)) | (0x80 << 14)) << 2)
-              | (((value & (0x7F << 7)) | (0x80 << 7)) << 1)
-              | ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint64NineBytes(long value) {
-      buffer.put(pos--, (byte) (value >>> 56));
-      writeVarint64EightBytesWithSign(value & 0xFFFFFFFFFFFFFFL);
-    }
-
-    private void writeVarint64TenBytes(long value) {
-      buffer.put(pos--, (byte) (value >>> 63));
-      buffer.put(pos--, (byte) (((value >>> 56) & 0x7F) | 0x80));
-      writeVarint64EightBytesWithSign(value & 0xFFFFFFFFFFFFFFL);
-    }
-
-    @Override
-    void writeFixed32(int value) {
-      pos -= 4;
-      buffer.putInt(pos + 1, value);
-    }
-
-    @Override
-    void writeFixed64(long value) {
-      pos -= 8;
-      buffer.putLong(pos + 1, value);
-    }
-
-    @Override
-    void writeString(String in) {
-      // Request enough space to write the ASCII string.
-      requireSpace(in.length());
-
-      // We know the buffer is big enough...
-      int i = in.length() - 1;
-      pos -= i;
-      // Designed to take advantage of
-      // https://wiki.openjdk.java.net/display/HotSpotInternals/RangeCheckElimination
-      for (char c; i >= 0 && (c = in.charAt(i)) < 0x80; i--) {
-        buffer.put(pos + i, (byte) c);
-      }
-      if (i == -1) {
-        // Move the position past the ASCII string.
-        pos -= 1;
-        return;
-      }
-      pos += i;
-      for (char c; i >= 0; i--) {
-        c = in.charAt(i);
-        if (c < 0x80 && pos >= 0) {
-          buffer.put(pos--, (byte) c);
-        } else if (c < 0x800 && pos > 0) { // 11 bits, two UTF-8 bytes
-          buffer.put(pos--, (byte) (0x80 | (0x3F & c)));
-          buffer.put(pos--, (byte) ((0xF << 6) | (c >>> 6)));
-        } else if ((c < Character.MIN_SURROGATE || Character.MAX_SURROGATE < c) && pos > 1) {
-          // Maximum single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
-          buffer.put(pos--, (byte) (0x80 | (0x3F & c)));
-          buffer.put(pos--, (byte) (0x80 | (0x3F & (c >>> 6))));
-          buffer.put(pos--, (byte) ((0xF << 5) | (c >>> 12)));
-        } else if (pos > 2) {
-          // Minimum code point represented by a surrogate pair is 0x10000, 17 bits,
-          // four UTF-8 bytes
-          char high = 0;
-          if (i == 0 || !Character.isSurrogatePair(high = in.charAt(i - 1), c)) {
-            throw new Utf8.UnpairedSurrogateException(i - 1, i);
-          }
-          i--;
-          int codePoint = Character.toCodePoint(high, c);
-          buffer.put(pos--, (byte) (0x80 | (0x3F & codePoint)));
-          buffer.put(pos--, (byte) (0x80 | (0x3F & (codePoint >>> 6))));
-          buffer.put(pos--, (byte) (0x80 | (0x3F & (codePoint >>> 12))));
-          buffer.put(pos--, (byte) ((0xF << 4) | (codePoint >>> 18)));
-        } else {
-          // Buffer is full - allocate a new one and revisit the current character.
-          requireSpace(i);
-          i++;
-        }
-      }
-    }
-
-    @Override
-    public void write(byte value) {
-      buffer.put(pos--, value);
-    }
-
-    @Override
-    public void write(byte[] value, int offset, int length) {
-      if (spaceLeft() < length) {
-        nextBuffer(length);
-      }
-
-      pos -= length;
-      buffer.position(pos + 1);
-      buffer.put(value, offset, length);
-    }
-
-    @Override
-    public void writeLazy(byte[] value, int offset, int length) {
-      if (spaceLeft() < length) {
-        // We consider the value to be immutable (likely the internals of a ByteString). Just
-        // wrap it in a Netty buffer and add it to the output buffer.
-        totalDoneBytes += length;
-        buffers.addFirst(AllocatedBuffer.wrap(value, offset, length));
-
-        // Advance the writer to the next buffer.
-        // TODO(nathanmittler): Consider slicing if space available above some threshold.
-        nextBuffer();
-        return;
-      }
-
-      pos -= length;
-      buffer.position(pos + 1);
-      buffer.put(value, offset, length);
-    }
-
-    @Override
-    public void write(ByteBuffer value) {
-      int length = value.remaining();
-      if (spaceLeft() < length) {
-        nextBuffer(length);
-      }
-
-      pos -= length;
-      buffer.position(pos + 1);
-      buffer.put(value);
-    }
-
-    @Override
-    public void writeLazy(ByteBuffer value) {
-      int length = value.remaining();
-      if (spaceLeft() < length) {
-        // We consider the value to be immutable (likely the internals of a ByteString). Just
-        // wrap it in a Netty buffer and add it to the output buffer.
-        totalDoneBytes += length;
-        buffers.addFirst(AllocatedBuffer.wrap(value));
-
-        // Advance the writer to the next buffer.
-        // TODO(nathanmittler): Consider slicing if space available above some threshold.
-        nextBuffer();
-        return;
-      }
-
-      pos -= length;
-      buffer.position(pos + 1);
-      buffer.put(value);
-    }
-
-    @Override
-    void requireSpace(int size) {
-      if (spaceLeft() < size) {
-        nextBuffer(size);
-      }
-    }
-  }
-
-  /** Writer that uses unsafe operations on a target {@link ByteBuffer}. */
-  private static final class UnsafeDirectWriter extends BinaryWriter {
-    private ByteBuffer buffer;
-    private long bufferOffset;
-    private long limitMinusOne;
-    private long pos;
-
-    UnsafeDirectWriter(BufferAllocator alloc, int chunkSize) {
-      super(alloc, chunkSize);
-      nextBuffer();
-    }
-
-    /** Indicates whether the required unsafe operations are supported on this platform. */
-    private static boolean isSupported() {
-      return UnsafeUtil.hasUnsafeByteBufferOperations();
-    }
-
-    private void nextBuffer() {
-      nextBuffer(newDirectBuffer());
-    }
-
-    private void nextBuffer(int capacity) {
-      nextBuffer(newDirectBuffer(capacity));
-    }
-
-    private void nextBuffer(AllocatedBuffer allocatedBuffer) {
-      if (!allocatedBuffer.hasNioBuffer()) {
-        throw new RuntimeException("Allocated buffer does not have NIO buffer");
-      }
-      ByteBuffer nioBuffer = allocatedBuffer.nioBuffer();
-      if (!nioBuffer.isDirect()) {
-        throw new RuntimeException("Allocator returned non-direct buffer");
-      }
-
-      finishCurrentBuffer();
-      buffers.addFirst(allocatedBuffer);
-
-      buffer = nioBuffer;
-      buffer.limit(buffer.capacity());
-      buffer.position(0);
-
-      bufferOffset = UnsafeUtil.addressOffset(buffer);
-      limitMinusOne = bufferOffset + (buffer.limit() - 1);
-      pos = limitMinusOne;
-    }
-
-    @Override
-    public int getTotalBytesWritten() {
-      return totalDoneBytes + bytesWrittenToCurrentBuffer();
-    }
-
-    private int bytesWrittenToCurrentBuffer() {
-      return (int) (limitMinusOne - pos);
-    }
-
-    private int spaceLeft() {
-      return bufferPos() + 1;
-    }
-
-    @Override
-    void finishCurrentBuffer() {
-      if (buffer != null) {
-        totalDoneBytes += bytesWrittenToCurrentBuffer();
-        // Update the indices on the netty buffer.
-        buffer.position(bufferPos() + 1);
-        buffer = null;
-        pos = 0;
-        limitMinusOne = 0;
-      }
-    }
-
-    private int bufferPos() {
-      return (int) (pos - bufferOffset);
-    }
-
-    @Override
-    public void writeUInt32(int fieldNumber, int value) {
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeVarint32(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeInt32(int fieldNumber, int value) {
-      requireSpace(MAX_VARINT32_SIZE + MAX_VARINT64_SIZE);
-      writeInt32(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeSInt32(int fieldNumber, int value) {
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeSInt32(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeFixed32(int fieldNumber, int value) {
-      requireSpace(MAX_VARINT32_SIZE + FIXED32_SIZE);
-      writeFixed32(value);
-      writeTag(fieldNumber, WIRETYPE_FIXED32);
-    }
-
-    @Override
-    public void writeUInt64(int fieldNumber, long value) {
-      requireSpace(MAX_VARINT32_SIZE + MAX_VARINT64_SIZE);
-      writeVarint64(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeSInt64(int fieldNumber, long value) {
-      requireSpace(MAX_VARINT32_SIZE + MAX_VARINT64_SIZE);
-      writeSInt64(value);
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeFixed64(int fieldNumber, long value) {
-      requireSpace(MAX_VARINT32_SIZE + FIXED64_SIZE);
-      writeFixed64(value);
-      writeTag(fieldNumber, WIRETYPE_FIXED64);
-    }
-
-    @Override
-    public void writeBool(int fieldNumber, boolean value) {
-      requireSpace(MAX_VARINT32_SIZE + 1);
-      write((byte) (value ? 1 : 0));
-      writeTag(fieldNumber, WIRETYPE_VARINT);
-    }
-
-    @Override
-    public void writeString(int fieldNumber, String value) {
-      int prevBytes = getTotalBytesWritten();
-      writeString(value);
-      int length = getTotalBytesWritten() - prevBytes;
-      requireSpace(2 * MAX_VARINT32_SIZE);
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    }
-
-    @Override
-    public void writeBytes(int fieldNumber, ByteString value) {
-      try {
-        value.writeToReverse(this);
-      } catch (IOException e) {
-        // Should never happen since the writer does not throw.
-        throw new RuntimeException(e);
-      }
-
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeVarint32(value.size());
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    }
-
-    @Override
-    public void writeMessage(int fieldNumber, Object value) throws IOException {
-      int prevBytes = getTotalBytesWritten();
-      Protobuf.getInstance().writeTo(value, this);
-      int length = getTotalBytesWritten() - prevBytes;
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    }
-
-    @Override
-    public void writeMessage(int fieldNumber, Object value, Schema schema) throws IOException {
-      int prevBytes = getTotalBytesWritten();
-      schema.writeTo(value, this);
-      int length = getTotalBytesWritten() - prevBytes;
-      requireSpace(MAX_VARINT32_SIZE * 2);
-      writeVarint32(length);
-      writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    }
-
-    @Override
-    public void writeGroup(int fieldNumber, Object value) throws IOException {
-      writeTag(fieldNumber, WIRETYPE_END_GROUP);
-      Protobuf.getInstance().writeTo(value, this);
-      writeTag(fieldNumber, WIRETYPE_START_GROUP);
-    }
-
-    @Override
-    public void writeGroup(int fieldNumber, Object value, Schema schema) throws IOException {
-      writeTag(fieldNumber, WIRETYPE_END_GROUP);
-      schema.writeTo(value, this);
-      writeTag(fieldNumber, WIRETYPE_START_GROUP);
-    }
-
-    @Override
-    public void writeStartGroup(int fieldNumber) {
-      writeTag(fieldNumber, WIRETYPE_START_GROUP);
-    }
-
-    @Override
-    public void writeEndGroup(int fieldNumber) {
-      writeTag(fieldNumber, WIRETYPE_END_GROUP);
-    }
-
-    @Override
-    void writeInt32(int value) {
-      if (value >= 0) {
-        writeVarint32(value);
-      } else {
-        writeVarint64(value);
-      }
-    }
-
-    @Override
-    void writeSInt32(int value) {
-      writeVarint32(CodedOutputStream.encodeZigZag32(value));
-    }
-
-    @Override
-    void writeSInt64(long value) {
-      writeVarint64(CodedOutputStream.encodeZigZag64(value));
-    }
-
-    @Override
-    void writeBool(boolean value) {
-      write((byte) (value ? 1 : 0));
-    }
-
-    @Override
-    void writeTag(int fieldNumber, int wireType) {
-      writeVarint32(WireFormat.makeTag(fieldNumber, wireType));
-    }
-
-    @Override
-    void writeVarint32(int value) {
-      if ((value & (~0 << 7)) == 0) {
-        writeVarint32OneByte(value);
-      } else if ((value & (~0 << 14)) == 0) {
-        writeVarint32TwoBytes(value);
-      } else if ((value & (~0 << 21)) == 0) {
-        writeVarint32ThreeBytes(value);
-      } else if ((value & (~0 << 28)) == 0) {
-        writeVarint32FourBytes(value);
-      } else {
-        writeVarint32FiveBytes(value);
-      }
-    }
-
-    private void writeVarint32OneByte(int value) {
-      UnsafeUtil.putByte(pos--, (byte) value);
-    }
-
-    private void writeVarint32TwoBytes(int value) {
-      UnsafeUtil.putByte(pos--, (byte) (value >>> 7));
-      UnsafeUtil.putByte(pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint32ThreeBytes(int value) {
-      UnsafeUtil.putByte(pos--, (byte) (value >>> 14));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint32FourBytes(int value) {
-      UnsafeUtil.putByte(pos--, (byte) (value >>> 21));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 14) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint32FiveBytes(int value) {
-      UnsafeUtil.putByte(pos--, (byte) (value >>> 28));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 21) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 14) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    @Override
-    void writeVarint64(long value) {
-      switch (computeUInt64SizeNoTag(value)) {
-        case 1:
-          writeVarint64OneByte(value);
-          break;
-        case 2:
-          writeVarint64TwoBytes(value);
-          break;
-        case 3:
-          writeVarint64ThreeBytes(value);
-          break;
-        case 4:
-          writeVarint64FourBytes(value);
-          break;
-        case 5:
-          writeVarint64FiveBytes(value);
-          break;
-        case 6:
-          writeVarint64SixBytes(value);
-          break;
-        case 7:
-          writeVarint64SevenBytes(value);
-          break;
-        case 8:
-          writeVarint64EightBytes(value);
-          break;
-        case 9:
-          writeVarint64NineBytes(value);
-          break;
-        case 10:
-          writeVarint64TenBytes(value);
-          break;
-      }
-    }
-
-    private void writeVarint64OneByte(long value) {
-      UnsafeUtil.putByte(pos--, (byte) value);
-    }
-
-    private void writeVarint64TwoBytes(long value) {
-      UnsafeUtil.putByte(pos--, (byte) (value >>> 7));
-      UnsafeUtil.putByte(pos--, (byte) (((int) value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint64ThreeBytes(long value) {
-      UnsafeUtil.putByte(pos--, (byte) (((int) value) >>> 14));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint64FourBytes(long value) {
-      UnsafeUtil.putByte(pos--, (byte) (value >>> 21));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 14) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint64FiveBytes(long value) {
-      UnsafeUtil.putByte(pos--, (byte) (value >>> 28));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 21) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 14) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint64SixBytes(long value) {
-      UnsafeUtil.putByte(pos--, (byte) (value >>> 35));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 28) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 21) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 14) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint64SevenBytes(long value) {
-      UnsafeUtil.putByte(pos--, (byte) (value >>> 42));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 35) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 28) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 21) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 14) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint64EightBytes(long value) {
-      UnsafeUtil.putByte(pos--, (byte) (value >>> 49));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 42) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 35) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 28) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 21) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 14) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint64NineBytes(long value) {
-      UnsafeUtil.putByte(pos--, (byte) (value >>> 56));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 49) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 42) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 35) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 28) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 21) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 14) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    private void writeVarint64TenBytes(long value) {
-      UnsafeUtil.putByte(pos--, (byte) (value >>> 63));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 56) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 49) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 42) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 35) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 28) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 21) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 14) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) (((value >>> 7) & 0x7F) | 0x80));
-      UnsafeUtil.putByte(pos--, (byte) ((value & 0x7F) | 0x80));
-    }
-
-    @Override
-    void writeFixed32(int value) {
-      UnsafeUtil.putByte(pos--, (byte) ((value >> 24) & 0xFF));
-      UnsafeUtil.putByte(pos--, (byte) ((value >> 16) & 0xFF));
-      UnsafeUtil.putByte(pos--, (byte) ((value >> 8) & 0xFF));
-      UnsafeUtil.putByte(pos--, (byte) (value & 0xFF));
-    }
-
-    @Override
-    void writeFixed64(long value) {
-      UnsafeUtil.putByte(pos--, (byte) ((int) (value >> 56) & 0xFF));
-      UnsafeUtil.putByte(pos--, (byte) ((int) (value >> 48) & 0xFF));
-      UnsafeUtil.putByte(pos--, (byte) ((int) (value >> 40) & 0xFF));
-      UnsafeUtil.putByte(pos--, (byte) ((int) (value >> 32) & 0xFF));
-      UnsafeUtil.putByte(pos--, (byte) ((int) (value >> 24) & 0xFF));
-      UnsafeUtil.putByte(pos--, (byte) ((int) (value >> 16) & 0xFF));
-      UnsafeUtil.putByte(pos--, (byte) ((int) (value >> 8) & 0xFF));
-      UnsafeUtil.putByte(pos--, (byte) ((int) (value) & 0xFF));
-    }
-
-    @Override
-    void writeString(String in) {
-      // Request enough space to write the ASCII string.
-      requireSpace(in.length());
-
-      // We know the buffer is big enough...
-      int i = in.length() - 1;
-      // Designed to take advantage of
-      // https://wiki.openjdk.java.net/display/HotSpotInternals/RangeCheckElimination
-      for (char c; i >= 0 && (c = in.charAt(i)) < 0x80; i--) {
-        UnsafeUtil.putByte(pos--, (byte) c);
-      }
-      if (i == -1) {
-        // ASCII.
-        return;
-      }
-      for (char c; i >= 0; i--) {
-        c = in.charAt(i);
-        if (c < 0x80 && pos >= bufferOffset) {
-          UnsafeUtil.putByte(pos--, (byte) c);
-        } else if (c < 0x800 && pos > bufferOffset) { // 11 bits, two UTF-8 bytes
-          UnsafeUtil.putByte(pos--, (byte) (0x80 | (0x3F & c)));
-          UnsafeUtil.putByte(pos--, (byte) ((0xF << 6) | (c >>> 6)));
-        } else if ((c < Character.MIN_SURROGATE || Character.MAX_SURROGATE < c)
-            && pos > bufferOffset + 1) {
-          // Maximum single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
-          UnsafeUtil.putByte(pos--, (byte) (0x80 | (0x3F & c)));
-          UnsafeUtil.putByte(pos--, (byte) (0x80 | (0x3F & (c >>> 6))));
-          UnsafeUtil.putByte(pos--, (byte) ((0xF << 5) | (c >>> 12)));
-        } else if (pos > bufferOffset + 2) {
-          // Minimum code point represented by a surrogate pair is 0x10000, 17 bits,
-          // four UTF-8 bytes
-          final char high;
-          if (i == 0 || !Character.isSurrogatePair(high = in.charAt(i - 1), c)) {
-            throw new Utf8.UnpairedSurrogateException(i - 1, i);
-          }
-          i--;
-          int codePoint = Character.toCodePoint(high, c);
-          UnsafeUtil.putByte(pos--, (byte) (0x80 | (0x3F & codePoint)));
-          UnsafeUtil.putByte(pos--, (byte) (0x80 | (0x3F & (codePoint >>> 6))));
-          UnsafeUtil.putByte(pos--, (byte) (0x80 | (0x3F & (codePoint >>> 12))));
-          UnsafeUtil.putByte(pos--, (byte) ((0xF << 4) | (codePoint >>> 18)));
-        } else {
-          // Buffer is full - allocate a new one and revisit the current character.
-          requireSpace(i);
-          i++;
-        }
-      }
-    }
-
-    @Override
-    public void write(byte value) {
-      UnsafeUtil.putByte(pos--, value);
-    }
-
-    @Override
-    public void write(byte[] value, int offset, int length) {
-      if (spaceLeft() < length) {
-        nextBuffer(length);
-      }
-
-      pos -= length;
-      buffer.position(bufferPos() + 1);
-      buffer.put(value, offset, length);
-    }
-
-    @Override
-    public void writeLazy(byte[] value, int offset, int length) {
-      if (spaceLeft() < length) {
-        // We consider the value to be immutable (likely the internals of a ByteString). Just
-        // wrap it in a Netty buffer and add it to the output buffer.
-        totalDoneBytes += length;
-        buffers.addFirst(AllocatedBuffer.wrap(value, offset, length));
-
-        // Advance the writer to the next buffer.
-        // TODO(nathanmittler): Consider slicing if space available above some threshold.
-        nextBuffer();
-        return;
-      }
-
-      pos -= length;
-      buffer.position(bufferPos() + 1);
-      buffer.put(value, offset, length);
-    }
-
-    @Override
-    public void write(ByteBuffer value) {
-      int length = value.remaining();
-      if (spaceLeft() < length) {
-        nextBuffer(length);
-      }
-
-      pos -= length;
-      buffer.position(bufferPos() + 1);
-      buffer.put(value);
-    }
-
-    @Override
-    public void writeLazy(ByteBuffer value) {
-      int length = value.remaining();
-      if (spaceLeft() < length) {
-        // We consider the value to be immutable (likely the internals of a ByteString). Just
-        // wrap it in a Netty buffer and add it to the output buffer.
-        totalDoneBytes += length;
-        buffers.addFirst(AllocatedBuffer.wrap(value));
-
-        // Advance the writer to the next buffer.
-        // TODO(nathanmittler): Consider slicing if space available above some threshold.
-        nextBuffer();
-        return;
-      }
-
-      pos -= length;
-      buffer.position(bufferPos() + 1);
-      buffer.put(value);
-    }
-
-    @Override
-    void requireSpace(int size) {
-      if (spaceLeft() < size) {
-        nextBuffer(size);
-      }
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/BoolValue.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/BoolValue.java
deleted file mode 100644
index 280f56e..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/BoolValue.java
+++ /dev/null
@@ -1,276 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/wrappers.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * Wrapper message for `bool`.
- * The JSON representation for `BoolValue` is JSON `true` and `false`.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.BoolValue}
- */
-public  final class BoolValue extends
-    com.google.protobuf.GeneratedMessageLite<
-        BoolValue, BoolValue.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.BoolValue)
-    BoolValueOrBuilder {
-  private BoolValue() {
-  }
-  public static final int VALUE_FIELD_NUMBER = 1;
-  private boolean value_;
-  /**
-   * <pre>
-   * The bool value.
-   * </pre>
-   *
-   * <code>bool value = 1;</code>
-   * @return The value.
-   */
-  @java.lang.Override
-  public boolean getValue() {
-    return value_;
-  }
-  /**
-   * <pre>
-   * The bool value.
-   * </pre>
-   *
-   * <code>bool value = 1;</code>
-   * @param value The value to set.
-   */
-  private void setValue(boolean value) {
-    
-    value_ = value;
-  }
-  /**
-   * <pre>
-   * The bool value.
-   * </pre>
-   *
-   * <code>bool value = 1;</code>
-   */
-  private void clearValue() {
-    
-    value_ = false;
-  }
-
-  public static com.google.protobuf.BoolValue parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.BoolValue parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.BoolValue parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.BoolValue parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.BoolValue parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.BoolValue parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.BoolValue parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.BoolValue parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.BoolValue parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.BoolValue parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.BoolValue parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.BoolValue parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.BoolValue prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * Wrapper message for `bool`.
-   * The JSON representation for `BoolValue` is JSON `true` and `false`.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.BoolValue}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.BoolValue, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.BoolValue)
-      com.google.protobuf.BoolValueOrBuilder {
-    // Construct using com.google.protobuf.BoolValue.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * The bool value.
-     * </pre>
-     *
-     * <code>bool value = 1;</code>
-     * @return The value.
-     */
-    @java.lang.Override
-    public boolean getValue() {
-      return instance.getValue();
-    }
-    /**
-     * <pre>
-     * The bool value.
-     * </pre>
-     *
-     * <code>bool value = 1;</code>
-     * @param value The value to set.
-     * @return This builder for chaining.
-     */
-    public Builder setValue(boolean value) {
-      copyOnWrite();
-      instance.setValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The bool value.
-     * </pre>
-     *
-     * <code>bool value = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearValue() {
-      copyOnWrite();
-      instance.clearValue();
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.BoolValue)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.BoolValue();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "value_",
-          };
-          java.lang.String info =
-              "\u0000\u0001\u0000\u0000\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u0007";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.BoolValue> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.BoolValue.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.BoolValue>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.BoolValue)
-  private static final com.google.protobuf.BoolValue DEFAULT_INSTANCE;
-  static {
-    BoolValue defaultInstance = new BoolValue();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      BoolValue.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.BoolValue getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  public static com.google.protobuf.BoolValue of(boolean value) {
-    return newBuilder().setValue(value).build();
-  }
-
-  private static volatile com.google.protobuf.Parser<BoolValue> PARSER;
-
-  public static com.google.protobuf.Parser<BoolValue> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/BoolValueOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/BoolValueOrBuilder.java
deleted file mode 100644
index c51d2a7..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/BoolValueOrBuilder.java
+++ /dev/null
@@ -1,19 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/wrappers.proto
-
-package com.google.protobuf;
-
-public interface BoolValueOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.BoolValue)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * The bool value.
-   * </pre>
-   *
-   * <code>bool value = 1;</code>
-   * @return The value.
-   */
-  boolean getValue();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/BooleanArrayList.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/BooleanArrayList.java
deleted file mode 100644
index 451fce1..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/BooleanArrayList.java
+++ /dev/null
@@ -1,298 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.Internal.checkNotNull;
-
-import com.google.protobuf.Internal.BooleanList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.RandomAccess;
-
-/**
- * An implementation of {@link BooleanList} on top of a primitive array.
- *
- * @author dweis@google.com (Daniel Weis)
- */
-final class BooleanArrayList extends AbstractProtobufList<Boolean>
-    implements BooleanList, RandomAccess, PrimitiveNonBoxingCollection {
-
-  private static final BooleanArrayList EMPTY_LIST = new BooleanArrayList(new boolean[0], 0);
-  static {
-    EMPTY_LIST.makeImmutable();
-  }
-
-  public static BooleanArrayList emptyList() {
-    return EMPTY_LIST;
-  }
-
-  /** The backing store for the list. */
-  private boolean[] array;
-
-  /**
-   * The size of the list distinct from the length of the array. That is, it is the number of
-   * elements set in the list.
-   */
-  private int size;
-
-  /** Constructs a new mutable {@code BooleanArrayList} with default capacity. */
-  BooleanArrayList() {
-    this(new boolean[DEFAULT_CAPACITY], 0);
-  }
-
-  /**
-   * Constructs a new mutable {@code BooleanArrayList} containing the same elements as {@code
-   * other}.
-   */
-  private BooleanArrayList(boolean[] other, int size) {
-    array = other;
-    this.size = size;
-  }
-
-  @Override
-  protected void removeRange(int fromIndex, int toIndex) {
-    ensureIsMutable();
-    if (toIndex < fromIndex) {
-      throw new IndexOutOfBoundsException("toIndex < fromIndex");
-    }
-
-    System.arraycopy(array, toIndex, array, fromIndex, size - toIndex);
-    size -= (toIndex - fromIndex);
-    modCount++;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (!(o instanceof BooleanArrayList)) {
-      return super.equals(o);
-    }
-    BooleanArrayList other = (BooleanArrayList) o;
-    if (size != other.size) {
-      return false;
-    }
-
-    final boolean[] arr = other.array;
-    for (int i = 0; i < size; i++) {
-      if (array[i] != arr[i]) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = 1;
-    for (int i = 0; i < size; i++) {
-      result = (31 * result) + Internal.hashBoolean(array[i]);
-    }
-    return result;
-  }
-
-  @Override
-  public BooleanList mutableCopyWithCapacity(int capacity) {
-    if (capacity < size) {
-      throw new IllegalArgumentException();
-    }
-    return new BooleanArrayList(Arrays.copyOf(array, capacity), size);
-  }
-
-  @Override
-  public Boolean get(int index) {
-    return getBoolean(index);
-  }
-
-  @Override
-  public boolean getBoolean(int index) {
-    ensureIndexInRange(index);
-    return array[index];
-  }
-
-  @Override
-  public int indexOf(Object element) {
-    if (!(element instanceof Boolean)) {
-      return -1;
-    }
-    boolean unboxedElement = (Boolean) element;
-    int numElems = size();
-    for (int i = 0; i < numElems; i++) {
-      if (array[i] == unboxedElement) {
-        return i;
-      }
-    }
-    return -1;
-  }
-
-  @Override
-  public boolean contains(Object element) {
-    return indexOf(element) != -1;
-  }
-
-  @Override
-  public int size() {
-    return size;
-  }
-
-  @Override
-  public Boolean set(int index, Boolean element) {
-    return setBoolean(index, element);
-  }
-
-  @Override
-  public boolean setBoolean(int index, boolean element) {
-    ensureIsMutable();
-    ensureIndexInRange(index);
-    boolean previousValue = array[index];
-    array[index] = element;
-    return previousValue;
-  }
-
-  @Override
-  public boolean add(Boolean element) {
-    addBoolean(element);
-    return true;
-  }
-
-  @Override
-  public void add(int index, Boolean element) {
-    addBoolean(index, element);
-  }
-
-  /** Like {@link #add(Boolean)} but more efficient in that it doesn't box the element. */
-  @Override
-  public void addBoolean(boolean element) {
-    ensureIsMutable();
-    if (size == array.length) {
-      // Resize to 1.5x the size
-      int length = ((size * 3) / 2) + 1;
-      boolean[] newArray = new boolean[length];
-
-      System.arraycopy(array, 0, newArray, 0, size);
-      array = newArray;
-    }
-
-    array[size++] = element;
-  }
-
-  /** Like {@link #add(int, Boolean)} but more efficient in that it doesn't box the element. */
-  private void addBoolean(int index, boolean element) {
-    ensureIsMutable();
-    if (index < 0 || index > size) {
-      throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index));
-    }
-
-    if (size < array.length) {
-      // Shift everything over to make room
-      System.arraycopy(array, index, array, index + 1, size - index);
-    } else {
-      // Resize to 1.5x the size
-      int length = ((size * 3) / 2) + 1;
-      boolean[] newArray = new boolean[length];
-
-      // Copy the first part directly
-      System.arraycopy(array, 0, newArray, 0, index);
-
-      // Copy the rest shifted over by one to make room
-      System.arraycopy(array, index, newArray, index + 1, size - index);
-      array = newArray;
-    }
-
-    array[index] = element;
-    size++;
-    modCount++;
-  }
-
-  @Override
-  public boolean addAll(Collection<? extends Boolean> collection) {
-    ensureIsMutable();
-
-    checkNotNull(collection);
-
-    // We specialize when adding another BooleanArrayList to avoid boxing elements.
-    if (!(collection instanceof BooleanArrayList)) {
-      return super.addAll(collection);
-    }
-
-    BooleanArrayList list = (BooleanArrayList) collection;
-    if (list.size == 0) {
-      return false;
-    }
-
-    int overflow = Integer.MAX_VALUE - size;
-    if (overflow < list.size) {
-      // We can't actually represent a list this large.
-      throw new OutOfMemoryError();
-    }
-
-    int newSize = size + list.size;
-    if (newSize > array.length) {
-      array = Arrays.copyOf(array, newSize);
-    }
-
-    System.arraycopy(list.array, 0, array, size, list.size);
-    size = newSize;
-    modCount++;
-    return true;
-  }
-
-  @Override
-  public Boolean remove(int index) {
-    ensureIsMutable();
-    ensureIndexInRange(index);
-    boolean value = array[index];
-    if (index < size - 1) {
-      System.arraycopy(array, index + 1, array, index, size - index - 1);
-    }
-    size--;
-    modCount++;
-    return value;
-  }
-
-  /**
-   * Ensures that the provided {@code index} is within the range of {@code [0, size]}. Throws an
-   * {@link IndexOutOfBoundsException} if it is not.
-   *
-   * @param index the index to verify is in range
-   */
-  private void ensureIndexInRange(int index) {
-    if (index < 0 || index >= size) {
-      throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index));
-    }
-  }
-
-  private String makeOutOfBoundsExceptionMessage(int index) {
-    return "Index:" + index + ", Size:" + size;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/BufferAllocator.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/BufferAllocator.java
deleted file mode 100644
index bfd9c72..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/BufferAllocator.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.nio.ByteBuffer;
-
-/**
- * An object responsible for allocation of buffers. This is an extension point to enable buffer
- * pooling within an application.
- */
-@ExperimentalApi
-abstract class BufferAllocator {
-  private static final BufferAllocator UNPOOLED =
-      new BufferAllocator() {
-        @Override
-        public AllocatedBuffer allocateHeapBuffer(int capacity) {
-          return AllocatedBuffer.wrap(new byte[capacity]);
-        }
-
-        @Override
-        public AllocatedBuffer allocateDirectBuffer(int capacity) {
-          return AllocatedBuffer.wrap(ByteBuffer.allocateDirect(capacity));
-        }
-      };
-
-  /** Returns an unpooled buffer allocator, which will create a new buffer for each request. */
-  public static BufferAllocator unpooled() {
-    return UNPOOLED;
-  }
-
-  /** Allocates a buffer with the given capacity that is backed by an array on the heap. */
-  public abstract AllocatedBuffer allocateHeapBuffer(int capacity);
-
-  /** Allocates a direct (i.e. non-heap) buffer with the given capacity. */
-  public abstract AllocatedBuffer allocateDirectBuffer(int capacity);
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ByteBufferWriter.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ByteBufferWriter.java
deleted file mode 100644
index 2cb3ada..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ByteBufferWriter.java
+++ /dev/null
@@ -1,181 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static java.lang.Math.max;
-import static java.lang.Math.min;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.lang.ref.SoftReference;
-import java.lang.reflect.Field;
-import java.nio.ByteBuffer;
-import java.nio.channels.WritableByteChannel;
-
-/** Utility class to provide efficient writing of {@link ByteBuffer}s to {@link OutputStream}s. */
-final class ByteBufferWriter {
-  private ByteBufferWriter() {}
-
-  /**
-   * Minimum size for a cached buffer. This prevents us from allocating buffers that are too small
-   * to be easily reused.
-   */
-  // TODO(nathanmittler): tune this property or allow configuration?
-  private static final int MIN_CACHED_BUFFER_SIZE = 1024;
-
-  /**
-   * Maximum size for a cached buffer. If a larger buffer is required, it will be allocated but not
-   * cached.
-   */
-  // TODO(nathanmittler): tune this property or allow configuration?
-  private static final int MAX_CACHED_BUFFER_SIZE = 16 * 1024;
-
-  /** The fraction of the requested buffer size under which the buffer will be reallocated. */
-  // TODO(nathanmittler): tune this property or allow configuration?
-  private static final float BUFFER_REALLOCATION_THRESHOLD = 0.5f;
-
-  /**
-   * Keeping a soft reference to a thread-local buffer. This buffer is used for writing a {@link
-   * ByteBuffer} to an {@link OutputStream} when no zero-copy alternative was available. Using a
-   * "soft" reference since VMs may keep this reference around longer than "weak" (e.g. HotSpot will
-   * maintain soft references until memory pressure warrants collection).
-   */
-  private static final ThreadLocal<SoftReference<byte[]>> BUFFER =
-      new ThreadLocal<SoftReference<byte[]>>();
-
-  /** This is a hack for GAE, where {@code FileOutputStream} is unavailable. */
-  private static final Class<?> FILE_OUTPUT_STREAM_CLASS = safeGetClass("java.io.FileOutputStream");
-
-  private static final long CHANNEL_FIELD_OFFSET = getChannelFieldOffset(FILE_OUTPUT_STREAM_CLASS);
-
-  /**
-   * For testing purposes only. Clears the cached buffer to force a new allocation on the next
-   * invocation.
-   */
-  static void clearCachedBuffer() {
-    BUFFER.set(null);
-  }
-
-  /**
-   * Writes the remaining content of the buffer to the given stream. The buffer {@code position}
-   * will remain unchanged by this method.
-   */
-  static void write(ByteBuffer buffer, OutputStream output) throws IOException {
-    final int initialPos = buffer.position();
-    try {
-      if (buffer.hasArray()) {
-        // Optimized write for array-backed buffers.
-        // Note that we're taking the risk that a malicious OutputStream could modify the array.
-        output.write(buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining());
-      } else if (!writeToChannel(buffer, output)) {
-        // Read all of the data from the buffer to an array.
-        // TODO(nathanmittler): Consider performance improvements for other "known" stream types.
-        final byte[] array = getOrCreateBuffer(buffer.remaining());
-        while (buffer.hasRemaining()) {
-          int length = min(buffer.remaining(), array.length);
-          buffer.get(array, 0, length);
-          output.write(array, 0, length);
-        }
-      }
-    } finally {
-      // Restore the initial position.
-      buffer.position(initialPos);
-    }
-  }
-
-  private static byte[] getOrCreateBuffer(int requestedSize) {
-    requestedSize = max(requestedSize, MIN_CACHED_BUFFER_SIZE);
-
-    byte[] buffer = getBuffer();
-    // Only allocate if we need to.
-    if (buffer == null || needToReallocate(requestedSize, buffer.length)) {
-      buffer = new byte[requestedSize];
-
-      // Only cache the buffer if it's not too big.
-      if (requestedSize <= MAX_CACHED_BUFFER_SIZE) {
-        setBuffer(buffer);
-      }
-    }
-    return buffer;
-  }
-
-  private static boolean needToReallocate(int requestedSize, int bufferLength) {
-    // First check against just the requested length to avoid the multiply.
-    return bufferLength < requestedSize
-        && bufferLength < requestedSize * BUFFER_REALLOCATION_THRESHOLD;
-  }
-
-  private static byte[] getBuffer() {
-    SoftReference<byte[]> sr = BUFFER.get();
-    return sr == null ? null : sr.get();
-  }
-
-  private static void setBuffer(byte[] value) {
-    BUFFER.set(new SoftReference<byte[]>(value));
-  }
-
-  private static boolean writeToChannel(ByteBuffer buffer, OutputStream output) throws IOException {
-    if (CHANNEL_FIELD_OFFSET >= 0 && FILE_OUTPUT_STREAM_CLASS.isInstance(output)) {
-      // Use a channel to write out the ByteBuffer. This will automatically empty the buffer.
-      WritableByteChannel channel = null;
-      try {
-        channel = (WritableByteChannel) UnsafeUtil.getObject(output, CHANNEL_FIELD_OFFSET);
-      } catch (ClassCastException e) {
-        // Absorb.
-      }
-      if (channel != null) {
-        channel.write(buffer);
-        return true;
-      }
-    }
-    return false;
-  }
-
-  private static Class<?> safeGetClass(String className) {
-    try {
-      return Class.forName(className);
-    } catch (ClassNotFoundException e) {
-      return null;
-    }
-  }
-
-  private static long getChannelFieldOffset(Class<?> clazz) {
-    try {
-      if (clazz != null && UnsafeUtil.hasUnsafeArrayOperations()) {
-        Field field = clazz.getDeclaredField("channel");
-        return UnsafeUtil.objectFieldOffset(field);
-      }
-    } catch (Throwable e) {
-      // Absorb
-    }
-    return -1;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ByteOutput.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ByteOutput.java
deleted file mode 100644
index dba7a37..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ByteOutput.java
+++ /dev/null
@@ -1,116 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * An output target for raw bytes. This interface provides semantics that support two types of
- * writing:
- *
- * <p><b>Traditional write operations:</b> (as defined by {@link java.io.OutputStream}) where the
- * target method is responsible for either copying the data or completing the write before returning
- * from the method call.
- *
- * <p><b>Lazy write operations:</b> where the caller guarantees that it will never modify the
- * provided buffer and it can therefore be considered immutable. The target method is free to
- * maintain a reference to the buffer beyond the scope of the method call (e.g. until the write
- * operation completes).
- */
-@ExperimentalApi
-public abstract class ByteOutput {
-  /**
-   * Writes a single byte.
-   *
-   * @param value the byte to be written
-   * @throws IOException thrown if an error occurred while writing
-   */
-  public abstract void write(byte value) throws IOException;
-
-  /**
-   * Writes a sequence of bytes. The {@link ByteOutput} must copy {@code value} if it will not be
-   * processed prior to the return of this method call, since {@code value} may be reused/altered by
-   * the caller.
-   *
-   * <p>NOTE: This method <strong>MUST NOT</strong> modify the {@code value}. Doing so is a
-   * programming error and will lead to data corruption which will be difficult to debug.
-   *
-   * @param value the bytes to be written
-   * @param offset the offset of the start of the writable range
-   * @param length the number of bytes to write starting from {@code offset}
-   * @throws IOException thrown if an error occurred while writing
-   */
-  public abstract void write(byte[] value, int offset, int length) throws IOException;
-
-  /**
-   * Writes a sequence of bytes. The {@link ByteOutput} is free to retain a reference to the value
-   * beyond the scope of this method call (e.g. write later) since it is considered immutable and is
-   * guaranteed not to change by the caller.
-   *
-   * <p>NOTE: This method <strong>MUST NOT</strong> modify the {@code value}. Doing so is a
-   * programming error and will lead to data corruption which will be difficult to debug.
-   *
-   * @param value the bytes to be written
-   * @param offset the offset of the start of the writable range
-   * @param length the number of bytes to write starting from {@code offset}
-   * @throws IOException thrown if an error occurred while writing
-   */
-  public abstract void writeLazy(byte[] value, int offset, int length) throws IOException;
-
-  /**
-   * Writes a sequence of bytes. The {@link ByteOutput} must copy {@code value} if it will not be
-   * processed prior to the return of this method call, since {@code value} may be reused/altered by
-   * the caller.
-   *
-   * <p>NOTE: This method <strong>MUST NOT</strong> modify the {@code value}. Doing so is a
-   * programming error and will lead to data corruption which will be difficult to debug.
-   *
-   * @param value the bytes to be written. Upon returning from this call, the {@code position} of
-   *     this buffer will be set to the {@code limit}
-   * @throws IOException thrown if an error occurred while writing
-   */
-  public abstract void write(ByteBuffer value) throws IOException;
-
-  /**
-   * Writes a sequence of bytes. The {@link ByteOutput} is free to retain a reference to the value
-   * beyond the scope of this method call (e.g. write later) since it is considered immutable and is
-   * guaranteed not to change by the caller.
-   *
-   * <p>NOTE: This method <strong>MUST NOT</strong> modify the {@code value}. Doing so is a
-   * programming error and will lead to data corruption which will be difficult to debug.
-   *
-   * @param value the bytes to be written. Upon returning from this call, the {@code position} of
-   *     this buffer will be set to the {@code limit}
-   * @throws IOException thrown if an error occurred while writing
-   */
-  public abstract void writeLazy(ByteBuffer value) throws IOException;
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ByteString.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ByteString.java
deleted file mode 100644
index 74c9a71..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ByteString.java
+++ /dev/null
@@ -1,1615 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.TextFormatEscaper.escapeBytes;
-import static java.lang.Integer.toHexString;
-import static java.lang.System.identityHashCode;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InvalidObjectException;
-import java.io.ObjectInputStream;
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.UnsupportedCharsetException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.NoSuchElementException;
-
-/**
- * Immutable sequence of bytes. Provides conversions to and from {@code byte[]}, {@link
- * java.lang.String}, {@link ByteBuffer}, {@link InputStream}, {@link OutputStream}. Also provides a
- * conversion to {@link CodedInputStream}.
- *
- * <p>Like {@link String}, the contents of a {@link ByteString} can never be observed to change, not
- * even in the presence of a data race or incorrect API usage in the client code.
- *
- * <p>Substring is supported by sharing the reference to the immutable underlying bytes.
- * Concatenation is likewise supported without copying (long strings) by building a tree of pieces
- * in {@link RopeByteString}.
- *
- * @author crazybob@google.com Bob Lee
- * @author kenton@google.com Kenton Varda
- * @author carlanton@google.com Carl Haverl
- * @author martinrb@google.com Martin Buchholz
- */
-public abstract class ByteString implements Iterable<Byte>, Serializable {
-
-  /**
-   * When two strings to be concatenated have a combined length shorter than this, we just copy
-   * their bytes on {@link #concat(ByteString)}. The trade-off is copy size versus the overhead of
-   * creating tree nodes in {@link RopeByteString}.
-   */
-  static final int CONCATENATE_BY_COPY_SIZE = 128;
-
-  /**
-   * When copying an InputStream into a ByteString with .readFrom(), the chunks in the underlying
-   * rope start at 256 bytes, but double each iteration up to 8192 bytes.
-   */
-  static final int MIN_READ_FROM_CHUNK_SIZE = 0x100; // 256b
-
-  static final int MAX_READ_FROM_CHUNK_SIZE = 0x2000; // 8k
-
-  /** Empty {@code ByteString}. */
-  public static final ByteString EMPTY = new LiteralByteString(Internal.EMPTY_BYTE_ARRAY);
-
-  /**
-   * An interface to efficiently copy {@code byte[]}.
-   *
-   * <p>One of the noticeable costs of copying a byte[] into a new array using {@code
-   * System.arraycopy} is nullification of a new buffer before the copy. It has been shown the
-   * Hotspot VM is capable to intrisicfy {@code Arrays.copyOfRange} operation to avoid this
-   * expensive nullification and provide substantial performance gain. Unfortunately this does not
-   * hold on Android runtimes and could make the copy slightly slower due to additional code in the
-   * {@code Arrays.copyOfRange}. Thus we provide two different implementation for array copier for
-   * Hotspot and Android runtimes.
-   */
-  private interface ByteArrayCopier {
-    /** Copies the specified range of the specified array into a new array */
-    byte[] copyFrom(byte[] bytes, int offset, int size);
-  }
-
-  /** Implementation of {@code ByteArrayCopier} which uses {@link System#arraycopy}. */
-  private static final class SystemByteArrayCopier implements ByteArrayCopier {
-    @Override
-    public byte[] copyFrom(byte[] bytes, int offset, int size) {
-      byte[] copy = new byte[size];
-      System.arraycopy(bytes, offset, copy, 0, size);
-      return copy;
-    }
-  }
-
-  /** Implementation of {@code ByteArrayCopier} which uses {@link Arrays#copyOfRange}. */
-  private static final class ArraysByteArrayCopier implements ByteArrayCopier {
-    @Override
-    public byte[] copyFrom(byte[] bytes, int offset, int size) {
-      return Arrays.copyOfRange(bytes, offset, offset + size);
-    }
-  }
-
-  private static final ByteArrayCopier byteArrayCopier;
-
-  static {
-    byteArrayCopier =
-        Android.isOnAndroidDevice() ? new SystemByteArrayCopier() : new ArraysByteArrayCopier();
-  }
-
-  /**
-   * Cached hash value. Intentionally accessed via a data race, which is safe because of the Java
-   * Memory Model's "no out-of-thin-air values" guarantees for ints. A value of 0 implies that the
-   * hash has not been set.
-   */
-  private int hash = 0;
-
-  // This constructor is here to prevent subclassing outside of this package,
-  ByteString() {}
-
-  /**
-   * Gets the byte at the given index. This method should be used only for random access to
-   * individual bytes. To access bytes sequentially, use the {@link ByteIterator} returned by {@link
-   * #iterator()}, and call {@link #substring(int, int)} first if necessary.
-   *
-   * @param index index of byte
-   * @return the value
-   * @throws IndexOutOfBoundsException {@code index < 0 or index >= size}
-   */
-  public abstract byte byteAt(int index);
-
-  /**
-   * Gets the byte at the given index, assumes bounds checking has already been performed.
-   *
-   * @param index index of byte
-   * @return the value
-   * @throws IndexOutOfBoundsException {@code index < 0 or index >= size}
-   */
-  abstract byte internalByteAt(int index);
-
-  /**
-   * Return a {@link ByteString.ByteIterator} over the bytes in the ByteString. To avoid
-   * auto-boxing, you may get the iterator manually and call {@link ByteIterator#nextByte()}.
-   *
-   * @return the iterator
-   */
-  @Override
-  public ByteIterator iterator() {
-    return new AbstractByteIterator() {
-      private int position = 0;
-      private final int limit = size();
-
-      @Override
-      public boolean hasNext() {
-        return position < limit;
-      }
-
-      @Override
-      public byte nextByte() {
-        int currentPos = position;
-        if (currentPos >= limit) {
-          throw new NoSuchElementException();
-        }
-        position = currentPos + 1;
-        return internalByteAt(currentPos);
-      }
-    };
-  }
-
-  /**
-   * This interface extends {@code Iterator<Byte>}, so that we can return an unboxed {@code byte}.
-   */
-  public interface ByteIterator extends Iterator<Byte> {
-    /**
-     * An alternative to {@link Iterator#next()} that returns an unboxed primitive {@code byte}.
-     *
-     * @return the next {@code byte} in the iteration
-     * @throws NoSuchElementException if the iteration has no more elements
-     */
-    byte nextByte();
-  }
-
-  abstract static class AbstractByteIterator implements ByteIterator {
-    @Override
-    public final Byte next() {
-      // Boxing calls Byte.valueOf(byte), which does not instantiate.
-      return nextByte();
-    }
-
-    @Override
-    public final void remove() {
-      throw new UnsupportedOperationException();
-    }
-  }
-
-  /**
-   * Gets the number of bytes.
-   *
-   * @return size in bytes
-   */
-  public abstract int size();
-
-  /**
-   * Returns {@code true} if the size is {@code 0}, {@code false} otherwise.
-   *
-   * @return true if this is zero bytes long
-   */
-  public final boolean isEmpty() {
-    return size() == 0;
-  }
-
-  // =================================================================
-  // Comparison
-
-  private static final int UNSIGNED_BYTE_MASK = 0xFF;
-
-  /**
-   * Returns the value of the given byte as an integer, interpreting the byte as an unsigned value.
-   * That is, returns {@code value + 256} if {@code value} is negative; {@code value} itself
-   * otherwise.
-   *
-   * <p>Note: This code was copied from {@link com.google.common.primitives.UnsignedBytes#toInt}, as
-   * Guava libraries cannot be used in the {@code com.google.protobuf} package.
-   */
-  private static int toInt(byte value) {
-    return value & UNSIGNED_BYTE_MASK;
-  }
-
-  /**
-   * Compares two {@link ByteString}s lexicographically, treating their contents as unsigned byte
-   * values between 0 and 255 (inclusive).
-   *
-   * <p>For example, {@code (byte) -1} is considered to be greater than {@code (byte) 1} because it
-   * is interpreted as an unsigned value, {@code 255}.
-   */
-  private static final Comparator<ByteString> UNSIGNED_LEXICOGRAPHICAL_COMPARATOR =
-      new Comparator<ByteString>() {
-        @Override
-        public int compare(ByteString former, ByteString latter) {
-          ByteIterator formerBytes = former.iterator();
-          ByteIterator latterBytes = latter.iterator();
-
-          while (formerBytes.hasNext() && latterBytes.hasNext()) {
-            // Note: This code was copied from com.google.common.primitives.UnsignedBytes#compare,
-            // as Guava libraries cannot be used in the {@code com.google.protobuf} package.
-            int result =
-                Integer.compare(toInt(formerBytes.nextByte()), toInt(latterBytes.nextByte()));
-            if (result != 0) {
-              return result;
-            }
-          }
-
-          return Integer.compare(former.size(), latter.size());
-        }
-      };
-
-  /**
-   * Returns a {@link Comparator} which compares {@link ByteString}-s lexicographically
-   * as sequences of unsigned bytes (i.e. values between 0 and 255, inclusive).
-   *
-   * <p>For example, {@code (byte) -1} is considered to be greater than {@code (byte) 1} because it
-   * is interpreted as an unsigned value, {@code 255}:
-   *
-   * <ul>
-   *   <li>{@code `-1` -> 0b11111111 (two's complement) -> 255}
-   *   <li>{@code `1` -> 0b00000001 -> 1}
-   * </ul>
-   */
-  public static Comparator<ByteString> unsignedLexicographicalComparator() {
-    return UNSIGNED_LEXICOGRAPHICAL_COMPARATOR;
-  }
-
-  // =================================================================
-  // ByteString -> substring
-
-  /**
-   * Return the substring from {@code beginIndex}, inclusive, to the end of the string.
-   *
-   * @param beginIndex start at this index
-   * @return substring sharing underlying data
-   * @throws IndexOutOfBoundsException if {@code beginIndex < 0} or {@code beginIndex > size()}.
-   */
-  public final ByteString substring(int beginIndex) {
-    return substring(beginIndex, size());
-  }
-
-  /**
-   * Return the substring from {@code beginIndex}, inclusive, to {@code endIndex}, exclusive.
-   *
-   * @param beginIndex start at this index
-   * @param endIndex the last character is the one before this index
-   * @return substring sharing underlying data
-   * @throws IndexOutOfBoundsException if {@code beginIndex < 0}, {@code endIndex > size()}, or
-   *     {@code beginIndex > endIndex}.
-   */
-  public abstract ByteString substring(int beginIndex, int endIndex);
-
-  /**
-   * Tests if this bytestring starts with the specified prefix. Similar to {@link
-   * String#startsWith(String)}
-   *
-   * @param prefix the prefix.
-   * @return <code>true</code> if the byte sequence represented by the argument is a prefix of the
-   *     byte sequence represented by this string; <code>false</code> otherwise.
-   */
-  public final boolean startsWith(ByteString prefix) {
-    return size() >= prefix.size() && substring(0, prefix.size()).equals(prefix);
-  }
-
-  /**
-   * Tests if this bytestring ends with the specified suffix. Similar to {@link
-   * String#endsWith(String)}
-   *
-   * @param suffix the suffix.
-   * @return <code>true</code> if the byte sequence represented by the argument is a suffix of the
-   *     byte sequence represented by this string; <code>false</code> otherwise.
-   */
-  public final boolean endsWith(ByteString suffix) {
-    return size() >= suffix.size() && substring(size() - suffix.size()).equals(suffix);
-  }
-
-  // =================================================================
-  // byte[] -> ByteString
-
-  /**
-   * Copies the given bytes into a {@code ByteString}.
-   *
-   * @param bytes source array
-   * @param offset offset in source array
-   * @param size number of bytes to copy
-   * @return new {@code ByteString}
-   * @throws IndexOutOfBoundsException if {@code offset} or {@code size} are out of bounds
-   */
-  public static ByteString copyFrom(byte[] bytes, int offset, int size) {
-    checkRange(offset, offset + size, bytes.length);
-    return new LiteralByteString(byteArrayCopier.copyFrom(bytes, offset, size));
-  }
-
-  /**
-   * Copies the given bytes into a {@code ByteString}.
-   *
-   * @param bytes to copy
-   * @return new {@code ByteString}
-   */
-  public static ByteString copyFrom(byte[] bytes) {
-    return copyFrom(bytes, 0, bytes.length);
-  }
-
-  /** Wraps the given bytes into a {@code ByteString}. Intended for internal only usage. */
-  static ByteString wrap(ByteBuffer buffer) {
-    if (buffer.hasArray()) {
-      final int offset = buffer.arrayOffset();
-      return ByteString.wrap(buffer.array(), offset + buffer.position(), buffer.remaining());
-    } else {
-      return new NioByteString(buffer);
-    }
-  }
-
-  /**
-   * Wraps the given bytes into a {@code ByteString}. Intended for internal only usage to force a
-   * classload of ByteString before LiteralByteString.
-   */
-  static ByteString wrap(byte[] bytes) {
-    // TODO(dweis): Return EMPTY when bytes are empty to reduce allocations?
-    return new LiteralByteString(bytes);
-  }
-
-  /**
-   * Wraps the given bytes into a {@code ByteString}. Intended for internal only usage to force a
-   * classload of ByteString before BoundedByteString and LiteralByteString.
-   */
-  static ByteString wrap(byte[] bytes, int offset, int length) {
-    return new BoundedByteString(bytes, offset, length);
-  }
-
-  /**
-   * Copies the next {@code size} bytes from a {@code java.nio.ByteBuffer} into a {@code
-   * ByteString}.
-   *
-   * @param bytes source buffer
-   * @param size number of bytes to copy
-   * @return new {@code ByteString}
-   * @throws IndexOutOfBoundsException if {@code size > bytes.remaining()}
-   */
-  public static ByteString copyFrom(ByteBuffer bytes, int size) {
-    checkRange(0, size, bytes.remaining());
-    byte[] copy = new byte[size];
-    bytes.get(copy);
-    return new LiteralByteString(copy);
-  }
-
-  /**
-   * Copies the remaining bytes from a {@code java.nio.ByteBuffer} into a {@code ByteString}.
-   *
-   * @param bytes sourceBuffer
-   * @return new {@code ByteString}
-   */
-  public static ByteString copyFrom(ByteBuffer bytes) {
-    return copyFrom(bytes, bytes.remaining());
-  }
-
-  /**
-   * Encodes {@code text} into a sequence of bytes using the named charset and returns the result as
-   * a {@code ByteString}.
-   *
-   * @param text source string
-   * @param charsetName encoding to use
-   * @return new {@code ByteString}
-   * @throws UnsupportedEncodingException if the encoding isn't found
-   */
-  public static ByteString copyFrom(String text, String charsetName)
-      throws UnsupportedEncodingException {
-    return new LiteralByteString(text.getBytes(charsetName));
-  }
-
-  /**
-   * Encodes {@code text} into a sequence of bytes using the named charset and returns the result as
-   * a {@code ByteString}.
-   *
-   * @param text source string
-   * @param charset encode using this charset
-   * @return new {@code ByteString}
-   */
-  public static ByteString copyFrom(String text, Charset charset) {
-    return new LiteralByteString(text.getBytes(charset));
-  }
-
-  /**
-   * Encodes {@code text} into a sequence of UTF-8 bytes and returns the result as a {@code
-   * ByteString}.
-   *
-   * @param text source string
-   * @return new {@code ByteString}
-   */
-  public static ByteString copyFromUtf8(String text) {
-    return new LiteralByteString(text.getBytes(Internal.UTF_8));
-  }
-
-  // =================================================================
-  // InputStream -> ByteString
-
-  /**
-   * Completely reads the given stream's bytes into a {@code ByteString}, blocking if necessary
-   * until all bytes are read through to the end of the stream.
-   *
-   * <p><b>Performance notes:</b> The returned {@code ByteString} is an immutable tree of byte
-   * arrays ("chunks") of the stream data. The first chunk is small, with subsequent chunks each
-   * being double the size, up to 8K.
-   *
-   * <p>Each byte read from the input stream will be copied twice to ensure that the resulting
-   * ByteString is truly immutable.
-   *
-   * @param streamToDrain The source stream, which is read completely but not closed.
-   * @return A new {@code ByteString} which is made up of chunks of various sizes, depending on the
-   *     behavior of the underlying stream.
-   * @throws IOException IOException is thrown if there is a problem reading the underlying stream.
-   */
-  public static ByteString readFrom(InputStream streamToDrain) throws IOException {
-    return readFrom(streamToDrain, MIN_READ_FROM_CHUNK_SIZE, MAX_READ_FROM_CHUNK_SIZE);
-  }
-
-  /**
-   * Completely reads the given stream's bytes into a {@code ByteString}, blocking if necessary
-   * until all bytes are read through to the end of the stream.
-   *
-   * <p><b>Performance notes:</b> The returned {@code ByteString} is an immutable tree of byte
-   * arrays ("chunks") of the stream data. The chunkSize parameter sets the size of these byte
-   * arrays.
-   *
-   * <p>Each byte read from the input stream will be copied twice to ensure that the resulting
-   * ByteString is truly immutable.
-   *
-   * @param streamToDrain The source stream, which is read completely but not closed.
-   * @param chunkSize The size of the chunks in which to read the stream.
-   * @return A new {@code ByteString} which is made up of chunks of the given size.
-   * @throws IOException IOException is thrown if there is a problem reading the underlying stream.
-   */
-  public static ByteString readFrom(InputStream streamToDrain, int chunkSize) throws IOException {
-    return readFrom(streamToDrain, chunkSize, chunkSize);
-  }
-
-  // Helper method that takes the chunk size range as a parameter.
-  public static ByteString readFrom(InputStream streamToDrain, int minChunkSize, int maxChunkSize)
-      throws IOException {
-    Collection<ByteString> results = new ArrayList<ByteString>();
-
-    // copy the inbound bytes into a list of chunks; the chunk size
-    // grows exponentially to support both short and long streams.
-    int chunkSize = minChunkSize;
-    while (true) {
-      ByteString chunk = readChunk(streamToDrain, chunkSize);
-      if (chunk == null) {
-        break;
-      }
-      results.add(chunk);
-      chunkSize = Math.min(chunkSize * 2, maxChunkSize);
-    }
-
-    return ByteString.copyFrom(results);
-  }
-
-  /**
-   * Blocks until a chunk of the given size can be made from the stream, or EOF is reached. Calls
-   * read() repeatedly in case the given stream implementation doesn't completely fill the given
-   * buffer in one read() call.
-   *
-   * @return A chunk of the desired size, or else a chunk as large as was available when end of
-   *     stream was reached. Returns null if the given stream had no more data in it.
-   */
-  private static ByteString readChunk(InputStream in, final int chunkSize) throws IOException {
-    final byte[] buf = new byte[chunkSize];
-    int bytesRead = 0;
-    while (bytesRead < chunkSize) {
-      final int count = in.read(buf, bytesRead, chunkSize - bytesRead);
-      if (count == -1) {
-        break;
-      }
-      bytesRead += count;
-    }
-
-    if (bytesRead == 0) {
-      return null;
-    }
-
-    // Always make a copy since InputStream could steal a reference to buf.
-    return ByteString.copyFrom(buf, 0, bytesRead);
-  }
-
-  // =================================================================
-  // Multiple ByteStrings -> One ByteString
-
-  /**
-   * Concatenate the given {@code ByteString} to this one. Short concatenations, of total size
-   * smaller than {@link ByteString#CONCATENATE_BY_COPY_SIZE}, are produced by copying the
-   * underlying bytes (as per Rope.java, <a
-   * href="http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol25/issue12/spe986.pdf">
-   * BAP95 </a>. In general, the concatenate involves no copying.
-   *
-   * @param other string to concatenate
-   * @return a new {@code ByteString} instance
-   */
-  public final ByteString concat(ByteString other) {
-    if (Integer.MAX_VALUE - size() < other.size()) {
-      throw new IllegalArgumentException(
-          "ByteString would be too long: " + size() + "+" + other.size());
-    }
-
-    return RopeByteString.concatenate(this, other);
-  }
-
-  /**
-   * Concatenates all byte strings in the iterable and returns the result. This is designed to run
-   * in O(list size), not O(total bytes).
-   *
-   * <p>The returned {@code ByteString} is not necessarily a unique object. If the list is empty,
-   * the returned object is the singleton empty {@code ByteString}. If the list has only one
-   * element, that {@code ByteString} will be returned without copying.
-   *
-   * @param byteStrings strings to be concatenated
-   * @return new {@code ByteString}
-   */
-  public static ByteString copyFrom(Iterable<ByteString> byteStrings) {
-    // Determine the size;
-    final int size;
-    if (!(byteStrings instanceof Collection)) {
-      int tempSize = 0;
-      for (Iterator<ByteString> iter = byteStrings.iterator();
-          iter.hasNext();
-          iter.next(), ++tempSize) {}
-      size = tempSize;
-    } else {
-      size = ((Collection<ByteString>) byteStrings).size();
-    }
-
-    if (size == 0) {
-      return EMPTY;
-    }
-
-    return balancedConcat(byteStrings.iterator(), size);
-  }
-
-  // Internal function used by copyFrom(Iterable<ByteString>).
-  // Create a balanced concatenation of the next "length" elements from the
-  // iterable.
-  private static ByteString balancedConcat(Iterator<ByteString> iterator, int length) {
-    if (length < 1) {
-      throw new IllegalArgumentException(String.format("length (%s) must be >= 1", length));
-    }
-    ByteString result;
-    if (length == 1) {
-      result = iterator.next();
-    } else {
-      int halfLength = length >>> 1;
-      ByteString left = balancedConcat(iterator, halfLength);
-      ByteString right = balancedConcat(iterator, length - halfLength);
-      result = left.concat(right);
-    }
-    return result;
-  }
-
-  // =================================================================
-  // ByteString -> byte[]
-
-  /**
-   * Copies bytes into a buffer at the given offset.
-   *
-   * <p>To copy a subset of bytes, you call this method on the return value of {@link
-   * #substring(int, int)}. Example: {@code byteString.substring(start, end).copyTo(target, offset)}
-   *
-   * @param target buffer to copy into
-   * @param offset in the target buffer
-   * @throws IndexOutOfBoundsException if the offset is negative or too large
-   */
-  public void copyTo(byte[] target, int offset) {
-    copyTo(target, 0, offset, size());
-  }
-
-  /**
-   * Copies bytes into a buffer.
-   *
-   * @param target buffer to copy into
-   * @param sourceOffset offset within these bytes
-   * @param targetOffset offset within the target buffer
-   * @param numberToCopy number of bytes to copy
-   * @throws IndexOutOfBoundsException if an offset or size is negative or too large
-   * @deprecated Instead, call {@code byteString.substring(sourceOffset, sourceOffset +
-   *     numberToCopy).copyTo(target, targetOffset)}
-   */
-  @Deprecated
-  public final void copyTo(byte[] target, int sourceOffset, int targetOffset, int numberToCopy) {
-    checkRange(sourceOffset, sourceOffset + numberToCopy, size());
-    checkRange(targetOffset, targetOffset + numberToCopy, target.length);
-    if (numberToCopy > 0) {
-      copyToInternal(target, sourceOffset, targetOffset, numberToCopy);
-    }
-  }
-
-  /**
-   * Internal (package private) implementation of {@link #copyTo(byte[],int,int,int)}. It assumes
-   * that all error checking has already been performed and that {@code numberToCopy > 0}.
-   */
-  protected abstract void copyToInternal(
-      byte[] target, int sourceOffset, int targetOffset, int numberToCopy);
-
-  /**
-   * Copies bytes into a ByteBuffer.
-   *
-   * <p>To copy a subset of bytes, you call this method on the return value of {@link
-   * #substring(int, int)}. Example: {@code byteString.substring(start, end).copyTo(target)}
-   *
-   * @param target ByteBuffer to copy into.
-   * @throws java.nio.ReadOnlyBufferException if the {@code target} is read-only
-   * @throws java.nio.BufferOverflowException if the {@code target}'s remaining() space is not large
-   *     enough to hold the data.
-   */
-  public abstract void copyTo(ByteBuffer target);
-
-  /**
-   * Copies bytes to a {@code byte[]}.
-   *
-   * @return copied bytes
-   */
-  public final byte[] toByteArray() {
-    final int size = size();
-    if (size == 0) {
-      return Internal.EMPTY_BYTE_ARRAY;
-    }
-    byte[] result = new byte[size];
-    copyToInternal(result, 0, 0, size);
-    return result;
-  }
-
-  /**
-   * Writes a copy of the contents of this byte string to the specified output stream argument.
-   *
-   * @param out the output stream to which to write the data.
-   * @throws IOException if an I/O error occurs.
-   */
-  public abstract void writeTo(OutputStream out) throws IOException;
-
-  /**
-   * Writes a specified part of this byte string to an output stream.
-   *
-   * @param out the output stream to which to write the data.
-   * @param sourceOffset offset within these bytes
-   * @param numberToWrite number of bytes to write
-   * @throws IOException if an I/O error occurs.
-   * @throws IndexOutOfBoundsException if an offset or size is negative or too large
-   */
-  final void writeTo(OutputStream out, int sourceOffset, int numberToWrite) throws IOException {
-    checkRange(sourceOffset, sourceOffset + numberToWrite, size());
-    if (numberToWrite > 0) {
-      writeToInternal(out, sourceOffset, numberToWrite);
-    }
-  }
-
-  /**
-   * Internal version of {@link #writeTo(OutputStream,int,int)} that assumes all error checking has
-   * already been done.
-   */
-  abstract void writeToInternal(OutputStream out, int sourceOffset, int numberToWrite)
-      throws IOException;
-
-  /**
-   * Writes this {@link ByteString} to the provided {@link ByteOutput}. Calling this method may
-   * result in multiple operations on the target {@link ByteOutput}.
-   *
-   * <p>This method may expose internal backing buffers of the {@link ByteString} to the {@link
-   * ByteOutput} in order to avoid additional copying overhead. It would be possible for a malicious
-   * {@link ByteOutput} to corrupt the {@link ByteString}. Use with caution!
-   *
-   * @param byteOutput the output target to receive the bytes
-   * @throws IOException if an I/O error occurs
-   * @see UnsafeByteOperations#unsafeWriteTo(ByteString, ByteOutput)
-   */
-  abstract void writeTo(ByteOutput byteOutput) throws IOException;
-
-  /**
-   * This method behaves exactly the same as {@link #writeTo(ByteOutput)} unless the {@link
-   * ByteString} is a rope. For ropes, the leaf nodes are written in reverse order to the {@code
-   * byteOutput}.
-   *
-   * @param byteOutput the output target to receive the bytes
-   * @throws IOException if an I/O error occurs
-   * @see UnsafeByteOperations#unsafeWriteToReverse(ByteString, ByteOutput)
-   */
-  abstract void writeToReverse(ByteOutput byteOutput) throws IOException;
-
-  /**
-   * Constructs a read-only {@code java.nio.ByteBuffer} whose content is equal to the contents of
-   * this byte string. The result uses the same backing array as the byte string, if possible.
-   *
-   * @return wrapped bytes
-   */
-  public abstract ByteBuffer asReadOnlyByteBuffer();
-
-  /**
-   * Constructs a list of read-only {@code java.nio.ByteBuffer} objects such that the concatenation
-   * of their contents is equal to the contents of this byte string. The result uses the same
-   * backing arrays as the byte string.
-   *
-   * <p>By returning a list, implementations of this method may be able to avoid copying even when
-   * there are multiple backing arrays.
-   *
-   * @return a list of wrapped bytes
-   */
-  public abstract List<ByteBuffer> asReadOnlyByteBufferList();
-
-  /**
-   * Constructs a new {@code String} by decoding the bytes using the specified charset.
-   *
-   * @param charsetName encode using this charset
-   * @return new string
-   * @throws UnsupportedEncodingException if charset isn't recognized
-   */
-  public final String toString(String charsetName) throws UnsupportedEncodingException {
-    try {
-      return toString(Charset.forName(charsetName));
-    } catch (UnsupportedCharsetException e) {
-      UnsupportedEncodingException exception = new UnsupportedEncodingException(charsetName);
-      exception.initCause(e);
-      throw exception;
-    }
-  }
-
-  /**
-   * Constructs a new {@code String} by decoding the bytes using the specified charset. Returns the
-   * same empty String if empty.
-   *
-   * @param charset encode using this charset
-   * @return new string
-   */
-  public final String toString(Charset charset) {
-    return size() == 0 ? "" : toStringInternal(charset);
-  }
-
-  /**
-   * Constructs a new {@code String} by decoding the bytes using the specified charset.
-   *
-   * @param charset encode using this charset
-   * @return new string
-   */
-  protected abstract String toStringInternal(Charset charset);
-
-  // =================================================================
-  // UTF-8 decoding
-
-  /**
-   * Constructs a new {@code String} by decoding the bytes as UTF-8.
-   *
-   * @return new string using UTF-8 encoding
-   */
-  public final String toStringUtf8() {
-    return toString(Internal.UTF_8);
-  }
-
-  /**
-   * Tells whether this {@code ByteString} represents a well-formed UTF-8 byte sequence, such that
-   * the original bytes can be converted to a String object and then round tripped back to bytes
-   * without loss.
-   *
-   * <p>More precisely, returns {@code true} whenever:
-   *
-   * <pre>{@code
-   * Arrays.equals(byteString.toByteArray(),
-   *     new String(byteString.toByteArray(), "UTF-8").getBytes("UTF-8"))
-   * }</pre>
-   *
-   * <p>This method returns {@code false} for "overlong" byte sequences, as well as for 3-byte
-   * sequences that would map to a surrogate character, in accordance with the restricted definition
-   * of UTF-8 introduced in Unicode 3.1. Note that the UTF-8 decoder included in Oracle's JDK has
-   * been modified to also reject "overlong" byte sequences, but (as of 2011) still accepts 3-byte
-   * surrogate character byte sequences.
-   *
-   * <p>See the Unicode Standard,<br>
-   * Table 3-6. <em>UTF-8 Bit Distribution</em>,<br>
-   * Table 3-7. <em>Well Formed UTF-8 Byte Sequences</em>.
-   *
-   * @return whether the bytes in this {@code ByteString} are a well-formed UTF-8 byte sequence
-   */
-  public abstract boolean isValidUtf8();
-
-  /**
-   * Tells whether the given byte sequence is a well-formed, malformed, or incomplete UTF-8 byte
-   * sequence. This method accepts and returns a partial state result, allowing the bytes for a
-   * complete UTF-8 byte sequence to be composed from multiple {@code ByteString} segments.
-   *
-   * @param state either {@code 0} (if this is the initial decoding operation) or the value returned
-   *     from a call to a partial decoding method for the previous bytes
-   * @param offset offset of the first byte to check
-   * @param length number of bytes to check
-   * @return {@code -1} if the partial byte sequence is definitely malformed, {@code 0} if it is
-   *     well-formed (no additional input needed), or, if the byte sequence is "incomplete", i.e.
-   *     apparently terminated in the middle of a character, an opaque integer "state" value
-   *     containing enough information to decode the character when passed to a subsequent
-   *     invocation of a partial decoding method.
-   */
-  protected abstract int partialIsValidUtf8(int state, int offset, int length);
-
-  // =================================================================
-  // equals() and hashCode()
-
-  @Override
-  public abstract boolean equals(Object o);
-
-  /** Base class for leaf {@link ByteString}s (i.e. non-ropes). */
-  abstract static class LeafByteString extends ByteString {
-    @Override
-    protected final int getTreeDepth() {
-      return 0;
-    }
-
-    @Override
-    protected final boolean isBalanced() {
-      return true;
-    }
-
-    @Override
-    void writeToReverse(ByteOutput byteOutput) throws IOException {
-      writeTo(byteOutput);
-    }
-
-    /**
-     * Check equality of the substring of given length of this object starting at zero with another
-     * {@code ByteString} substring starting at offset.
-     *
-     * @param other what to compare a substring in
-     * @param offset offset into other
-     * @param length number of bytes to compare
-     * @return true for equality of substrings, else false.
-     */
-    abstract boolean equalsRange(ByteString other, int offset, int length);
-  }
-
-  /**
-   * Compute the hashCode using the traditional algorithm from {@link ByteString}.
-   *
-   * @return hashCode value
-   */
-  @Override
-  public final int hashCode() {
-    int h = hash;
-
-    if (h == 0) {
-      int size = size();
-      h = partialHash(size, 0, size);
-      if (h == 0) {
-        h = 1;
-      }
-      hash = h;
-    }
-    return h;
-  }
-
-  // =================================================================
-  // Input stream
-
-  /**
-   * Creates an {@code InputStream} which can be used to read the bytes.
-   *
-   * <p>The {@link InputStream} returned by this method is guaranteed to be completely non-blocking.
-   * The method {@link InputStream#available()} returns the number of bytes remaining in the stream.
-   * The methods {@link InputStream#read(byte[])}, {@link InputStream#read(byte[],int,int)} and
-   * {@link InputStream#skip(long)} will read/skip as many bytes as are available. The method {@link
-   * InputStream#markSupported()} returns {@code true}.
-   *
-   * <p>The methods in the returned {@link InputStream} might <b>not</b> be thread safe.
-   *
-   * @return an input stream that returns the bytes of this byte string.
-   */
-  public abstract InputStream newInput();
-
-  /**
-   * Creates a {@link CodedInputStream} which can be used to read the bytes. Using this is often
-   * more efficient than creating a {@link CodedInputStream} that wraps the result of {@link
-   * #newInput()}.
-   *
-   * @return stream based on wrapped data
-   */
-  public abstract CodedInputStream newCodedInput();
-
-  // =================================================================
-  // Output stream
-
-  /**
-   * Creates a new {@link Output} with the given initial capacity. Call {@link
-   * Output#toByteString()} to create the {@code ByteString} instance.
-   *
-   * <p>A {@link ByteString.Output} offers the same functionality as a {@link
-   * ByteArrayOutputStream}, except that it returns a {@link ByteString} rather than a {@code byte}
-   * array.
-   *
-   * @param initialCapacity estimate of number of bytes to be written
-   * @return {@code OutputStream} for building a {@code ByteString}
-   */
-  public static Output newOutput(int initialCapacity) {
-    return new Output(initialCapacity);
-  }
-
-  /**
-   * Creates a new {@link Output}. Call {@link Output#toByteString()} to create the {@code
-   * ByteString} instance.
-   *
-   * <p>A {@link ByteString.Output} offers the same functionality as a {@link
-   * ByteArrayOutputStream}, except that it returns a {@link ByteString} rather than a {@code byte
-   * array}.
-   *
-   * @return {@code OutputStream} for building a {@code ByteString}
-   */
-  public static Output newOutput() {
-    return new Output(CONCATENATE_BY_COPY_SIZE);
-  }
-
-  /**
-   * Outputs to a {@code ByteString} instance. Call {@link #toByteString()} to create the {@code
-   * ByteString} instance.
-   */
-  public static final class Output extends OutputStream {
-    // Implementation note.
-    // The public methods of this class must be synchronized.  ByteStrings
-    // are guaranteed to be immutable.  Without some sort of locking, it could
-    // be possible for one thread to call toByteSring(), while another thread
-    // is still modifying the underlying byte array.
-
-    private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
-    // argument passed by user, indicating initial capacity.
-    private final int initialCapacity;
-    // ByteStrings to be concatenated to create the result
-    private final ArrayList<ByteString> flushedBuffers;
-    // Total number of bytes in the ByteStrings of flushedBuffers
-    private int flushedBuffersTotalBytes;
-    // Current buffer to which we are writing
-    private byte[] buffer;
-    // Location in buffer[] to which we write the next byte.
-    private int bufferPos;
-
-    /**
-     * Creates a new ByteString output stream with the specified initial capacity.
-     *
-     * @param initialCapacity the initial capacity of the output stream.
-     */
-    Output(int initialCapacity) {
-      if (initialCapacity < 0) {
-        throw new IllegalArgumentException("Buffer size < 0");
-      }
-      this.initialCapacity = initialCapacity;
-      this.flushedBuffers = new ArrayList<ByteString>();
-      this.buffer = new byte[initialCapacity];
-    }
-
-    @Override
-    public synchronized void write(int b) {
-      if (bufferPos == buffer.length) {
-        flushFullBuffer(1);
-      }
-      buffer[bufferPos++] = (byte) b;
-    }
-
-    @Override
-    public synchronized void write(byte[] b, int offset, int length) {
-      if (length <= buffer.length - bufferPos) {
-        // The bytes can fit into the current buffer.
-        System.arraycopy(b, offset, buffer, bufferPos, length);
-        bufferPos += length;
-      } else {
-        // Use up the current buffer
-        int copySize = buffer.length - bufferPos;
-        System.arraycopy(b, offset, buffer, bufferPos, copySize);
-        offset += copySize;
-        length -= copySize;
-        // Flush the buffer, and get a new buffer at least big enough to cover
-        // what we still need to output
-        flushFullBuffer(length);
-        System.arraycopy(b, offset, buffer, /* count= */ 0, length);
-        bufferPos = length;
-      }
-    }
-
-    /**
-     * Creates a byte string with the size and contents of this output stream. This does not create
-     * a new copy of the underlying bytes. If the stream size grows dynamically, the runtime is
-     * O(log n) in respect to the number of bytes written to the {@link Output}. If the stream size
-     * stays within the initial capacity, the runtime is O(1).
-     *
-     * @return the current contents of this output stream, as a byte string.
-     */
-    public synchronized ByteString toByteString() {
-      flushLastBuffer();
-      return ByteString.copyFrom(flushedBuffers);
-    }
-
-    /** Implement java.util.Arrays.copyOf() for jdk 1.5. */
-    private byte[] copyArray(byte[] buffer, int length) {
-      byte[] result = new byte[length];
-      System.arraycopy(buffer, 0, result, 0, Math.min(buffer.length, length));
-      return result;
-    }
-
-    /**
-     * Writes the complete contents of this byte array output stream to the specified output stream
-     * argument.
-     *
-     * @param out the output stream to which to write the data.
-     * @throws IOException if an I/O error occurs.
-     */
-    public void writeTo(OutputStream out) throws IOException {
-      ByteString[] cachedFlushBuffers;
-      byte[] cachedBuffer;
-      int cachedBufferPos;
-      synchronized (this) {
-        // Copy the information we need into local variables so as to hold
-        // the lock for as short a time as possible.
-        cachedFlushBuffers = flushedBuffers.toArray(new ByteString[flushedBuffers.size()]);
-        cachedBuffer = buffer;
-        cachedBufferPos = bufferPos;
-      }
-      for (ByteString byteString : cachedFlushBuffers) {
-        byteString.writeTo(out);
-      }
-
-      out.write(copyArray(cachedBuffer, cachedBufferPos));
-    }
-
-    /**
-     * Returns the current size of the output stream.
-     *
-     * @return the current size of the output stream
-     */
-    public synchronized int size() {
-      return flushedBuffersTotalBytes + bufferPos;
-    }
-
-    /**
-     * Resets this stream, so that all currently accumulated output in the output stream is
-     * discarded. The output stream can be used again, reusing the already allocated buffer space.
-     */
-    public synchronized void reset() {
-      flushedBuffers.clear();
-      flushedBuffersTotalBytes = 0;
-      bufferPos = 0;
-    }
-
-    @Override
-    public String toString() {
-      return String.format(
-          "<ByteString.Output@%s size=%d>",
-          Integer.toHexString(System.identityHashCode(this)), size());
-    }
-
-    /**
-     * Internal function used by writers. The current buffer is full, and the writer needs a new
-     * buffer whose size is at least the specified minimum size.
-     */
-    private void flushFullBuffer(int minSize) {
-      flushedBuffers.add(new LiteralByteString(buffer));
-      flushedBuffersTotalBytes += buffer.length;
-      // We want to increase our total capacity by 50%, but as a minimum,
-      // the new buffer should also at least be >= minSize and
-      // >= initial Capacity.
-      int newSize = Math.max(initialCapacity, Math.max(minSize, flushedBuffersTotalBytes >>> 1));
-      buffer = new byte[newSize];
-      bufferPos = 0;
-    }
-
-    /**
-     * Internal function used by {@link #toByteString()}. The current buffer may or may not be full,
-     * but it needs to be flushed.
-     */
-    private void flushLastBuffer() {
-      if (bufferPos < buffer.length) {
-        if (bufferPos > 0) {
-          byte[] bufferCopy = copyArray(buffer, bufferPos);
-          flushedBuffers.add(new LiteralByteString(bufferCopy));
-        }
-        // We reuse this buffer for further writes.
-      } else {
-        // Buffer is completely full.  Huzzah.
-        flushedBuffers.add(new LiteralByteString(buffer));
-        // 99% of the time, we're not going to use this OutputStream again.
-        // We set buffer to an empty byte stream so that we're handling this
-        // case without wasting space.  In the rare case that more writes
-        // *do* occur, this empty buffer will be flushed and an appropriately
-        // sized new buffer will be created.
-        buffer = EMPTY_BYTE_ARRAY;
-      }
-      flushedBuffersTotalBytes += bufferPos;
-      bufferPos = 0;
-    }
-  }
-
-  /**
-   * Constructs a new {@code ByteString} builder, which allows you to efficiently construct a {@code
-   * ByteString} by writing to a {@link CodedOutputStream}. Using this is much more efficient than
-   * calling {@code newOutput()} and wrapping that in a {@code CodedOutputStream}.
-   *
-   * <p>This is package-private because it's a somewhat confusing interface. Users can call {@link
-   * Message#toByteString()} instead of calling this directly.
-   *
-   * @param size The target byte size of the {@code ByteString}. You must write exactly this many
-   *     bytes before building the result.
-   * @return the builder
-   */
-  static CodedBuilder newCodedBuilder(int size) {
-    return new CodedBuilder(size);
-  }
-
-  /** See {@link ByteString#newCodedBuilder(int)}. */
-  static final class CodedBuilder {
-    private final CodedOutputStream output;
-    private final byte[] buffer;
-
-    private CodedBuilder(int size) {
-      buffer = new byte[size];
-      output = CodedOutputStream.newInstance(buffer);
-    }
-
-    public ByteString build() {
-      output.checkNoSpaceLeft();
-
-      // We can be confident that the CodedOutputStream will not modify the
-      // underlying bytes anymore because it already wrote all of them.  So,
-      // no need to make a copy.
-      return new LiteralByteString(buffer);
-    }
-
-    public CodedOutputStream getCodedOutput() {
-      return output;
-    }
-  }
-
-  // =================================================================
-  // Methods {@link RopeByteString} needs on instances, which aren't part of the
-  // public API.
-
-  /**
-   * Return the depth of the tree representing this {@code ByteString}, if any, whose root is this
-   * node. If this is a leaf node, return 0.
-   *
-   * @return tree depth or zero
-   */
-  protected abstract int getTreeDepth();
-
-  /**
-   * Return {@code true} if this ByteString is literal (a leaf node) or a flat-enough tree in the
-   * sense of {@link RopeByteString}.
-   *
-   * @return true if the tree is flat enough
-   */
-  protected abstract boolean isBalanced();
-
-  /**
-   * Return the cached hash code if available.
-   *
-   * @return value of cached hash code or 0 if not computed yet
-   */
-  protected final int peekCachedHashCode() {
-    return hash;
-  }
-
-  /**
-   * Compute the hash across the value bytes starting with the given hash, and return the result.
-   * This is used to compute the hash across strings represented as a set of pieces by allowing the
-   * hash computation to be continued from piece to piece.
-   *
-   * @param h starting hash value
-   * @param offset offset into this value to start looking at data values
-   * @param length number of data values to include in the hash computation
-   * @return ending hash value
-   */
-  protected abstract int partialHash(int h, int offset, int length);
-
-  /**
-   * Checks that the given index falls within the specified array size.
-   *
-   * @param index the index position to be tested
-   * @param size the length of the array
-   * @throws IndexOutOfBoundsException if the index does not fall within the array.
-   */
-  static void checkIndex(int index, int size) {
-    if ((index | (size - (index + 1))) < 0) {
-      if (index < 0) {
-        throw new ArrayIndexOutOfBoundsException("Index < 0: " + index);
-      }
-      throw new ArrayIndexOutOfBoundsException("Index > length: " + index + ", " + size);
-    }
-  }
-
-  /**
-   * Checks that the given range falls within the bounds of an array
-   *
-   * @param startIndex the start index of the range (inclusive)
-   * @param endIndex the end index of the range (exclusive)
-   * @param size the size of the array.
-   * @return the length of the range.
-   * @throws IndexOutOfBoundsException some or all of the range falls outside of the array.
-   */
-  static int checkRange(int startIndex, int endIndex, int size) {
-    final int length = endIndex - startIndex;
-    if ((startIndex | endIndex | length | (size - endIndex)) < 0) {
-      if (startIndex < 0) {
-        throw new IndexOutOfBoundsException("Beginning index: " + startIndex + " < 0");
-      }
-      if (endIndex < startIndex) {
-        throw new IndexOutOfBoundsException(
-            "Beginning index larger than ending index: " + startIndex + ", " + endIndex);
-      }
-      // endIndex >= size
-      throw new IndexOutOfBoundsException("End index: " + endIndex + " >= " + size);
-    }
-    return length;
-  }
-
-  @Override
-  public final String toString() {
-    return String.format(
-        Locale.ROOT,
-        "<ByteString@%s size=%d contents=\"%s\">",
-        toHexString(identityHashCode(this)),
-        size(),
-        truncateAndEscapeForDisplay());
-  }
-
-  private String truncateAndEscapeForDisplay() {
-    final int limit = 50;
-
-    return size() <= limit ? escapeBytes(this) : escapeBytes(substring(0, limit - 3)) + "...";
-  }
-
-  /**
-   * This class implements a {@link com.google.protobuf.ByteString} backed by a single array of
-   * bytes, contiguous in memory. It supports substring by pointing to only a sub-range of the
-   * underlying byte array, meaning that a substring will reference the full byte-array of the
-   * string it's made from, exactly as with {@link String}.
-   *
-   * @author carlanton@google.com (Carl Haverl)
-   */
-  // Keep this class private to avoid deadlocks in classloading across threads as ByteString's
-  // static initializer loads LiteralByteString and another thread loads LiteralByteString.
-  private static class LiteralByteString extends ByteString.LeafByteString {
-    private static final long serialVersionUID = 1L;
-
-    protected final byte[] bytes;
-
-    /**
-     * Creates a {@code LiteralByteString} backed by the given array, without copying.
-     *
-     * @param bytes array to wrap
-     */
-    LiteralByteString(byte[] bytes) {
-      if (bytes == null) {
-        throw new NullPointerException();
-      }
-      this.bytes = bytes;
-    }
-
-    @Override
-    public byte byteAt(int index) {
-      // Unlike most methods in this class, this one is a direct implementation
-      // ignoring the potential offset because we need to do range-checking in the
-      // substring case anyway.
-      return bytes[index];
-    }
-
-    @Override
-    byte internalByteAt(int index) {
-      return bytes[index];
-    }
-
-    @Override
-    public int size() {
-      return bytes.length;
-    }
-
-    // =================================================================
-    // ByteString -> substring
-
-    @Override
-    public final ByteString substring(int beginIndex, int endIndex) {
-      final int length = checkRange(beginIndex, endIndex, size());
-
-      if (length == 0) {
-        return ByteString.EMPTY;
-      }
-
-      return new BoundedByteString(bytes, getOffsetIntoBytes() + beginIndex, length);
-    }
-
-    // =================================================================
-    // ByteString -> byte[]
-
-    @Override
-    protected void copyToInternal(
-        byte[] target, int sourceOffset, int targetOffset, int numberToCopy) {
-      // Optimized form, not for subclasses, since we don't call
-      // getOffsetIntoBytes() or check the 'numberToCopy' parameter.
-      // TODO(nathanmittler): Is not calling getOffsetIntoBytes really saving that much?
-      System.arraycopy(bytes, sourceOffset, target, targetOffset, numberToCopy);
-    }
-
-    @Override
-    public final void copyTo(ByteBuffer target) {
-      target.put(bytes, getOffsetIntoBytes(), size()); // Copies bytes
-    }
-
-    @Override
-    public final ByteBuffer asReadOnlyByteBuffer() {
-      return ByteBuffer.wrap(bytes, getOffsetIntoBytes(), size()).asReadOnlyBuffer();
-    }
-
-    @Override
-    public final List<ByteBuffer> asReadOnlyByteBufferList() {
-      return Collections.singletonList(asReadOnlyByteBuffer());
-    }
-
-    @Override
-    public final void writeTo(OutputStream outputStream) throws IOException {
-      outputStream.write(toByteArray());
-    }
-
-    @Override
-    final void writeToInternal(OutputStream outputStream, int sourceOffset, int numberToWrite)
-        throws IOException {
-      outputStream.write(bytes, getOffsetIntoBytes() + sourceOffset, numberToWrite);
-    }
-
-    @Override
-    final void writeTo(ByteOutput output) throws IOException {
-      output.writeLazy(bytes, getOffsetIntoBytes(), size());
-    }
-
-    @Override
-    protected final String toStringInternal(Charset charset) {
-      return new String(bytes, getOffsetIntoBytes(), size(), charset);
-    }
-
-    // =================================================================
-    // UTF-8 decoding
-
-    @Override
-    public final boolean isValidUtf8() {
-      int offset = getOffsetIntoBytes();
-      return Utf8.isValidUtf8(bytes, offset, offset + size());
-    }
-
-    @Override
-    protected final int partialIsValidUtf8(int state, int offset, int length) {
-      int index = getOffsetIntoBytes() + offset;
-      return Utf8.partialIsValidUtf8(state, bytes, index, index + length);
-    }
-
-    // =================================================================
-    // equals() and hashCode()
-
-    @Override
-    public final boolean equals(Object other) {
-      if (other == this) {
-        return true;
-      }
-      if (!(other instanceof ByteString)) {
-        return false;
-      }
-
-      if (size() != ((ByteString) other).size()) {
-        return false;
-      }
-      if (size() == 0) {
-        return true;
-      }
-
-      if (other instanceof LiteralByteString) {
-        LiteralByteString otherAsLiteral = (LiteralByteString) other;
-        // If we know the hash codes and they are not equal, we know the byte
-        // strings are not equal.
-        int thisHash = peekCachedHashCode();
-        int thatHash = otherAsLiteral.peekCachedHashCode();
-        if (thisHash != 0 && thatHash != 0 && thisHash != thatHash) {
-          return false;
-        }
-
-        return equalsRange((LiteralByteString) other, 0, size());
-      } else {
-        // RopeByteString and NioByteString.
-        return other.equals(this);
-      }
-    }
-
-    /**
-     * Check equality of the substring of given length of this object starting at zero with another
-     * {@code LiteralByteString} substring starting at offset.
-     *
-     * @param other what to compare a substring in
-     * @param offset offset into other
-     * @param length number of bytes to compare
-     * @return true for equality of substrings, else false.
-     */
-    @Override
-    final boolean equalsRange(ByteString other, int offset, int length) {
-      if (length > other.size()) {
-        throw new IllegalArgumentException("Length too large: " + length + size());
-      }
-      if (offset + length > other.size()) {
-        throw new IllegalArgumentException(
-            "Ran off end of other: " + offset + ", " + length + ", " + other.size());
-      }
-
-      if (other instanceof LiteralByteString) {
-        LiteralByteString lbsOther = (LiteralByteString) other;
-        byte[] thisBytes = bytes;
-        byte[] otherBytes = lbsOther.bytes;
-        int thisLimit = getOffsetIntoBytes() + length;
-        for (int thisIndex = getOffsetIntoBytes(),
-                otherIndex = lbsOther.getOffsetIntoBytes() + offset;
-            (thisIndex < thisLimit);
-            ++thisIndex, ++otherIndex) {
-          if (thisBytes[thisIndex] != otherBytes[otherIndex]) {
-            return false;
-          }
-        }
-        return true;
-      }
-
-      return other.substring(offset, offset + length).equals(substring(0, length));
-    }
-
-    @Override
-    protected final int partialHash(int h, int offset, int length) {
-      return Internal.partialHash(h, bytes, getOffsetIntoBytes() + offset, length);
-    }
-
-    // =================================================================
-    // Input stream
-
-    @Override
-    public final InputStream newInput() {
-      return new ByteArrayInputStream(bytes, getOffsetIntoBytes(), size()); // No copy
-    }
-
-    @Override
-    public final CodedInputStream newCodedInput() {
-      // We trust CodedInputStream not to modify the bytes, or to give anyone
-      // else access to them.
-      return CodedInputStream.newInstance(
-          bytes, getOffsetIntoBytes(), size(), /* bufferIsImmutable= */ true);
-    }
-
-    // =================================================================
-    // Internal methods
-
-    /**
-     * Offset into {@code bytes[]} to use, non-zero for substrings.
-     *
-     * @return always 0 for this class
-     */
-    protected int getOffsetIntoBytes() {
-      return 0;
-    }
-  }
-
-  /**
-   * This class is used to represent the substring of a {@link ByteString} over a single byte array.
-   * In terms of the public API of {@link ByteString}, you end up here by calling {@link
-   * ByteString#copyFrom(byte[])} followed by {@link ByteString#substring(int, int)}.
-   *
-   * <p>This class contains most of the overhead involved in creating a substring from a {@link
-   * LiteralByteString}. The overhead involves some range-checking and two extra fields.
-   *
-   * @author carlanton@google.com (Carl Haverl)
-   */
-  // Keep this class private to avoid deadlocks in classloading across threads as ByteString's
-  // static initializer loads LiteralByteString and another thread loads BoundedByteString.
-  private static final class BoundedByteString extends LiteralByteString {
-
-    private final int bytesOffset;
-    private final int bytesLength;
-
-    /**
-     * Creates a {@code BoundedByteString} backed by the sub-range of given array, without copying.
-     *
-     * @param bytes array to wrap
-     * @param offset index to first byte to use in bytes
-     * @param length number of bytes to use from bytes
-     * @throws IllegalArgumentException if {@code offset < 0}, {@code length < 0}, or if {@code
-     *     offset + length > bytes.length}.
-     */
-    BoundedByteString(byte[] bytes, int offset, int length) {
-      super(bytes);
-      checkRange(offset, offset + length, bytes.length);
-
-      this.bytesOffset = offset;
-      this.bytesLength = length;
-    }
-
-    /**
-     * Gets the byte at the given index. Throws {@link ArrayIndexOutOfBoundsException} for
-     * backwards-compatibility reasons although it would more properly be {@link
-     * IndexOutOfBoundsException}.
-     *
-     * @param index index of byte
-     * @return the value
-     * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size
-     */
-    @Override
-    public byte byteAt(int index) {
-      // We must check the index ourselves as we cannot rely on Java array index
-      // checking for substrings.
-      checkIndex(index, size());
-      return bytes[bytesOffset + index];
-    }
-
-    @Override
-    byte internalByteAt(int index) {
-      return bytes[bytesOffset + index];
-    }
-
-    @Override
-    public int size() {
-      return bytesLength;
-    }
-
-    @Override
-    protected int getOffsetIntoBytes() {
-      return bytesOffset;
-    }
-
-    // =================================================================
-    // ByteString -> byte[]
-
-    @Override
-    protected void copyToInternal(
-        byte[] target, int sourceOffset, int targetOffset, int numberToCopy) {
-      System.arraycopy(
-          bytes, getOffsetIntoBytes() + sourceOffset, target, targetOffset, numberToCopy);
-    }
-
-    // =================================================================
-    // Serializable
-
-    private static final long serialVersionUID = 1L;
-
-    Object writeReplace() {
-      return ByteString.wrap(toByteArray());
-    }
-
-    private void readObject(@SuppressWarnings("unused") ObjectInputStream in) throws IOException {
-      throw new InvalidObjectException(
-          "BoundedByteStream instances are not to be serialized directly");
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/BytesValue.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/BytesValue.java
deleted file mode 100644
index c8e2c21..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/BytesValue.java
+++ /dev/null
@@ -1,278 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/wrappers.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * Wrapper message for `bytes`.
- * The JSON representation for `BytesValue` is JSON string.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.BytesValue}
- */
-public  final class BytesValue extends
-    com.google.protobuf.GeneratedMessageLite<
-        BytesValue, BytesValue.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.BytesValue)
-    BytesValueOrBuilder {
-  private BytesValue() {
-    value_ = com.google.protobuf.ByteString.EMPTY;
-  }
-  public static final int VALUE_FIELD_NUMBER = 1;
-  private com.google.protobuf.ByteString value_;
-  /**
-   * <pre>
-   * The bytes value.
-   * </pre>
-   *
-   * <code>bytes value = 1;</code>
-   * @return The value.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString getValue() {
-    return value_;
-  }
-  /**
-   * <pre>
-   * The bytes value.
-   * </pre>
-   *
-   * <code>bytes value = 1;</code>
-   * @param value The value to set.
-   */
-  private void setValue(com.google.protobuf.ByteString value) {
-    value.getClass();
-  
-    value_ = value;
-  }
-  /**
-   * <pre>
-   * The bytes value.
-   * </pre>
-   *
-   * <code>bytes value = 1;</code>
-   */
-  private void clearValue() {
-    
-    value_ = getDefaultInstance().getValue();
-  }
-
-  public static com.google.protobuf.BytesValue parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.BytesValue parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.BytesValue parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.BytesValue parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.BytesValue parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.BytesValue parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.BytesValue parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.BytesValue parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.BytesValue parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.BytesValue parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.BytesValue parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.BytesValue parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.BytesValue prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * Wrapper message for `bytes`.
-   * The JSON representation for `BytesValue` is JSON string.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.BytesValue}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.BytesValue, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.BytesValue)
-      com.google.protobuf.BytesValueOrBuilder {
-    // Construct using com.google.protobuf.BytesValue.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * The bytes value.
-     * </pre>
-     *
-     * <code>bytes value = 1;</code>
-     * @return The value.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getValue() {
-      return instance.getValue();
-    }
-    /**
-     * <pre>
-     * The bytes value.
-     * </pre>
-     *
-     * <code>bytes value = 1;</code>
-     * @param value The value to set.
-     * @return This builder for chaining.
-     */
-    public Builder setValue(com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The bytes value.
-     * </pre>
-     *
-     * <code>bytes value = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearValue() {
-      copyOnWrite();
-      instance.clearValue();
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.BytesValue)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.BytesValue();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "value_",
-          };
-          java.lang.String info =
-              "\u0000\u0001\u0000\u0000\u0001\u0001\u0001\u0000\u0000\u0000\u0001\n";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.BytesValue> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.BytesValue.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.BytesValue>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.BytesValue)
-  private static final com.google.protobuf.BytesValue DEFAULT_INSTANCE;
-  static {
-    BytesValue defaultInstance = new BytesValue();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      BytesValue.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.BytesValue getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  public static com.google.protobuf.BytesValue of(com.google.protobuf.ByteString value) {
-    return newBuilder().setValue(value).build();
-  }
-
-  private static volatile com.google.protobuf.Parser<BytesValue> PARSER;
-
-  public static com.google.protobuf.Parser<BytesValue> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/BytesValueOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/BytesValueOrBuilder.java
deleted file mode 100644
index 3adef62..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/BytesValueOrBuilder.java
+++ /dev/null
@@ -1,19 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/wrappers.proto
-
-package com.google.protobuf;
-
-public interface BytesValueOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.BytesValue)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * The bytes value.
-   * </pre>
-   *
-   * <code>bytes value = 1;</code>
-   * @return The value.
-   */
-  com.google.protobuf.ByteString getValue();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/CodedInputStream.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/CodedInputStream.java
deleted file mode 100644
index 00be6f0..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/CodedInputStream.java
+++ /dev/null
@@ -1,3964 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.Internal.EMPTY_BYTE_ARRAY;
-import static com.google.protobuf.Internal.EMPTY_BYTE_BUFFER;
-import static com.google.protobuf.Internal.UTF_8;
-import static com.google.protobuf.Internal.checkNotNull;
-import static com.google.protobuf.WireFormat.FIXED32_SIZE;
-import static com.google.protobuf.WireFormat.FIXED64_SIZE;
-import static com.google.protobuf.WireFormat.MAX_VARINT_SIZE;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Reads and decodes protocol message fields.
- *
- * <p>This class contains two kinds of methods: methods that read specific protocol message
- * constructs and field types (e.g. {@link #readTag()} and {@link #readInt32()}) and methods that
- * read low-level values (e.g. {@link #readRawVarint32()} and {@link #readRawBytes}). If you are
- * reading encoded protocol messages, you should use the former methods, but if you are reading some
- * other format of your own design, use the latter.
- *
- * @author kenton@google.com Kenton Varda
- */
-public abstract class CodedInputStream {
-  private static final int DEFAULT_BUFFER_SIZE = 4096;
-  private static final int DEFAULT_RECURSION_LIMIT = 100;
-  // Integer.MAX_VALUE == 0x7FFFFFF == INT_MAX from limits.h
-  private static final int DEFAULT_SIZE_LIMIT = Integer.MAX_VALUE;
-
-  /** Visible for subclasses. See setRecursionLimit() */
-  int recursionDepth;
-
-  int recursionLimit = DEFAULT_RECURSION_LIMIT;
-
-  /** Visible for subclasses. See setSizeLimit() */
-  int sizeLimit = DEFAULT_SIZE_LIMIT;
-
-  /** Used to adapt to the experimental {@link Reader} interface. */
-  CodedInputStreamReader wrapper;
-
-  /** Create a new CodedInputStream wrapping the given InputStream. */
-  public static CodedInputStream newInstance(final InputStream input) {
-    return newInstance(input, DEFAULT_BUFFER_SIZE);
-  }
-
-  /** Create a new CodedInputStream wrapping the given InputStream, with a specified buffer size. */
-  public static CodedInputStream newInstance(final InputStream input, int bufferSize) {
-    if (bufferSize <= 0) {
-      throw new IllegalArgumentException("bufferSize must be > 0");
-    }
-    if (input == null) {
-      // TODO(nathanmittler): Ideally we should throw here. This is done for backward compatibility.
-      return newInstance(EMPTY_BYTE_ARRAY);
-    }
-    return new StreamDecoder(input, bufferSize);
-  }
-
-  /** Create a new CodedInputStream wrapping the given {@code Iterable <ByteBuffer>}. */
-  public static CodedInputStream newInstance(final Iterable<ByteBuffer> input) {
-    if (!UnsafeDirectNioDecoder.isSupported()) {
-      return newInstance(new IterableByteBufferInputStream(input));
-    }
-    return newInstance(input, false);
-  }
-
-  /** Create a new CodedInputStream wrapping the given {@code Iterable <ByteBuffer>}. */
-  static CodedInputStream newInstance(
-      final Iterable<ByteBuffer> bufs, final boolean bufferIsImmutable) {
-    // flag is to check the type of input's ByteBuffers.
-    // flag equals 1: all ByteBuffers have array.
-    // flag equals 2: all ByteBuffers are direct ByteBuffers.
-    // flag equals 3: some ByteBuffers are direct and some have array.
-    // flag greater than 3: other cases.
-    int flag = 0;
-    // Total size of the input
-    int totalSize = 0;
-    for (ByteBuffer buf : bufs) {
-      totalSize += buf.remaining();
-      if (buf.hasArray()) {
-        flag |= 1;
-      } else if (buf.isDirect()) {
-        flag |= 2;
-      } else {
-        flag |= 4;
-      }
-    }
-    if (flag == 2) {
-      return new IterableDirectByteBufferDecoder(bufs, totalSize, bufferIsImmutable);
-    } else {
-      // TODO(yilunchong): add another decoders to deal case 1 and 3.
-      return newInstance(new IterableByteBufferInputStream(bufs));
-    }
-  }
-
-  /** Create a new CodedInputStream wrapping the given byte array. */
-  public static CodedInputStream newInstance(final byte[] buf) {
-    return newInstance(buf, 0, buf.length);
-  }
-
-  /** Create a new CodedInputStream wrapping the given byte array slice. */
-  public static CodedInputStream newInstance(final byte[] buf, final int off, final int len) {
-    return newInstance(buf, off, len, /* bufferIsImmutable= */ false);
-  }
-
-  /** Create a new CodedInputStream wrapping the given byte array slice. */
-  static CodedInputStream newInstance(
-      final byte[] buf, final int off, final int len, final boolean bufferIsImmutable) {
-    ArrayDecoder result = new ArrayDecoder(buf, off, len, bufferIsImmutable);
-    try {
-      // Some uses of CodedInputStream can be more efficient if they know
-      // exactly how many bytes are available.  By pushing the end point of the
-      // buffer as a limit, we allow them to get this information via
-      // getBytesUntilLimit().  Pushing a limit that we know is at the end of
-      // the stream can never hurt, since we can never past that point anyway.
-      result.pushLimit(len);
-    } catch (InvalidProtocolBufferException ex) {
-      // The only reason pushLimit() might throw an exception here is if len
-      // is negative. Normally pushLimit()'s parameter comes directly off the
-      // wire, so it's important to catch exceptions in case of corrupt or
-      // malicious data. However, in this case, we expect that len is not a
-      // user-supplied value, so we can assume that it being negative indicates
-      // a programming error. Therefore, throwing an unchecked exception is
-      // appropriate.
-      throw new IllegalArgumentException(ex);
-    }
-    return result;
-  }
-
-  /**
-   * Create a new CodedInputStream wrapping the given ByteBuffer. The data starting from the
-   * ByteBuffer's current position to its limit will be read. The returned CodedInputStream may or
-   * may not share the underlying data in the ByteBuffer, therefore the ByteBuffer cannot be changed
-   * while the CodedInputStream is in use. Note that the ByteBuffer's position won't be changed by
-   * this function. Concurrent calls with the same ByteBuffer object are safe if no other thread is
-   * trying to alter the ByteBuffer's status.
-   */
-  public static CodedInputStream newInstance(ByteBuffer buf) {
-    return newInstance(buf, /* bufferIsImmutable= */ false);
-  }
-
-  /** Create a new CodedInputStream wrapping the given buffer. */
-  static CodedInputStream newInstance(ByteBuffer buf, boolean bufferIsImmutable) {
-    if (buf.hasArray()) {
-      return newInstance(
-          buf.array(), buf.arrayOffset() + buf.position(), buf.remaining(), bufferIsImmutable);
-    }
-
-    if (buf.isDirect() && UnsafeDirectNioDecoder.isSupported()) {
-      return new UnsafeDirectNioDecoder(buf, bufferIsImmutable);
-    }
-
-    // The buffer is non-direct and does not expose the underlying array. Using the ByteBuffer API
-    // to access individual bytes is very slow, so just copy the buffer to an array.
-    // TODO(nathanmittler): Re-evaluate with Java 9
-    byte[] buffer = new byte[buf.remaining()];
-    buf.duplicate().get(buffer);
-    return newInstance(buffer, 0, buffer.length, true);
-  }
-
-  /** Disable construction/inheritance outside of this class. */
-  private CodedInputStream() {}
-
-  // -----------------------------------------------------------------
-
-  /**
-   * Attempt to read a field tag, returning zero if we have reached EOF. Protocol message parsers
-   * use this to read tags, since a protocol message may legally end wherever a tag occurs, and zero
-   * is not a valid tag number.
-   */
-  public abstract int readTag() throws IOException;
-
-  /**
-   * Verifies that the last call to readTag() returned the given tag value. This is used to verify
-   * that a nested group ended with the correct end tag.
-   *
-   * @throws InvalidProtocolBufferException {@code value} does not match the last tag.
-   */
-  public abstract void checkLastTagWas(final int value) throws InvalidProtocolBufferException;
-
-  public abstract int getLastTag();
-
-  /**
-   * Reads and discards a single field, given its tag value.
-   *
-   * @return {@code false} if the tag is an endgroup tag, in which case nothing is skipped.
-   *     Otherwise, returns {@code true}.
-   */
-  public abstract boolean skipField(final int tag) throws IOException;
-
-  /**
-   * Reads a single field and writes it to output in wire format, given its tag value.
-   *
-   * @return {@code false} if the tag is an endgroup tag, in which case nothing is skipped.
-   *     Otherwise, returns {@code true}.
-   * @deprecated use {@code UnknownFieldSet} or {@code UnknownFieldSetLite} to skip to an output
-   *     stream.
-   */
-  @Deprecated
-  public abstract boolean skipField(final int tag, final CodedOutputStream output)
-      throws IOException;
-
-  /**
-   * Reads and discards an entire message. This will read either until EOF or until an endgroup tag,
-   * whichever comes first.
-   */
-  public abstract void skipMessage() throws IOException;
-
-  /**
-   * Reads an entire message and writes it to output in wire format. This will read either until EOF
-   * or until an endgroup tag, whichever comes first.
-   */
-  public abstract void skipMessage(CodedOutputStream output) throws IOException;
-
-
-  // -----------------------------------------------------------------
-
-  /** Read a {@code double} field value from the stream. */
-  public abstract double readDouble() throws IOException;
-
-  /** Read a {@code float} field value from the stream. */
-  public abstract float readFloat() throws IOException;
-
-  /** Read a {@code uint64} field value from the stream. */
-  public abstract long readUInt64() throws IOException;
-
-  /** Read an {@code int64} field value from the stream. */
-  public abstract long readInt64() throws IOException;
-
-  /** Read an {@code int32} field value from the stream. */
-  public abstract int readInt32() throws IOException;
-
-  /** Read a {@code fixed64} field value from the stream. */
-  public abstract long readFixed64() throws IOException;
-
-  /** Read a {@code fixed32} field value from the stream. */
-  public abstract int readFixed32() throws IOException;
-
-  /** Read a {@code bool} field value from the stream. */
-  public abstract boolean readBool() throws IOException;
-
-  /**
-   * Read a {@code string} field value from the stream. If the stream contains malformed UTF-8,
-   * replace the offending bytes with the standard UTF-8 replacement character.
-   */
-  public abstract String readString() throws IOException;
-
-  /**
-   * Read a {@code string} field value from the stream. If the stream contains malformed UTF-8,
-   * throw exception {@link InvalidProtocolBufferException}.
-   */
-  public abstract String readStringRequireUtf8() throws IOException;
-
-  /** Read a {@code group} field value from the stream. */
-  public abstract void readGroup(
-      final int fieldNumber,
-      final MessageLite.Builder builder,
-      final ExtensionRegistryLite extensionRegistry)
-      throws IOException;
-
-
-  /** Read a {@code group} field value from the stream. */
-  public abstract <T extends MessageLite> T readGroup(
-      final int fieldNumber, final Parser<T> parser, final ExtensionRegistryLite extensionRegistry)
-      throws IOException;
-
-  /**
-   * Reads a {@code group} field value from the stream and merges it into the given {@link
-   * UnknownFieldSet}.
-   *
-   * @deprecated UnknownFieldSet.Builder now implements MessageLite.Builder, so you can just call
-   *     {@link #readGroup}.
-   */
-  @Deprecated
-  public abstract void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
-      throws IOException;
-
-  /** Read an embedded message field value from the stream. */
-  public abstract void readMessage(
-      final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
-      throws IOException;
-
-
-  /** Read an embedded message field value from the stream. */
-  public abstract <T extends MessageLite> T readMessage(
-      final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException;
-
-  /** Read a {@code bytes} field value from the stream. */
-  public abstract ByteString readBytes() throws IOException;
-
-  /** Read a {@code bytes} field value from the stream. */
-  public abstract byte[] readByteArray() throws IOException;
-
-  /** Read a {@code bytes} field value from the stream. */
-  public abstract ByteBuffer readByteBuffer() throws IOException;
-
-  /** Read a {@code uint32} field value from the stream. */
-  public abstract int readUInt32() throws IOException;
-
-  /**
-   * Read an enum field value from the stream. Caller is responsible for converting the numeric
-   * value to an actual enum.
-   */
-  public abstract int readEnum() throws IOException;
-
-  /** Read an {@code sfixed32} field value from the stream. */
-  public abstract int readSFixed32() throws IOException;
-
-  /** Read an {@code sfixed64} field value from the stream. */
-  public abstract long readSFixed64() throws IOException;
-
-  /** Read an {@code sint32} field value from the stream. */
-  public abstract int readSInt32() throws IOException;
-
-  /** Read an {@code sint64} field value from the stream. */
-  public abstract long readSInt64() throws IOException;
-
-  // =================================================================
-
-  /** Read a raw Varint from the stream. If larger than 32 bits, discard the upper bits. */
-  public abstract int readRawVarint32() throws IOException;
-
-  /** Read a raw Varint from the stream. */
-  public abstract long readRawVarint64() throws IOException;
-
-  /** Variant of readRawVarint64 for when uncomfortably close to the limit. */
-  /* Visible for testing */
-  abstract long readRawVarint64SlowPath() throws IOException;
-
-  /** Read a 32-bit little-endian integer from the stream. */
-  public abstract int readRawLittleEndian32() throws IOException;
-
-  /** Read a 64-bit little-endian integer from the stream. */
-  public abstract long readRawLittleEndian64() throws IOException;
-
-  // -----------------------------------------------------------------
-
-  /**
-   * Enables {@link ByteString} aliasing of the underlying buffer, trading off on buffer pinning for
-   * data copies. Only valid for buffer-backed streams.
-   */
-  public abstract void enableAliasing(boolean enabled);
-
-  /**
-   * Set the maximum message recursion depth. In order to prevent malicious messages from causing
-   * stack overflows, {@code CodedInputStream} limits how deeply messages may be nested. The default
-   * limit is 100.
-   *
-   * @return the old limit.
-   */
-  public final int setRecursionLimit(final int limit) {
-    if (limit < 0) {
-      throw new IllegalArgumentException("Recursion limit cannot be negative: " + limit);
-    }
-    final int oldLimit = recursionLimit;
-    recursionLimit = limit;
-    return oldLimit;
-  }
-
-  /**
-   * Only valid for {@link InputStream}-backed streams.
-   *
-   * <p>Set the maximum message size. In order to prevent malicious messages from exhausting memory
-   * or causing integer overflows, {@code CodedInputStream} limits how large a message may be. The
-   * default limit is {@code Integer.MAX_INT}. You should set this limit as small as you can without
-   * harming your app's functionality. Note that size limits only apply when reading from an {@code
-   * InputStream}, not when constructed around a raw byte array.
-   *
-   * <p>If you want to read several messages from a single CodedInputStream, you could call {@link
-   * #resetSizeCounter()} after each one to avoid hitting the size limit.
-   *
-   * @return the old limit.
-   */
-  public final int setSizeLimit(final int limit) {
-    if (limit < 0) {
-      throw new IllegalArgumentException("Size limit cannot be negative: " + limit);
-    }
-    final int oldLimit = sizeLimit;
-    sizeLimit = limit;
-    return oldLimit;
-  }
-
-  private boolean shouldDiscardUnknownFields = false;
-
-  /**
-   * Sets this {@code CodedInputStream} to discard unknown fields. Only applies to full runtime
-   * messages; lite messages will always preserve unknowns.
-   *
-   * <p>Note calling this function alone will have NO immediate effect on the underlying input data.
-   * The unknown fields will be discarded during parsing. This affects both Proto2 and Proto3 full
-   * runtime.
-   */
-  final void discardUnknownFields() {
-    shouldDiscardUnknownFields = true;
-  }
-
-  /**
-   * Reverts the unknown fields preservation behavior for Proto2 and Proto3 full runtime to their
-   * default.
-   */
-  final void unsetDiscardUnknownFields() {
-    shouldDiscardUnknownFields = false;
-  }
-
-  /**
-   * Whether unknown fields in this input stream should be discarded during parsing into full
-   * runtime messages.
-   */
-  final boolean shouldDiscardUnknownFields() {
-    return shouldDiscardUnknownFields;
-  }
-
-  /**
-   * Resets the current size counter to zero (see {@link #setSizeLimit(int)}). Only valid for {@link
-   * InputStream}-backed streams.
-   */
-  public abstract void resetSizeCounter();
-
-  /**
-   * Sets {@code currentLimit} to (current position) + {@code byteLimit}. This is called when
-   * descending into a length-delimited embedded message.
-   *
-   * <p>Note that {@code pushLimit()} does NOT affect how many bytes the {@code CodedInputStream}
-   * reads from an underlying {@code InputStream} when refreshing its buffer. If you need to prevent
-   * reading past a certain point in the underlying {@code InputStream} (e.g. because you expect it
-   * to contain more data after the end of the message which you need to handle differently) then
-   * you must place a wrapper around your {@code InputStream} which limits the amount of data that
-   * can be read from it.
-   *
-   * @return the old limit.
-   */
-  public abstract int pushLimit(int byteLimit) throws InvalidProtocolBufferException;
-
-  /**
-   * Discards the current limit, returning to the previous limit.
-   *
-   * @param oldLimit The old limit, as returned by {@code pushLimit}.
-   */
-  public abstract void popLimit(final int oldLimit);
-
-  /**
-   * Returns the number of bytes to be read before the current limit. If no limit is set, returns
-   * -1.
-   */
-  public abstract int getBytesUntilLimit();
-
-  /**
-   * Returns true if the stream has reached the end of the input. This is the case if either the end
-   * of the underlying input source has been reached or if the stream has reached a limit created
-   * using {@link #pushLimit(int)}. This function may get blocked when using StreamDecoder as it
-   * invokes {@link StreamDecoder#tryRefillBuffer(int)} in this function which will try to read
-   * bytes from input.
-   */
-  public abstract boolean isAtEnd() throws IOException;
-
-  /**
-   * The total bytes read up to the current position. Calling {@link #resetSizeCounter()} resets
-   * this value to zero.
-   */
-  public abstract int getTotalBytesRead();
-
-  /**
-   * Read one byte from the input.
-   *
-   * @throws InvalidProtocolBufferException The end of the stream or the current limit was reached.
-   */
-  public abstract byte readRawByte() throws IOException;
-
-  /**
-   * Read a fixed size of bytes from the input.
-   *
-   * @throws InvalidProtocolBufferException The end of the stream or the current limit was reached.
-   */
-  public abstract byte[] readRawBytes(final int size) throws IOException;
-
-  /**
-   * Reads and discards {@code size} bytes.
-   *
-   * @throws InvalidProtocolBufferException The end of the stream or the current limit was reached.
-   */
-  public abstract void skipRawBytes(final int size) throws IOException;
-
-  /**
-   * Decode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers into values that can be
-   * efficiently encoded with varint. (Otherwise, negative values must be sign-extended to 64 bits
-   * to be varint encoded, thus always taking 10 bytes on the wire.)
-   *
-   * @param n An unsigned 32-bit integer, stored in a signed int because Java has no explicit
-   *     unsigned support.
-   * @return A signed 32-bit integer.
-   */
-  public static int decodeZigZag32(final int n) {
-    return (n >>> 1) ^ -(n & 1);
-  }
-
-  /**
-   * Decode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers into values that can be
-   * efficiently encoded with varint. (Otherwise, negative values must be sign-extended to 64 bits
-   * to be varint encoded, thus always taking 10 bytes on the wire.)
-   *
-   * @param n An unsigned 64-bit integer, stored in a signed int because Java has no explicit
-   *     unsigned support.
-   * @return A signed 64-bit integer.
-   */
-  public static long decodeZigZag64(final long n) {
-    return (n >>> 1) ^ -(n & 1);
-  }
-
-  /**
-   * Like {@link #readRawVarint32(InputStream)}, but expects that the caller has already read one
-   * byte. This allows the caller to determine if EOF has been reached before attempting to read.
-   */
-  public static int readRawVarint32(final int firstByte, final InputStream input)
-      throws IOException {
-    if ((firstByte & 0x80) == 0) {
-      return firstByte;
-    }
-
-    int result = firstByte & 0x7f;
-    int offset = 7;
-    for (; offset < 32; offset += 7) {
-      final int b = input.read();
-      if (b == -1) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-      result |= (b & 0x7f) << offset;
-      if ((b & 0x80) == 0) {
-        return result;
-      }
-    }
-    // Keep reading up to 64 bits.
-    for (; offset < 64; offset += 7) {
-      final int b = input.read();
-      if (b == -1) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-      if ((b & 0x80) == 0) {
-        return result;
-      }
-    }
-    throw InvalidProtocolBufferException.malformedVarint();
-  }
-
-  /**
-   * Reads a varint from the input one byte at a time, so that it does not read any bytes after the
-   * end of the varint. If you simply wrapped the stream in a CodedInputStream and used {@link
-   * #readRawVarint32(InputStream)} then you would probably end up reading past the end of the
-   * varint since CodedInputStream buffers its input.
-   */
-  static int readRawVarint32(final InputStream input) throws IOException {
-    final int firstByte = input.read();
-    if (firstByte == -1) {
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-    return readRawVarint32(firstByte, input);
-  }
-
-  /** A {@link CodedInputStream} implementation that uses a backing array as the input. */
-  private static final class ArrayDecoder extends CodedInputStream {
-    private final byte[] buffer;
-    private final boolean immutable;
-    private int limit;
-    private int bufferSizeAfterLimit;
-    private int pos;
-    private int startPos;
-    private int lastTag;
-    private boolean enableAliasing;
-
-    /** The absolute position of the end of the current message. */
-    private int currentLimit = Integer.MAX_VALUE;
-
-    private ArrayDecoder(final byte[] buffer, final int offset, final int len, boolean immutable) {
-      this.buffer = buffer;
-      limit = offset + len;
-      pos = offset;
-      startPos = pos;
-      this.immutable = immutable;
-    }
-
-    @Override
-    public int readTag() throws IOException {
-      if (isAtEnd()) {
-        lastTag = 0;
-        return 0;
-      }
-
-      lastTag = readRawVarint32();
-      if (WireFormat.getTagFieldNumber(lastTag) == 0) {
-        // If we actually read zero (or any tag number corresponding to field
-        // number zero), that's not a valid tag.
-        throw InvalidProtocolBufferException.invalidTag();
-      }
-      return lastTag;
-    }
-
-    @Override
-    public void checkLastTagWas(final int value) throws InvalidProtocolBufferException {
-      if (lastTag != value) {
-        throw InvalidProtocolBufferException.invalidEndTag();
-      }
-    }
-
-    @Override
-    public int getLastTag() {
-      return lastTag;
-    }
-
-    @Override
-    public boolean skipField(final int tag) throws IOException {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WireFormat.WIRETYPE_VARINT:
-          skipRawVarint();
-          return true;
-        case WireFormat.WIRETYPE_FIXED64:
-          skipRawBytes(FIXED64_SIZE);
-          return true;
-        case WireFormat.WIRETYPE_LENGTH_DELIMITED:
-          skipRawBytes(readRawVarint32());
-          return true;
-        case WireFormat.WIRETYPE_START_GROUP:
-          skipMessage();
-          checkLastTagWas(
-              WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));
-          return true;
-        case WireFormat.WIRETYPE_END_GROUP:
-          return false;
-        case WireFormat.WIRETYPE_FIXED32:
-          skipRawBytes(FIXED32_SIZE);
-          return true;
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-
-    @Override
-    public boolean skipField(final int tag, final CodedOutputStream output) throws IOException {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WireFormat.WIRETYPE_VARINT:
-          {
-            long value = readInt64();
-            output.writeRawVarint32(tag);
-            output.writeUInt64NoTag(value);
-            return true;
-          }
-        case WireFormat.WIRETYPE_FIXED64:
-          {
-            long value = readRawLittleEndian64();
-            output.writeRawVarint32(tag);
-            output.writeFixed64NoTag(value);
-            return true;
-          }
-        case WireFormat.WIRETYPE_LENGTH_DELIMITED:
-          {
-            ByteString value = readBytes();
-            output.writeRawVarint32(tag);
-            output.writeBytesNoTag(value);
-            return true;
-          }
-        case WireFormat.WIRETYPE_START_GROUP:
-          {
-            output.writeRawVarint32(tag);
-            skipMessage(output);
-            int endtag =
-                WireFormat.makeTag(
-                    WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP);
-            checkLastTagWas(endtag);
-            output.writeRawVarint32(endtag);
-            return true;
-          }
-        case WireFormat.WIRETYPE_END_GROUP:
-          {
-            return false;
-          }
-        case WireFormat.WIRETYPE_FIXED32:
-          {
-            int value = readRawLittleEndian32();
-            output.writeRawVarint32(tag);
-            output.writeFixed32NoTag(value);
-            return true;
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-
-    @Override
-    public void skipMessage() throws IOException {
-      while (true) {
-        final int tag = readTag();
-        if (tag == 0 || !skipField(tag)) {
-          return;
-        }
-      }
-    }
-
-    @Override
-    public void skipMessage(CodedOutputStream output) throws IOException {
-      while (true) {
-        final int tag = readTag();
-        if (tag == 0 || !skipField(tag, output)) {
-          return;
-        }
-      }
-    }
-
-
-    // -----------------------------------------------------------------
-
-    @Override
-    public double readDouble() throws IOException {
-      return Double.longBitsToDouble(readRawLittleEndian64());
-    }
-
-    @Override
-    public float readFloat() throws IOException {
-      return Float.intBitsToFloat(readRawLittleEndian32());
-    }
-
-    @Override
-    public long readUInt64() throws IOException {
-      return readRawVarint64();
-    }
-
-    @Override
-    public long readInt64() throws IOException {
-      return readRawVarint64();
-    }
-
-    @Override
-    public int readInt32() throws IOException {
-      return readRawVarint32();
-    }
-
-    @Override
-    public long readFixed64() throws IOException {
-      return readRawLittleEndian64();
-    }
-
-    @Override
-    public int readFixed32() throws IOException {
-      return readRawLittleEndian32();
-    }
-
-    @Override
-    public boolean readBool() throws IOException {
-      return readRawVarint64() != 0;
-    }
-
-    @Override
-    public String readString() throws IOException {
-      final int size = readRawVarint32();
-      if (size > 0 && size <= (limit - pos)) {
-        // Fast path:  We already have the bytes in a contiguous buffer, so
-        //   just copy directly from it.
-        final String result = new String(buffer, pos, size, UTF_8);
-        pos += size;
-        return result;
-      }
-
-      if (size == 0) {
-        return "";
-      }
-      if (size < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-
-    @Override
-    public String readStringRequireUtf8() throws IOException {
-      final int size = readRawVarint32();
-      if (size > 0 && size <= (limit - pos)) {
-        String result = Utf8.decodeUtf8(buffer, pos, size);
-        pos += size;
-        return result;
-      }
-
-      if (size == 0) {
-        return "";
-      }
-      if (size <= 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-
-    @Override
-    public void readGroup(
-        final int fieldNumber,
-        final MessageLite.Builder builder,
-        final ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.recursionLimitExceeded();
-      }
-      ++recursionDepth;
-      builder.mergeFrom(this, extensionRegistry);
-      checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
-      --recursionDepth;
-    }
-
-
-    @Override
-    public <T extends MessageLite> T readGroup(
-        final int fieldNumber,
-        final Parser<T> parser,
-        final ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.recursionLimitExceeded();
-      }
-      ++recursionDepth;
-      T result = parser.parsePartialFrom(this, extensionRegistry);
-      checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
-      --recursionDepth;
-      return result;
-    }
-
-    @Deprecated
-    @Override
-    public void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
-        throws IOException {
-      readGroup(fieldNumber, builder, ExtensionRegistryLite.getEmptyRegistry());
-    }
-
-    @Override
-    public void readMessage(
-        final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      final int length = readRawVarint32();
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.recursionLimitExceeded();
-      }
-      final int oldLimit = pushLimit(length);
-      ++recursionDepth;
-      builder.mergeFrom(this, extensionRegistry);
-      checkLastTagWas(0);
-      --recursionDepth;
-      popLimit(oldLimit);
-    }
-
-
-    @Override
-    public <T extends MessageLite> T readMessage(
-        final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException {
-      int length = readRawVarint32();
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.recursionLimitExceeded();
-      }
-      final int oldLimit = pushLimit(length);
-      ++recursionDepth;
-      T result = parser.parsePartialFrom(this, extensionRegistry);
-      checkLastTagWas(0);
-      --recursionDepth;
-      popLimit(oldLimit);
-      return result;
-    }
-
-    @Override
-    public ByteString readBytes() throws IOException {
-      final int size = readRawVarint32();
-      if (size > 0 && size <= (limit - pos)) {
-        // Fast path:  We already have the bytes in a contiguous buffer, so
-        //   just copy directly from it.
-        final ByteString result =
-            immutable && enableAliasing
-                ? ByteString.wrap(buffer, pos, size)
-                : ByteString.copyFrom(buffer, pos, size);
-        pos += size;
-        return result;
-      }
-      if (size == 0) {
-        return ByteString.EMPTY;
-      }
-      // Slow path:  Build a byte array first then copy it.
-      return ByteString.wrap(readRawBytes(size));
-    }
-
-    @Override
-    public byte[] readByteArray() throws IOException {
-      final int size = readRawVarint32();
-      return readRawBytes(size);
-    }
-
-    @Override
-    public ByteBuffer readByteBuffer() throws IOException {
-      final int size = readRawVarint32();
-      if (size > 0 && size <= (limit - pos)) {
-        // Fast path: We already have the bytes in a contiguous buffer.
-        // When aliasing is enabled, we can return a ByteBuffer pointing directly
-        // into the underlying byte array without copy if the CodedInputStream is
-        // constructed from a byte array. If aliasing is disabled or the input is
-        // from an InputStream or ByteString, we have to make a copy of the bytes.
-        ByteBuffer result =
-            !immutable && enableAliasing
-                ? ByteBuffer.wrap(buffer, pos, size).slice()
-                : ByteBuffer.wrap(Arrays.copyOfRange(buffer, pos, pos + size));
-        pos += size;
-        // TODO(nathanmittler): Investigate making the ByteBuffer be made read-only
-        return result;
-      }
-
-      if (size == 0) {
-        return EMPTY_BYTE_BUFFER;
-      }
-      if (size < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-
-    @Override
-    public int readUInt32() throws IOException {
-      return readRawVarint32();
-    }
-
-    @Override
-    public int readEnum() throws IOException {
-      return readRawVarint32();
-    }
-
-    @Override
-    public int readSFixed32() throws IOException {
-      return readRawLittleEndian32();
-    }
-
-    @Override
-    public long readSFixed64() throws IOException {
-      return readRawLittleEndian64();
-    }
-
-    @Override
-    public int readSInt32() throws IOException {
-      return decodeZigZag32(readRawVarint32());
-    }
-
-    @Override
-    public long readSInt64() throws IOException {
-      return decodeZigZag64(readRawVarint64());
-    }
-
-    // =================================================================
-
-    @Override
-    public int readRawVarint32() throws IOException {
-      // See implementation notes for readRawVarint64
-      fastpath:
-      {
-        int tempPos = pos;
-
-        if (limit == tempPos) {
-          break fastpath;
-        }
-
-        final byte[] buffer = this.buffer;
-        int x;
-        if ((x = buffer[tempPos++]) >= 0) {
-          pos = tempPos;
-          return x;
-        } else if (limit - tempPos < 9) {
-          break fastpath;
-        } else if ((x ^= (buffer[tempPos++] << 7)) < 0) {
-          x ^= (~0 << 7);
-        } else if ((x ^= (buffer[tempPos++] << 14)) >= 0) {
-          x ^= (~0 << 7) ^ (~0 << 14);
-        } else if ((x ^= (buffer[tempPos++] << 21)) < 0) {
-          x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
-        } else {
-          int y = buffer[tempPos++];
-          x ^= y << 28;
-          x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
-          if (y < 0
-              && buffer[tempPos++] < 0
-              && buffer[tempPos++] < 0
-              && buffer[tempPos++] < 0
-              && buffer[tempPos++] < 0
-              && buffer[tempPos++] < 0) {
-            break fastpath; // Will throw malformedVarint()
-          }
-        }
-        pos = tempPos;
-        return x;
-      }
-      return (int) readRawVarint64SlowPath();
-    }
-
-    private void skipRawVarint() throws IOException {
-      if (limit - pos >= MAX_VARINT_SIZE) {
-        skipRawVarintFastPath();
-      } else {
-        skipRawVarintSlowPath();
-      }
-    }
-
-    private void skipRawVarintFastPath() throws IOException {
-      for (int i = 0; i < MAX_VARINT_SIZE; i++) {
-        if (buffer[pos++] >= 0) {
-          return;
-        }
-      }
-      throw InvalidProtocolBufferException.malformedVarint();
-    }
-
-    private void skipRawVarintSlowPath() throws IOException {
-      for (int i = 0; i < MAX_VARINT_SIZE; i++) {
-        if (readRawByte() >= 0) {
-          return;
-        }
-      }
-      throw InvalidProtocolBufferException.malformedVarint();
-    }
-
-    @Override
-    public long readRawVarint64() throws IOException {
-      // Implementation notes:
-      //
-      // Optimized for one-byte values, expected to be common.
-      // The particular code below was selected from various candidates
-      // empirically, by winning VarintBenchmark.
-      //
-      // Sign extension of (signed) Java bytes is usually a nuisance, but
-      // we exploit it here to more easily obtain the sign of bytes read.
-      // Instead of cleaning up the sign extension bits by masking eagerly,
-      // we delay until we find the final (positive) byte, when we clear all
-      // accumulated bits with one xor.  We depend on javac to constant fold.
-      fastpath:
-      {
-        int tempPos = pos;
-
-        if (limit == tempPos) {
-          break fastpath;
-        }
-
-        final byte[] buffer = this.buffer;
-        long x;
-        int y;
-        if ((y = buffer[tempPos++]) >= 0) {
-          pos = tempPos;
-          return y;
-        } else if (limit - tempPos < 9) {
-          break fastpath;
-        } else if ((y ^= (buffer[tempPos++] << 7)) < 0) {
-          x = y ^ (~0 << 7);
-        } else if ((y ^= (buffer[tempPos++] << 14)) >= 0) {
-          x = y ^ ((~0 << 7) ^ (~0 << 14));
-        } else if ((y ^= (buffer[tempPos++] << 21)) < 0) {
-          x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
-        } else if ((x = y ^ ((long) buffer[tempPos++] << 28)) >= 0L) {
-          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
-        } else if ((x ^= ((long) buffer[tempPos++] << 35)) < 0L) {
-          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
-        } else if ((x ^= ((long) buffer[tempPos++] << 42)) >= 0L) {
-          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
-        } else if ((x ^= ((long) buffer[tempPos++] << 49)) < 0L) {
-          x ^=
-              (~0L << 7)
-                  ^ (~0L << 14)
-                  ^ (~0L << 21)
-                  ^ (~0L << 28)
-                  ^ (~0L << 35)
-                  ^ (~0L << 42)
-                  ^ (~0L << 49);
-        } else {
-          x ^= ((long) buffer[tempPos++] << 56);
-          x ^=
-              (~0L << 7)
-                  ^ (~0L << 14)
-                  ^ (~0L << 21)
-                  ^ (~0L << 28)
-                  ^ (~0L << 35)
-                  ^ (~0L << 42)
-                  ^ (~0L << 49)
-                  ^ (~0L << 56);
-          if (x < 0L) {
-            if (buffer[tempPos++] < 0L) {
-              break fastpath; // Will throw malformedVarint()
-            }
-          }
-        }
-        pos = tempPos;
-        return x;
-      }
-      return readRawVarint64SlowPath();
-    }
-
-    @Override
-    long readRawVarint64SlowPath() throws IOException {
-      long result = 0;
-      for (int shift = 0; shift < 64; shift += 7) {
-        final byte b = readRawByte();
-        result |= (long) (b & 0x7F) << shift;
-        if ((b & 0x80) == 0) {
-          return result;
-        }
-      }
-      throw InvalidProtocolBufferException.malformedVarint();
-    }
-
-    @Override
-    public int readRawLittleEndian32() throws IOException {
-      int tempPos = pos;
-
-      if (limit - tempPos < FIXED32_SIZE) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-
-      final byte[] buffer = this.buffer;
-      pos = tempPos + FIXED32_SIZE;
-      return (((buffer[tempPos] & 0xff))
-          | ((buffer[tempPos + 1] & 0xff) << 8)
-          | ((buffer[tempPos + 2] & 0xff) << 16)
-          | ((buffer[tempPos + 3] & 0xff) << 24));
-    }
-
-    @Override
-    public long readRawLittleEndian64() throws IOException {
-      int tempPos = pos;
-
-      if (limit - tempPos < FIXED64_SIZE) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-
-      final byte[] buffer = this.buffer;
-      pos = tempPos + FIXED64_SIZE;
-      return (((buffer[tempPos] & 0xffL))
-          | ((buffer[tempPos + 1] & 0xffL) << 8)
-          | ((buffer[tempPos + 2] & 0xffL) << 16)
-          | ((buffer[tempPos + 3] & 0xffL) << 24)
-          | ((buffer[tempPos + 4] & 0xffL) << 32)
-          | ((buffer[tempPos + 5] & 0xffL) << 40)
-          | ((buffer[tempPos + 6] & 0xffL) << 48)
-          | ((buffer[tempPos + 7] & 0xffL) << 56));
-    }
-
-    @Override
-    public void enableAliasing(boolean enabled) {
-      this.enableAliasing = enabled;
-    }
-
-    @Override
-    public void resetSizeCounter() {
-      startPos = pos;
-    }
-
-    @Override
-    public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
-      if (byteLimit < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-      byteLimit += getTotalBytesRead();
-      final int oldLimit = currentLimit;
-      if (byteLimit > oldLimit) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-      currentLimit = byteLimit;
-
-      recomputeBufferSizeAfterLimit();
-
-      return oldLimit;
-    }
-
-    private void recomputeBufferSizeAfterLimit() {
-      limit += bufferSizeAfterLimit;
-      final int bufferEnd = limit - startPos;
-      if (bufferEnd > currentLimit) {
-        // Limit is in current buffer.
-        bufferSizeAfterLimit = bufferEnd - currentLimit;
-        limit -= bufferSizeAfterLimit;
-      } else {
-        bufferSizeAfterLimit = 0;
-      }
-    }
-
-    @Override
-    public void popLimit(final int oldLimit) {
-      currentLimit = oldLimit;
-      recomputeBufferSizeAfterLimit();
-    }
-
-    @Override
-    public int getBytesUntilLimit() {
-      if (currentLimit == Integer.MAX_VALUE) {
-        return -1;
-      }
-
-      return currentLimit - getTotalBytesRead();
-    }
-
-    @Override
-    public boolean isAtEnd() throws IOException {
-      return pos == limit;
-    }
-
-    @Override
-    public int getTotalBytesRead() {
-      return pos - startPos;
-    }
-
-    @Override
-    public byte readRawByte() throws IOException {
-      if (pos == limit) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-      return buffer[pos++];
-    }
-
-    @Override
-    public byte[] readRawBytes(final int length) throws IOException {
-      if (length > 0 && length <= (limit - pos)) {
-        final int tempPos = pos;
-        pos += length;
-        return Arrays.copyOfRange(buffer, tempPos, pos);
-      }
-
-      if (length <= 0) {
-        if (length == 0) {
-          return Internal.EMPTY_BYTE_ARRAY;
-        } else {
-          throw InvalidProtocolBufferException.negativeSize();
-        }
-      }
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-
-    @Override
-    public void skipRawBytes(final int length) throws IOException {
-      if (length >= 0 && length <= (limit - pos)) {
-        // We have all the bytes we need already.
-        pos += length;
-        return;
-      }
-
-      if (length < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-  }
-
-  /**
-   * A {@link CodedInputStream} implementation that uses a backing direct ByteBuffer as the input.
-   * Requires the use of {@code sun.misc.Unsafe} to perform fast reads on the buffer.
-   */
-  private static final class UnsafeDirectNioDecoder extends CodedInputStream {
-    /** The direct buffer that is backing this stream. */
-    private final ByteBuffer buffer;
-
-    /**
-     * If {@code true}, indicates that the buffer is backing a {@link ByteString} and is therefore
-     * considered to be an immutable input source.
-     */
-    private final boolean immutable;
-
-    /** The unsafe address of the content of {@link #buffer}. */
-    private final long address;
-
-    /** The unsafe address of the current read limit of the buffer. */
-    private long limit;
-
-    /** The unsafe address of the current read position of the buffer. */
-    private long pos;
-
-    /** The unsafe address of the starting read position. */
-    private long startPos;
-
-    /** The amount of available data in the buffer beyond {@link #limit}. */
-    private int bufferSizeAfterLimit;
-
-    /** The last tag that was read from this stream. */
-    private int lastTag;
-
-    /**
-     * If {@code true}, indicates that calls to read {@link ByteString} or {@code byte[]}
-     * <strong>may</strong> return slices of the underlying buffer, rather than copies.
-     */
-    private boolean enableAliasing;
-
-    /** The absolute position of the end of the current message. */
-    private int currentLimit = Integer.MAX_VALUE;
-
-    static boolean isSupported() {
-      return UnsafeUtil.hasUnsafeByteBufferOperations();
-    }
-
-    private UnsafeDirectNioDecoder(ByteBuffer buffer, boolean immutable) {
-      this.buffer = buffer;
-      address = UnsafeUtil.addressOffset(buffer);
-      limit = address + buffer.limit();
-      pos = address + buffer.position();
-      startPos = pos;
-      this.immutable = immutable;
-    }
-
-    @Override
-    public int readTag() throws IOException {
-      if (isAtEnd()) {
-        lastTag = 0;
-        return 0;
-      }
-
-      lastTag = readRawVarint32();
-      if (WireFormat.getTagFieldNumber(lastTag) == 0) {
-        // If we actually read zero (or any tag number corresponding to field
-        // number zero), that's not a valid tag.
-        throw InvalidProtocolBufferException.invalidTag();
-      }
-      return lastTag;
-    }
-
-    @Override
-    public void checkLastTagWas(final int value) throws InvalidProtocolBufferException {
-      if (lastTag != value) {
-        throw InvalidProtocolBufferException.invalidEndTag();
-      }
-    }
-
-    @Override
-    public int getLastTag() {
-      return lastTag;
-    }
-
-    @Override
-    public boolean skipField(final int tag) throws IOException {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WireFormat.WIRETYPE_VARINT:
-          skipRawVarint();
-          return true;
-        case WireFormat.WIRETYPE_FIXED64:
-          skipRawBytes(FIXED64_SIZE);
-          return true;
-        case WireFormat.WIRETYPE_LENGTH_DELIMITED:
-          skipRawBytes(readRawVarint32());
-          return true;
-        case WireFormat.WIRETYPE_START_GROUP:
-          skipMessage();
-          checkLastTagWas(
-              WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));
-          return true;
-        case WireFormat.WIRETYPE_END_GROUP:
-          return false;
-        case WireFormat.WIRETYPE_FIXED32:
-          skipRawBytes(FIXED32_SIZE);
-          return true;
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-
-    @Override
-    public boolean skipField(final int tag, final CodedOutputStream output) throws IOException {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WireFormat.WIRETYPE_VARINT:
-          {
-            long value = readInt64();
-            output.writeRawVarint32(tag);
-            output.writeUInt64NoTag(value);
-            return true;
-          }
-        case WireFormat.WIRETYPE_FIXED64:
-          {
-            long value = readRawLittleEndian64();
-            output.writeRawVarint32(tag);
-            output.writeFixed64NoTag(value);
-            return true;
-          }
-        case WireFormat.WIRETYPE_LENGTH_DELIMITED:
-          {
-            ByteString value = readBytes();
-            output.writeRawVarint32(tag);
-            output.writeBytesNoTag(value);
-            return true;
-          }
-        case WireFormat.WIRETYPE_START_GROUP:
-          {
-            output.writeRawVarint32(tag);
-            skipMessage(output);
-            int endtag =
-                WireFormat.makeTag(
-                    WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP);
-            checkLastTagWas(endtag);
-            output.writeRawVarint32(endtag);
-            return true;
-          }
-        case WireFormat.WIRETYPE_END_GROUP:
-          {
-            return false;
-          }
-        case WireFormat.WIRETYPE_FIXED32:
-          {
-            int value = readRawLittleEndian32();
-            output.writeRawVarint32(tag);
-            output.writeFixed32NoTag(value);
-            return true;
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-
-    @Override
-    public void skipMessage() throws IOException {
-      while (true) {
-        final int tag = readTag();
-        if (tag == 0 || !skipField(tag)) {
-          return;
-        }
-      }
-    }
-
-    @Override
-    public void skipMessage(CodedOutputStream output) throws IOException {
-      while (true) {
-        final int tag = readTag();
-        if (tag == 0 || !skipField(tag, output)) {
-          return;
-        }
-      }
-    }
-
-
-    // -----------------------------------------------------------------
-
-    @Override
-    public double readDouble() throws IOException {
-      return Double.longBitsToDouble(readRawLittleEndian64());
-    }
-
-    @Override
-    public float readFloat() throws IOException {
-      return Float.intBitsToFloat(readRawLittleEndian32());
-    }
-
-    @Override
-    public long readUInt64() throws IOException {
-      return readRawVarint64();
-    }
-
-    @Override
-    public long readInt64() throws IOException {
-      return readRawVarint64();
-    }
-
-    @Override
-    public int readInt32() throws IOException {
-      return readRawVarint32();
-    }
-
-    @Override
-    public long readFixed64() throws IOException {
-      return readRawLittleEndian64();
-    }
-
-    @Override
-    public int readFixed32() throws IOException {
-      return readRawLittleEndian32();
-    }
-
-    @Override
-    public boolean readBool() throws IOException {
-      return readRawVarint64() != 0;
-    }
-
-    @Override
-    public String readString() throws IOException {
-      final int size = readRawVarint32();
-      if (size > 0 && size <= remaining()) {
-        // TODO(nathanmittler): Is there a way to avoid this copy?
-        // TODO(anuraaga): It might be possible to share the optimized loop with
-        // readStringRequireUtf8 by implementing Java replacement logic there.
-        // The same as readBytes' logic
-        byte[] bytes = new byte[size];
-        UnsafeUtil.copyMemory(pos, bytes, 0, size);
-        String result = new String(bytes, UTF_8);
-        pos += size;
-        return result;
-      }
-
-      if (size == 0) {
-        return "";
-      }
-      if (size < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-
-    @Override
-    public String readStringRequireUtf8() throws IOException {
-      final int size = readRawVarint32();
-      if (size > 0 && size <= remaining()) {
-        final int bufferPos = bufferPos(pos);
-        String result = Utf8.decodeUtf8(buffer, bufferPos, size);
-        pos += size;
-        return result;
-      }
-
-      if (size == 0) {
-        return "";
-      }
-      if (size <= 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-
-    @Override
-    public void readGroup(
-        final int fieldNumber,
-        final MessageLite.Builder builder,
-        final ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.recursionLimitExceeded();
-      }
-      ++recursionDepth;
-      builder.mergeFrom(this, extensionRegistry);
-      checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
-      --recursionDepth;
-    }
-
-
-    @Override
-    public <T extends MessageLite> T readGroup(
-        final int fieldNumber,
-        final Parser<T> parser,
-        final ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.recursionLimitExceeded();
-      }
-      ++recursionDepth;
-      T result = parser.parsePartialFrom(this, extensionRegistry);
-      checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
-      --recursionDepth;
-      return result;
-    }
-
-    @Deprecated
-    @Override
-    public void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
-        throws IOException {
-      readGroup(fieldNumber, builder, ExtensionRegistryLite.getEmptyRegistry());
-    }
-
-    @Override
-    public void readMessage(
-        final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      final int length = readRawVarint32();
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.recursionLimitExceeded();
-      }
-      final int oldLimit = pushLimit(length);
-      ++recursionDepth;
-      builder.mergeFrom(this, extensionRegistry);
-      checkLastTagWas(0);
-      --recursionDepth;
-      popLimit(oldLimit);
-    }
-
-
-    @Override
-    public <T extends MessageLite> T readMessage(
-        final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException {
-      int length = readRawVarint32();
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.recursionLimitExceeded();
-      }
-      final int oldLimit = pushLimit(length);
-      ++recursionDepth;
-      T result = parser.parsePartialFrom(this, extensionRegistry);
-      checkLastTagWas(0);
-      --recursionDepth;
-      popLimit(oldLimit);
-      return result;
-    }
-
-    @Override
-    public ByteString readBytes() throws IOException {
-      final int size = readRawVarint32();
-      if (size > 0 && size <= remaining()) {
-        if (immutable && enableAliasing) {
-          final ByteBuffer result = slice(pos, pos + size);
-          pos += size;
-          return ByteString.wrap(result);
-        } else {
-          // Use UnsafeUtil to copy the memory to bytes instead of using ByteBuffer ways.
-          byte[] bytes = new byte[size];
-          UnsafeUtil.copyMemory(pos, bytes, 0, size);
-          pos += size;
-          return ByteString.wrap(bytes);
-        }
-      }
-
-      if (size == 0) {
-        return ByteString.EMPTY;
-      }
-      if (size < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-
-    @Override
-    public byte[] readByteArray() throws IOException {
-      return readRawBytes(readRawVarint32());
-    }
-
-    @Override
-    public ByteBuffer readByteBuffer() throws IOException {
-      final int size = readRawVarint32();
-      if (size > 0 && size <= remaining()) {
-        // "Immutable" implies that buffer is backing a ByteString.
-        // Disallow slicing in this case to prevent the caller from modifying the contents
-        // of the ByteString.
-        if (!immutable && enableAliasing) {
-          final ByteBuffer result = slice(pos, pos + size);
-          pos += size;
-          return result;
-        } else {
-          // The same as readBytes' logic
-          byte[] bytes = new byte[size];
-          UnsafeUtil.copyMemory(pos, bytes, 0, size);
-          pos += size;
-          return ByteBuffer.wrap(bytes);
-        }
-        // TODO(nathanmittler): Investigate making the ByteBuffer be made read-only
-      }
-
-      if (size == 0) {
-        return EMPTY_BYTE_BUFFER;
-      }
-      if (size < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-
-    @Override
-    public int readUInt32() throws IOException {
-      return readRawVarint32();
-    }
-
-    @Override
-    public int readEnum() throws IOException {
-      return readRawVarint32();
-    }
-
-    @Override
-    public int readSFixed32() throws IOException {
-      return readRawLittleEndian32();
-    }
-
-    @Override
-    public long readSFixed64() throws IOException {
-      return readRawLittleEndian64();
-    }
-
-    @Override
-    public int readSInt32() throws IOException {
-      return decodeZigZag32(readRawVarint32());
-    }
-
-    @Override
-    public long readSInt64() throws IOException {
-      return decodeZigZag64(readRawVarint64());
-    }
-
-    // =================================================================
-
-    @Override
-    public int readRawVarint32() throws IOException {
-      // See implementation notes for readRawVarint64
-      fastpath:
-      {
-        long tempPos = pos;
-
-        if (limit == tempPos) {
-          break fastpath;
-        }
-
-        int x;
-        if ((x = UnsafeUtil.getByte(tempPos++)) >= 0) {
-          pos = tempPos;
-          return x;
-        } else if (limit - tempPos < 9) {
-          break fastpath;
-        } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 7)) < 0) {
-          x ^= (~0 << 7);
-        } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 14)) >= 0) {
-          x ^= (~0 << 7) ^ (~0 << 14);
-        } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 21)) < 0) {
-          x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
-        } else {
-          int y = UnsafeUtil.getByte(tempPos++);
-          x ^= y << 28;
-          x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
-          if (y < 0
-              && UnsafeUtil.getByte(tempPos++) < 0
-              && UnsafeUtil.getByte(tempPos++) < 0
-              && UnsafeUtil.getByte(tempPos++) < 0
-              && UnsafeUtil.getByte(tempPos++) < 0
-              && UnsafeUtil.getByte(tempPos++) < 0) {
-            break fastpath; // Will throw malformedVarint()
-          }
-        }
-        pos = tempPos;
-        return x;
-      }
-      return (int) readRawVarint64SlowPath();
-    }
-
-    private void skipRawVarint() throws IOException {
-      if (remaining() >= MAX_VARINT_SIZE) {
-        skipRawVarintFastPath();
-      } else {
-        skipRawVarintSlowPath();
-      }
-    }
-
-    private void skipRawVarintFastPath() throws IOException {
-      for (int i = 0; i < MAX_VARINT_SIZE; i++) {
-        if (UnsafeUtil.getByte(pos++) >= 0) {
-          return;
-        }
-      }
-      throw InvalidProtocolBufferException.malformedVarint();
-    }
-
-    private void skipRawVarintSlowPath() throws IOException {
-      for (int i = 0; i < MAX_VARINT_SIZE; i++) {
-        if (readRawByte() >= 0) {
-          return;
-        }
-      }
-      throw InvalidProtocolBufferException.malformedVarint();
-    }
-
-    @Override
-    public long readRawVarint64() throws IOException {
-      // Implementation notes:
-      //
-      // Optimized for one-byte values, expected to be common.
-      // The particular code below was selected from various candidates
-      // empirically, by winning VarintBenchmark.
-      //
-      // Sign extension of (signed) Java bytes is usually a nuisance, but
-      // we exploit it here to more easily obtain the sign of bytes read.
-      // Instead of cleaning up the sign extension bits by masking eagerly,
-      // we delay until we find the final (positive) byte, when we clear all
-      // accumulated bits with one xor.  We depend on javac to constant fold.
-      fastpath:
-      {
-        long tempPos = pos;
-
-        if (limit == tempPos) {
-          break fastpath;
-        }
-
-        long x;
-        int y;
-        if ((y = UnsafeUtil.getByte(tempPos++)) >= 0) {
-          pos = tempPos;
-          return y;
-        } else if (limit - tempPos < 9) {
-          break fastpath;
-        } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 7)) < 0) {
-          x = y ^ (~0 << 7);
-        } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 14)) >= 0) {
-          x = y ^ ((~0 << 7) ^ (~0 << 14));
-        } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 21)) < 0) {
-          x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
-        } else if ((x = y ^ ((long) UnsafeUtil.getByte(tempPos++) << 28)) >= 0L) {
-          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
-        } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 35)) < 0L) {
-          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
-        } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 42)) >= 0L) {
-          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
-        } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 49)) < 0L) {
-          x ^=
-              (~0L << 7)
-                  ^ (~0L << 14)
-                  ^ (~0L << 21)
-                  ^ (~0L << 28)
-                  ^ (~0L << 35)
-                  ^ (~0L << 42)
-                  ^ (~0L << 49);
-        } else {
-          x ^= ((long) UnsafeUtil.getByte(tempPos++) << 56);
-          x ^=
-              (~0L << 7)
-                  ^ (~0L << 14)
-                  ^ (~0L << 21)
-                  ^ (~0L << 28)
-                  ^ (~0L << 35)
-                  ^ (~0L << 42)
-                  ^ (~0L << 49)
-                  ^ (~0L << 56);
-          if (x < 0L) {
-            if (UnsafeUtil.getByte(tempPos++) < 0L) {
-              break fastpath; // Will throw malformedVarint()
-            }
-          }
-        }
-        pos = tempPos;
-        return x;
-      }
-      return readRawVarint64SlowPath();
-    }
-
-    @Override
-    long readRawVarint64SlowPath() throws IOException {
-      long result = 0;
-      for (int shift = 0; shift < 64; shift += 7) {
-        final byte b = readRawByte();
-        result |= (long) (b & 0x7F) << shift;
-        if ((b & 0x80) == 0) {
-          return result;
-        }
-      }
-      throw InvalidProtocolBufferException.malformedVarint();
-    }
-
-    @Override
-    public int readRawLittleEndian32() throws IOException {
-      long tempPos = pos;
-
-      if (limit - tempPos < FIXED32_SIZE) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-
-      pos = tempPos + FIXED32_SIZE;
-      return (((UnsafeUtil.getByte(tempPos) & 0xff))
-          | ((UnsafeUtil.getByte(tempPos + 1) & 0xff) << 8)
-          | ((UnsafeUtil.getByte(tempPos + 2) & 0xff) << 16)
-          | ((UnsafeUtil.getByte(tempPos + 3) & 0xff) << 24));
-    }
-
-    @Override
-    public long readRawLittleEndian64() throws IOException {
-      long tempPos = pos;
-
-      if (limit - tempPos < FIXED64_SIZE) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-
-      pos = tempPos + FIXED64_SIZE;
-      return (((UnsafeUtil.getByte(tempPos) & 0xffL))
-          | ((UnsafeUtil.getByte(tempPos + 1) & 0xffL) << 8)
-          | ((UnsafeUtil.getByte(tempPos + 2) & 0xffL) << 16)
-          | ((UnsafeUtil.getByte(tempPos + 3) & 0xffL) << 24)
-          | ((UnsafeUtil.getByte(tempPos + 4) & 0xffL) << 32)
-          | ((UnsafeUtil.getByte(tempPos + 5) & 0xffL) << 40)
-          | ((UnsafeUtil.getByte(tempPos + 6) & 0xffL) << 48)
-          | ((UnsafeUtil.getByte(tempPos + 7) & 0xffL) << 56));
-    }
-
-    @Override
-    public void enableAliasing(boolean enabled) {
-      this.enableAliasing = enabled;
-    }
-
-    @Override
-    public void resetSizeCounter() {
-      startPos = pos;
-    }
-
-    @Override
-    public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
-      if (byteLimit < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-      byteLimit += getTotalBytesRead();
-      final int oldLimit = currentLimit;
-      if (byteLimit > oldLimit) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-      currentLimit = byteLimit;
-
-      recomputeBufferSizeAfterLimit();
-
-      return oldLimit;
-    }
-
-    @Override
-    public void popLimit(final int oldLimit) {
-      currentLimit = oldLimit;
-      recomputeBufferSizeAfterLimit();
-    }
-
-    @Override
-    public int getBytesUntilLimit() {
-      if (currentLimit == Integer.MAX_VALUE) {
-        return -1;
-      }
-
-      return currentLimit - getTotalBytesRead();
-    }
-
-    @Override
-    public boolean isAtEnd() throws IOException {
-      return pos == limit;
-    }
-
-    @Override
-    public int getTotalBytesRead() {
-      return (int) (pos - startPos);
-    }
-
-    @Override
-    public byte readRawByte() throws IOException {
-      if (pos == limit) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-      return UnsafeUtil.getByte(pos++);
-    }
-
-    @Override
-    public byte[] readRawBytes(final int length) throws IOException {
-      if (length >= 0 && length <= remaining()) {
-        byte[] bytes = new byte[length];
-        slice(pos, pos + length).get(bytes);
-        pos += length;
-        return bytes;
-      }
-
-      if (length <= 0) {
-        if (length == 0) {
-          return EMPTY_BYTE_ARRAY;
-        } else {
-          throw InvalidProtocolBufferException.negativeSize();
-        }
-      }
-
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-
-    @Override
-    public void skipRawBytes(final int length) throws IOException {
-      if (length >= 0 && length <= remaining()) {
-        // We have all the bytes we need already.
-        pos += length;
-        return;
-      }
-
-      if (length < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-
-    private void recomputeBufferSizeAfterLimit() {
-      limit += bufferSizeAfterLimit;
-      final int bufferEnd = (int) (limit - startPos);
-      if (bufferEnd > currentLimit) {
-        // Limit is in current buffer.
-        bufferSizeAfterLimit = bufferEnd - currentLimit;
-        limit -= bufferSizeAfterLimit;
-      } else {
-        bufferSizeAfterLimit = 0;
-      }
-    }
-
-    private int remaining() {
-      return (int) (limit - pos);
-    }
-
-    private int bufferPos(long pos) {
-      return (int) (pos - address);
-    }
-
-    private ByteBuffer slice(long begin, long end) throws IOException {
-      int prevPos = buffer.position();
-      int prevLimit = buffer.limit();
-      try {
-        ((Buffer) buffer).position(bufferPos(begin));
-        ((Buffer) buffer).limit(bufferPos(end));
-        return buffer.slice();
-      } catch (IllegalArgumentException e) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      } finally {
-        ((Buffer) buffer).position(prevPos);
-        ((Buffer) buffer).limit(prevLimit);
-      }
-    }
-  }
-
-  /**
-   * Implementation of {@link CodedInputStream} that uses an {@link InputStream} as the data source.
-   */
-  private static final class StreamDecoder extends CodedInputStream {
-    private final InputStream input;
-    private final byte[] buffer;
-    /** bufferSize represents how many bytes are currently filled in the buffer */
-    private int bufferSize;
-
-    private int bufferSizeAfterLimit;
-    private int pos;
-    private int lastTag;
-
-    /**
-     * The total number of bytes read before the current buffer. The total bytes read up to the
-     * current position can be computed as {@code totalBytesRetired + pos}. This value may be
-     * negative if reading started in the middle of the current buffer (e.g. if the constructor that
-     * takes a byte array and an offset was used).
-     */
-    private int totalBytesRetired;
-
-    /** The absolute position of the end of the current message. */
-    private int currentLimit = Integer.MAX_VALUE;
-
-    private StreamDecoder(final InputStream input, int bufferSize) {
-      checkNotNull(input, "input");
-      this.input = input;
-      this.buffer = new byte[bufferSize];
-      this.bufferSize = 0;
-      pos = 0;
-      totalBytesRetired = 0;
-    }
-
-    /*
-     * The following wrapper methods exist so that InvalidProtocolBufferExceptions thrown by the
-     * InputStream can be differentiated from ones thrown by CodedInputStream itself. Each call to
-     * an InputStream method that can throw IOException must be wrapped like this. We do this
-     * because we sometimes need to modify IPBE instances after they are thrown far away from where
-     * they are thrown (ex. to add unfinished messages) and we use this signal elsewhere in the
-     * exception catch chain to know when to perform these operations directly or to wrap the
-     * exception in their own IPBE so the extra information can be communicated without trampling
-     * downstream information.
-     */
-    private static int read(InputStream input, byte[] data, int offset, int length)
-        throws IOException {
-      try {
-        return input.read(data, offset, length);
-      } catch (InvalidProtocolBufferException e) {
-        e.setThrownFromInputStream();
-        throw e;
-      }
-    }
-
-    private static long skip(InputStream input, long length) throws IOException {
-      try {
-        return input.skip(length);
-      } catch (InvalidProtocolBufferException e) {
-        e.setThrownFromInputStream();
-        throw e;
-      }
-    }
-
-    private static int available(InputStream input) throws IOException {
-      try {
-        return input.available();
-      } catch (InvalidProtocolBufferException e) {
-        e.setThrownFromInputStream();
-        throw e;
-      }
-    }
-
-    @Override
-    public int readTag() throws IOException {
-      if (isAtEnd()) {
-        lastTag = 0;
-        return 0;
-      }
-
-      lastTag = readRawVarint32();
-      if (WireFormat.getTagFieldNumber(lastTag) == 0) {
-        // If we actually read zero (or any tag number corresponding to field
-        // number zero), that's not a valid tag.
-        throw InvalidProtocolBufferException.invalidTag();
-      }
-      return lastTag;
-    }
-
-    @Override
-    public void checkLastTagWas(final int value) throws InvalidProtocolBufferException {
-      if (lastTag != value) {
-        throw InvalidProtocolBufferException.invalidEndTag();
-      }
-    }
-
-    @Override
-    public int getLastTag() {
-      return lastTag;
-    }
-
-    @Override
-    public boolean skipField(final int tag) throws IOException {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WireFormat.WIRETYPE_VARINT:
-          skipRawVarint();
-          return true;
-        case WireFormat.WIRETYPE_FIXED64:
-          skipRawBytes(FIXED64_SIZE);
-          return true;
-        case WireFormat.WIRETYPE_LENGTH_DELIMITED:
-          skipRawBytes(readRawVarint32());
-          return true;
-        case WireFormat.WIRETYPE_START_GROUP:
-          skipMessage();
-          checkLastTagWas(
-              WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));
-          return true;
-        case WireFormat.WIRETYPE_END_GROUP:
-          return false;
-        case WireFormat.WIRETYPE_FIXED32:
-          skipRawBytes(FIXED32_SIZE);
-          return true;
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-
-    @Override
-    public boolean skipField(final int tag, final CodedOutputStream output) throws IOException {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WireFormat.WIRETYPE_VARINT:
-          {
-            long value = readInt64();
-            output.writeRawVarint32(tag);
-            output.writeUInt64NoTag(value);
-            return true;
-          }
-        case WireFormat.WIRETYPE_FIXED64:
-          {
-            long value = readRawLittleEndian64();
-            output.writeRawVarint32(tag);
-            output.writeFixed64NoTag(value);
-            return true;
-          }
-        case WireFormat.WIRETYPE_LENGTH_DELIMITED:
-          {
-            ByteString value = readBytes();
-            output.writeRawVarint32(tag);
-            output.writeBytesNoTag(value);
-            return true;
-          }
-        case WireFormat.WIRETYPE_START_GROUP:
-          {
-            output.writeRawVarint32(tag);
-            skipMessage(output);
-            int endtag =
-                WireFormat.makeTag(
-                    WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP);
-            checkLastTagWas(endtag);
-            output.writeRawVarint32(endtag);
-            return true;
-          }
-        case WireFormat.WIRETYPE_END_GROUP:
-          {
-            return false;
-          }
-        case WireFormat.WIRETYPE_FIXED32:
-          {
-            int value = readRawLittleEndian32();
-            output.writeRawVarint32(tag);
-            output.writeFixed32NoTag(value);
-            return true;
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-
-    @Override
-    public void skipMessage() throws IOException {
-      while (true) {
-        final int tag = readTag();
-        if (tag == 0 || !skipField(tag)) {
-          return;
-        }
-      }
-    }
-
-    @Override
-    public void skipMessage(CodedOutputStream output) throws IOException {
-      while (true) {
-        final int tag = readTag();
-        if (tag == 0 || !skipField(tag, output)) {
-          return;
-        }
-      }
-    }
-
-    /** Collects the bytes skipped and returns the data in a ByteBuffer. */
-    private class SkippedDataSink implements RefillCallback {
-      private int lastPos = pos;
-      private ByteArrayOutputStream byteArrayStream;
-
-      @Override
-      public void onRefill() {
-        if (byteArrayStream == null) {
-          byteArrayStream = new ByteArrayOutputStream();
-        }
-        byteArrayStream.write(buffer, lastPos, pos - lastPos);
-        lastPos = 0;
-      }
-
-      /** Gets skipped data in a ByteBuffer. This method should only be called once. */
-      ByteBuffer getSkippedData() {
-        if (byteArrayStream == null) {
-          return ByteBuffer.wrap(buffer, lastPos, pos - lastPos);
-        } else {
-          byteArrayStream.write(buffer, lastPos, pos);
-          return ByteBuffer.wrap(byteArrayStream.toByteArray());
-        }
-      }
-    }
-
-
-    // -----------------------------------------------------------------
-
-    @Override
-    public double readDouble() throws IOException {
-      return Double.longBitsToDouble(readRawLittleEndian64());
-    }
-
-    @Override
-    public float readFloat() throws IOException {
-      return Float.intBitsToFloat(readRawLittleEndian32());
-    }
-
-    @Override
-    public long readUInt64() throws IOException {
-      return readRawVarint64();
-    }
-
-    @Override
-    public long readInt64() throws IOException {
-      return readRawVarint64();
-    }
-
-    @Override
-    public int readInt32() throws IOException {
-      return readRawVarint32();
-    }
-
-    @Override
-    public long readFixed64() throws IOException {
-      return readRawLittleEndian64();
-    }
-
-    @Override
-    public int readFixed32() throws IOException {
-      return readRawLittleEndian32();
-    }
-
-    @Override
-    public boolean readBool() throws IOException {
-      return readRawVarint64() != 0;
-    }
-
-    @Override
-    public String readString() throws IOException {
-      final int size = readRawVarint32();
-      if (size > 0 && size <= (bufferSize - pos)) {
-        // Fast path:  We already have the bytes in a contiguous buffer, so
-        //   just copy directly from it.
-        final String result = new String(buffer, pos, size, UTF_8);
-        pos += size;
-        return result;
-      }
-      if (size == 0) {
-        return "";
-      }
-      if (size <= bufferSize) {
-        refillBuffer(size);
-        String result = new String(buffer, pos, size, UTF_8);
-        pos += size;
-        return result;
-      }
-      // Slow path:  Build a byte array first then copy it.
-      return new String(readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ false), UTF_8);
-    }
-
-    @Override
-    public String readStringRequireUtf8() throws IOException {
-      final int size = readRawVarint32();
-      final byte[] bytes;
-      final int oldPos = pos;
-      final int tempPos;
-      if (size <= (bufferSize - oldPos) && size > 0) {
-        // Fast path:  We already have the bytes in a contiguous buffer, so
-        //   just copy directly from it.
-        bytes = buffer;
-        pos = oldPos + size;
-        tempPos = oldPos;
-      } else if (size == 0) {
-        return "";
-      } else if (size <= bufferSize) {
-        refillBuffer(size);
-        bytes = buffer;
-        tempPos = 0;
-        pos = tempPos + size;
-      } else {
-        // Slow path:  Build a byte array first then copy it.
-        bytes = readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ false);
-        tempPos = 0;
-      }
-      return Utf8.decodeUtf8(bytes, tempPos, size);
-    }
-
-    @Override
-    public void readGroup(
-        final int fieldNumber,
-        final MessageLite.Builder builder,
-        final ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.recursionLimitExceeded();
-      }
-      ++recursionDepth;
-      builder.mergeFrom(this, extensionRegistry);
-      checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
-      --recursionDepth;
-    }
-
-
-    @Override
-    public <T extends MessageLite> T readGroup(
-        final int fieldNumber,
-        final Parser<T> parser,
-        final ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.recursionLimitExceeded();
-      }
-      ++recursionDepth;
-      T result = parser.parsePartialFrom(this, extensionRegistry);
-      checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
-      --recursionDepth;
-      return result;
-    }
-
-    @Deprecated
-    @Override
-    public void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
-        throws IOException {
-      readGroup(fieldNumber, builder, ExtensionRegistryLite.getEmptyRegistry());
-    }
-
-    @Override
-    public void readMessage(
-        final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      final int length = readRawVarint32();
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.recursionLimitExceeded();
-      }
-      final int oldLimit = pushLimit(length);
-      ++recursionDepth;
-      builder.mergeFrom(this, extensionRegistry);
-      checkLastTagWas(0);
-      --recursionDepth;
-      popLimit(oldLimit);
-    }
-
-
-    @Override
-    public <T extends MessageLite> T readMessage(
-        final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException {
-      int length = readRawVarint32();
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.recursionLimitExceeded();
-      }
-      final int oldLimit = pushLimit(length);
-      ++recursionDepth;
-      T result = parser.parsePartialFrom(this, extensionRegistry);
-      checkLastTagWas(0);
-      --recursionDepth;
-      popLimit(oldLimit);
-      return result;
-    }
-
-    @Override
-    public ByteString readBytes() throws IOException {
-      final int size = readRawVarint32();
-      if (size <= (bufferSize - pos) && size > 0) {
-        // Fast path:  We already have the bytes in a contiguous buffer, so
-        //   just copy directly from it.
-        final ByteString result = ByteString.copyFrom(buffer, pos, size);
-        pos += size;
-        return result;
-      }
-      if (size == 0) {
-        return ByteString.EMPTY;
-      }
-      return readBytesSlowPath(size);
-    }
-
-    @Override
-    public byte[] readByteArray() throws IOException {
-      final int size = readRawVarint32();
-      if (size <= (bufferSize - pos) && size > 0) {
-        // Fast path: We already have the bytes in a contiguous buffer, so
-        // just copy directly from it.
-        final byte[] result = Arrays.copyOfRange(buffer, pos, pos + size);
-        pos += size;
-        return result;
-      } else {
-        // Slow path: Build a byte array first then copy it.
-        // TODO(dweis): Do we want to protect from malicious input streams here?
-        return readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ false);
-      }
-    }
-
-    @Override
-    public ByteBuffer readByteBuffer() throws IOException {
-      final int size = readRawVarint32();
-      if (size <= (bufferSize - pos) && size > 0) {
-        // Fast path: We already have the bytes in a contiguous buffer.
-        ByteBuffer result = ByteBuffer.wrap(Arrays.copyOfRange(buffer, pos, pos + size));
-        pos += size;
-        return result;
-      }
-      if (size == 0) {
-        return Internal.EMPTY_BYTE_BUFFER;
-      }
-      // Slow path: Build a byte array first then copy it.
-      
-      // We must copy as the byte array was handed off to the InputStream and a malicious
-      // implementation could retain a reference.
-      return ByteBuffer.wrap(readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ true));
-    }
-
-    @Override
-    public int readUInt32() throws IOException {
-      return readRawVarint32();
-    }
-
-    @Override
-    public int readEnum() throws IOException {
-      return readRawVarint32();
-    }
-
-    @Override
-    public int readSFixed32() throws IOException {
-      return readRawLittleEndian32();
-    }
-
-    @Override
-    public long readSFixed64() throws IOException {
-      return readRawLittleEndian64();
-    }
-
-    @Override
-    public int readSInt32() throws IOException {
-      return decodeZigZag32(readRawVarint32());
-    }
-
-    @Override
-    public long readSInt64() throws IOException {
-      return decodeZigZag64(readRawVarint64());
-    }
-
-    // =================================================================
-
-    @Override
-    public int readRawVarint32() throws IOException {
-      // See implementation notes for readRawVarint64
-      fastpath:
-      {
-        int tempPos = pos;
-
-        if (bufferSize == tempPos) {
-          break fastpath;
-        }
-
-        final byte[] buffer = this.buffer;
-        int x;
-        if ((x = buffer[tempPos++]) >= 0) {
-          pos = tempPos;
-          return x;
-        } else if (bufferSize - tempPos < 9) {
-          break fastpath;
-        } else if ((x ^= (buffer[tempPos++] << 7)) < 0) {
-          x ^= (~0 << 7);
-        } else if ((x ^= (buffer[tempPos++] << 14)) >= 0) {
-          x ^= (~0 << 7) ^ (~0 << 14);
-        } else if ((x ^= (buffer[tempPos++] << 21)) < 0) {
-          x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
-        } else {
-          int y = buffer[tempPos++];
-          x ^= y << 28;
-          x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
-          if (y < 0
-              && buffer[tempPos++] < 0
-              && buffer[tempPos++] < 0
-              && buffer[tempPos++] < 0
-              && buffer[tempPos++] < 0
-              && buffer[tempPos++] < 0) {
-            break fastpath; // Will throw malformedVarint()
-          }
-        }
-        pos = tempPos;
-        return x;
-      }
-      return (int) readRawVarint64SlowPath();
-    }
-
-    private void skipRawVarint() throws IOException {
-      if (bufferSize - pos >= MAX_VARINT_SIZE) {
-        skipRawVarintFastPath();
-      } else {
-        skipRawVarintSlowPath();
-      }
-    }
-
-    private void skipRawVarintFastPath() throws IOException {
-      for (int i = 0; i < MAX_VARINT_SIZE; i++) {
-        if (buffer[pos++] >= 0) {
-          return;
-        }
-      }
-      throw InvalidProtocolBufferException.malformedVarint();
-    }
-
-    private void skipRawVarintSlowPath() throws IOException {
-      for (int i = 0; i < MAX_VARINT_SIZE; i++) {
-        if (readRawByte() >= 0) {
-          return;
-        }
-      }
-      throw InvalidProtocolBufferException.malformedVarint();
-    }
-
-    @Override
-    public long readRawVarint64() throws IOException {
-      // Implementation notes:
-      //
-      // Optimized for one-byte values, expected to be common.
-      // The particular code below was selected from various candidates
-      // empirically, by winning VarintBenchmark.
-      //
-      // Sign extension of (signed) Java bytes is usually a nuisance, but
-      // we exploit it here to more easily obtain the sign of bytes read.
-      // Instead of cleaning up the sign extension bits by masking eagerly,
-      // we delay until we find the final (positive) byte, when we clear all
-      // accumulated bits with one xor.  We depend on javac to constant fold.
-      fastpath:
-      {
-        int tempPos = pos;
-
-        if (bufferSize == tempPos) {
-          break fastpath;
-        }
-
-        final byte[] buffer = this.buffer;
-        long x;
-        int y;
-        if ((y = buffer[tempPos++]) >= 0) {
-          pos = tempPos;
-          return y;
-        } else if (bufferSize - tempPos < 9) {
-          break fastpath;
-        } else if ((y ^= (buffer[tempPos++] << 7)) < 0) {
-          x = y ^ (~0 << 7);
-        } else if ((y ^= (buffer[tempPos++] << 14)) >= 0) {
-          x = y ^ ((~0 << 7) ^ (~0 << 14));
-        } else if ((y ^= (buffer[tempPos++] << 21)) < 0) {
-          x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
-        } else if ((x = y ^ ((long) buffer[tempPos++] << 28)) >= 0L) {
-          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
-        } else if ((x ^= ((long) buffer[tempPos++] << 35)) < 0L) {
-          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
-        } else if ((x ^= ((long) buffer[tempPos++] << 42)) >= 0L) {
-          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
-        } else if ((x ^= ((long) buffer[tempPos++] << 49)) < 0L) {
-          x ^=
-              (~0L << 7)
-                  ^ (~0L << 14)
-                  ^ (~0L << 21)
-                  ^ (~0L << 28)
-                  ^ (~0L << 35)
-                  ^ (~0L << 42)
-                  ^ (~0L << 49);
-        } else {
-          x ^= ((long) buffer[tempPos++] << 56);
-          x ^=
-              (~0L << 7)
-                  ^ (~0L << 14)
-                  ^ (~0L << 21)
-                  ^ (~0L << 28)
-                  ^ (~0L << 35)
-                  ^ (~0L << 42)
-                  ^ (~0L << 49)
-                  ^ (~0L << 56);
-          if (x < 0L) {
-            if (buffer[tempPos++] < 0L) {
-              break fastpath; // Will throw malformedVarint()
-            }
-          }
-        }
-        pos = tempPos;
-        return x;
-      }
-      return readRawVarint64SlowPath();
-    }
-
-    @Override
-    long readRawVarint64SlowPath() throws IOException {
-      long result = 0;
-      for (int shift = 0; shift < 64; shift += 7) {
-        final byte b = readRawByte();
-        result |= (long) (b & 0x7F) << shift;
-        if ((b & 0x80) == 0) {
-          return result;
-        }
-      }
-      throw InvalidProtocolBufferException.malformedVarint();
-    }
-
-    @Override
-    public int readRawLittleEndian32() throws IOException {
-      int tempPos = pos;
-
-      if (bufferSize - tempPos < FIXED32_SIZE) {
-        refillBuffer(FIXED32_SIZE);
-        tempPos = pos;
-      }
-
-      final byte[] buffer = this.buffer;
-      pos = tempPos + FIXED32_SIZE;
-      return (((buffer[tempPos] & 0xff))
-          | ((buffer[tempPos + 1] & 0xff) << 8)
-          | ((buffer[tempPos + 2] & 0xff) << 16)
-          | ((buffer[tempPos + 3] & 0xff) << 24));
-    }
-
-    @Override
-    public long readRawLittleEndian64() throws IOException {
-      int tempPos = pos;
-
-      if (bufferSize - tempPos < FIXED64_SIZE) {
-        refillBuffer(FIXED64_SIZE);
-        tempPos = pos;
-      }
-
-      final byte[] buffer = this.buffer;
-      pos = tempPos + FIXED64_SIZE;
-      return (((buffer[tempPos] & 0xffL))
-          | ((buffer[tempPos + 1] & 0xffL) << 8)
-          | ((buffer[tempPos + 2] & 0xffL) << 16)
-          | ((buffer[tempPos + 3] & 0xffL) << 24)
-          | ((buffer[tempPos + 4] & 0xffL) << 32)
-          | ((buffer[tempPos + 5] & 0xffL) << 40)
-          | ((buffer[tempPos + 6] & 0xffL) << 48)
-          | ((buffer[tempPos + 7] & 0xffL) << 56));
-    }
-
-    // -----------------------------------------------------------------
-
-    @Override
-    public void enableAliasing(boolean enabled) {
-      // TODO(nathanmittler): Ideally we should throw here. Do nothing for backward compatibility.
-    }
-
-    @Override
-    public void resetSizeCounter() {
-      totalBytesRetired = -pos;
-    }
-
-    @Override
-    public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
-      if (byteLimit < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-      byteLimit += totalBytesRetired + pos;
-      final int oldLimit = currentLimit;
-      if (byteLimit > oldLimit) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-      currentLimit = byteLimit;
-
-      recomputeBufferSizeAfterLimit();
-
-      return oldLimit;
-    }
-
-    private void recomputeBufferSizeAfterLimit() {
-      bufferSize += bufferSizeAfterLimit;
-      final int bufferEnd = totalBytesRetired + bufferSize;
-      if (bufferEnd > currentLimit) {
-        // Limit is in current buffer.
-        bufferSizeAfterLimit = bufferEnd - currentLimit;
-        bufferSize -= bufferSizeAfterLimit;
-      } else {
-        bufferSizeAfterLimit = 0;
-      }
-    }
-
-    @Override
-    public void popLimit(final int oldLimit) {
-      currentLimit = oldLimit;
-      recomputeBufferSizeAfterLimit();
-    }
-
-    @Override
-    public int getBytesUntilLimit() {
-      if (currentLimit == Integer.MAX_VALUE) {
-        return -1;
-      }
-
-      final int currentAbsolutePosition = totalBytesRetired + pos;
-      return currentLimit - currentAbsolutePosition;
-    }
-
-    @Override
-    public boolean isAtEnd() throws IOException {
-      return pos == bufferSize && !tryRefillBuffer(1);
-    }
-
-    @Override
-    public int getTotalBytesRead() {
-      return totalBytesRetired + pos;
-    }
-
-    private interface RefillCallback {
-      void onRefill();
-    }
-
-    private RefillCallback refillCallback = null;
-
-    /**
-     * Reads more bytes from the input, making at least {@code n} bytes available in the buffer.
-     * Caller must ensure that the requested space is not yet available, and that the requested
-     * space is less than BUFFER_SIZE.
-     *
-     * @throws InvalidProtocolBufferException The end of the stream or the current limit was
-     *     reached.
-     */
-    private void refillBuffer(int n) throws IOException {
-      if (!tryRefillBuffer(n)) {
-        // We have to distinguish the exception between sizeLimitExceeded and truncatedMessage. So
-        // we just throw an sizeLimitExceeded exception here if it exceeds the sizeLimit
-        if (n > sizeLimit - totalBytesRetired - pos) {
-          throw InvalidProtocolBufferException.sizeLimitExceeded();
-        } else {
-          throw InvalidProtocolBufferException.truncatedMessage();
-        }
-      }
-    }
-
-    /**
-     * Tries to read more bytes from the input, making at least {@code n} bytes available in the
-     * buffer. Caller must ensure that the requested space is not yet available, and that the
-     * requested space is less than BUFFER_SIZE.
-     *
-     * @return {@code true} If the bytes could be made available; {@code false} 1. Current at the
-     *     end of the stream 2. The current limit was reached 3. The total size limit was reached
-     */
-    private boolean tryRefillBuffer(int n) throws IOException {
-      if (pos + n <= bufferSize) {
-        throw new IllegalStateException(
-            "refillBuffer() called when " + n + " bytes were already available in buffer");
-      }
-
-      // Check whether the size of total message needs to read is bigger than the size limit.
-      // We shouldn't throw an exception here as isAtEnd() function needs to get this function's
-      // return as the result.
-      if (n > sizeLimit - totalBytesRetired - pos) {
-        return false;
-      }
-
-      // Shouldn't throw the exception here either.
-      if (totalBytesRetired + pos + n > currentLimit) {
-        // Oops, we hit a limit.
-        return false;
-      }
-
-      if (refillCallback != null) {
-        refillCallback.onRefill();
-      }
-
-      int tempPos = pos;
-      if (tempPos > 0) {
-        if (bufferSize > tempPos) {
-          System.arraycopy(buffer, tempPos, buffer, 0, bufferSize - tempPos);
-        }
-        totalBytesRetired += tempPos;
-        bufferSize -= tempPos;
-        pos = 0;
-      }
-
-      // Here we should refill the buffer as many bytes as possible.
-      int bytesRead =
-          read(
-              input,
-              buffer,
-              bufferSize,
-              Math.min(
-                  //  the size of allocated but unused bytes in the buffer
-                  buffer.length - bufferSize,
-                  //  do not exceed the total bytes limit
-                  sizeLimit - totalBytesRetired - bufferSize));
-      if (bytesRead == 0 || bytesRead < -1 || bytesRead > buffer.length) {
-        throw new IllegalStateException(
-            input.getClass()
-                + "#read(byte[]) returned invalid result: "
-                + bytesRead
-                + "\nThe InputStream implementation is buggy.");
-      }
-      if (bytesRead > 0) {
-        bufferSize += bytesRead;
-        recomputeBufferSizeAfterLimit();
-        return (bufferSize >= n) ? true : tryRefillBuffer(n);
-      }
-
-      return false;
-    }
-
-    @Override
-    public byte readRawByte() throws IOException {
-      if (pos == bufferSize) {
-        refillBuffer(1);
-      }
-      return buffer[pos++];
-    }
-
-    @Override
-    public byte[] readRawBytes(final int size) throws IOException {
-      final int tempPos = pos;
-      if (size <= (bufferSize - tempPos) && size > 0) {
-        pos = tempPos + size;
-        return Arrays.copyOfRange(buffer, tempPos, tempPos + size);
-      } else {
-        // TODO(dweis): Do we want to protect from malicious input streams here?
-        return readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ false);
-      }
-    }
-
-    /**
-     * Exactly like readRawBytes, but caller must have already checked the fast path: (size <=
-     * (bufferSize - pos) && size > 0)
-     * 
-     * If ensureNoLeakedReferences is true, the value is guaranteed to have not escaped to
-     * untrusted code.
-     */
-    private byte[] readRawBytesSlowPath(
-        final int size, boolean ensureNoLeakedReferences) throws IOException {
-      // Attempt to read the data in one byte array when it's safe to do.
-      byte[] result = readRawBytesSlowPathOneChunk(size);
-      if (result != null) {
-        return ensureNoLeakedReferences ? result.clone() : result;
-      }
-
-      final int originalBufferPos = pos;
-      final int bufferedBytes = bufferSize - pos;
-
-      // Mark the current buffer consumed.
-      totalBytesRetired += bufferSize;
-      pos = 0;
-      bufferSize = 0;
-
-      // Determine the number of bytes we need to read from the input stream.
-      int sizeLeft = size - bufferedBytes;
-
-      // The size is very large. For security reasons we read them in small
-      // chunks.
-      List<byte[]> chunks = readRawBytesSlowPathRemainingChunks(sizeLeft);
-
-      // OK, got everything.  Now concatenate it all into one buffer.
-      final byte[] bytes = new byte[size];
-
-      // Start by copying the leftover bytes from this.buffer.
-      System.arraycopy(buffer, originalBufferPos, bytes, 0, bufferedBytes);
-
-      // And now all the chunks.
-      int tempPos = bufferedBytes;
-      for (final byte[] chunk : chunks) {
-        System.arraycopy(chunk, 0, bytes, tempPos, chunk.length);
-        tempPos += chunk.length;
-      }
-
-      // Done.
-      return bytes;
-    }
-
-    /**
-     * Attempts to read the data in one byte array when it's safe to do. Returns null if the size to
-     * read is too large and needs to be allocated in smaller chunks for security reasons.
-     * 
-     * Returns a byte[] that may have escaped to user code via InputStream APIs.
-     */
-    private byte[] readRawBytesSlowPathOneChunk(final int size) throws IOException {
-      if (size == 0) {
-        return Internal.EMPTY_BYTE_ARRAY;
-      }
-      if (size < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-
-      // Integer-overflow-conscious check that the message size so far has not exceeded sizeLimit.
-      int currentMessageSize = totalBytesRetired + pos + size;
-      if (currentMessageSize - sizeLimit > 0) {
-        throw InvalidProtocolBufferException.sizeLimitExceeded();
-      }
-
-      // Verify that the message size so far has not exceeded currentLimit.
-      if (currentMessageSize > currentLimit) {
-        // Read to the end of the stream anyway.
-        skipRawBytes(currentLimit - totalBytesRetired - pos);
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-
-      final int bufferedBytes = bufferSize - pos;
-      // Determine the number of bytes we need to read from the input stream.
-      int sizeLeft = size - bufferedBytes;
-      // TODO(nathanmittler): Consider using a value larger than DEFAULT_BUFFER_SIZE.
-      if (sizeLeft < DEFAULT_BUFFER_SIZE || sizeLeft <= available(input)) {
-        // Either the bytes we need are known to be available, or the required buffer is
-        // within an allowed threshold - go ahead and allocate the buffer now.
-        final byte[] bytes = new byte[size];
-
-        // Copy all of the buffered bytes to the result buffer.
-        System.arraycopy(buffer, pos, bytes, 0, bufferedBytes);
-        totalBytesRetired += bufferSize;
-        pos = 0;
-        bufferSize = 0;
-
-        // Fill the remaining bytes from the input stream.
-        int tempPos = bufferedBytes;
-        while (tempPos < bytes.length) {
-          int n = read(input, bytes, tempPos, size - tempPos);
-          if (n == -1) {
-            throw InvalidProtocolBufferException.truncatedMessage();
-          }
-          totalBytesRetired += n;
-          tempPos += n;
-        }
-
-        return bytes;
-      }
-
-      return null;
-    }
-
-    /**
-     * Reads the remaining data in small chunks from the input stream.
-     * 
-     * Returns a byte[] that may have escaped to user code via InputStream APIs.
-     */
-    private List<byte[]> readRawBytesSlowPathRemainingChunks(int sizeLeft) throws IOException {
-      // The size is very large.  For security reasons, we can't allocate the
-      // entire byte array yet.  The size comes directly from the input, so a
-      // maliciously-crafted message could provide a bogus very large size in
-      // order to trick the app into allocating a lot of memory.  We avoid this
-      // by allocating and reading only a small chunk at a time, so that the
-      // malicious message must actually *be* extremely large to cause
-      // problems.  Meanwhile, we limit the allowed size of a message elsewhere.
-      final List<byte[]> chunks = new ArrayList<byte[]>();
-
-      while (sizeLeft > 0) {
-        // TODO(nathanmittler): Consider using a value larger than DEFAULT_BUFFER_SIZE.
-        final byte[] chunk = new byte[Math.min(sizeLeft, DEFAULT_BUFFER_SIZE)];
-        int tempPos = 0;
-        while (tempPos < chunk.length) {
-          final int n = input.read(chunk, tempPos, chunk.length - tempPos);
-          if (n == -1) {
-            throw InvalidProtocolBufferException.truncatedMessage();
-          }
-          totalBytesRetired += n;
-          tempPos += n;
-        }
-        sizeLeft -= chunk.length;
-        chunks.add(chunk);
-      }
-
-      return chunks;
-    }
-
-    /**
-     * Like readBytes, but caller must have already checked the fast path: (size <= (bufferSize -
-     * pos) && size > 0 || size == 0)
-     */
-    private ByteString readBytesSlowPath(final int size) throws IOException {
-      final byte[] result = readRawBytesSlowPathOneChunk(size);
-      if (result != null) {
-        // We must copy as the byte array was handed off to the InputStream and a malicious
-        // implementation could retain a reference.
-        return ByteString.copyFrom(result);
-      }
-
-      final int originalBufferPos = pos;
-      final int bufferedBytes = bufferSize - pos;
-
-      // Mark the current buffer consumed.
-      totalBytesRetired += bufferSize;
-      pos = 0;
-      bufferSize = 0;
-
-      // Determine the number of bytes we need to read from the input stream.
-      int sizeLeft = size - bufferedBytes;
-
-      // The size is very large. For security reasons we read them in small
-      // chunks.
-      List<byte[]> chunks = readRawBytesSlowPathRemainingChunks(sizeLeft);
-
-      // OK, got everything.  Now concatenate it all into one buffer.
-      final byte[] bytes = new byte[size];
-
-      // Start by copying the leftover bytes from this.buffer.
-      System.arraycopy(buffer, originalBufferPos, bytes, 0, bufferedBytes);
-
-      // And now all the chunks.
-      int tempPos = bufferedBytes;
-      for (final byte[] chunk : chunks) {
-        System.arraycopy(chunk, 0, bytes, tempPos, chunk.length);
-        tempPos += chunk.length;
-      }
-      
-      return ByteString.wrap(bytes);
-    }
-
-    @Override
-    public void skipRawBytes(final int size) throws IOException {
-      if (size <= (bufferSize - pos) && size >= 0) {
-        // We have all the bytes we need already.
-        pos += size;
-      } else {
-        skipRawBytesSlowPath(size);
-      }
-    }
-
-    /**
-     * Exactly like skipRawBytes, but caller must have already checked the fast path: (size <=
-     * (bufferSize - pos) && size >= 0)
-     */
-    private void skipRawBytesSlowPath(final int size) throws IOException {
-      if (size < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-
-      if (totalBytesRetired + pos + size > currentLimit) {
-        // Read to the end of the stream anyway.
-        skipRawBytes(currentLimit - totalBytesRetired - pos);
-        // Then fail.
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-
-      int totalSkipped = 0;
-      if (refillCallback == null) {
-        // Skipping more bytes than are in the buffer.  First skip what we have.
-        totalBytesRetired += pos;
-        totalSkipped = bufferSize - pos;
-        bufferSize = 0;
-        pos = 0;
-
-        try {
-          while (totalSkipped < size) {
-            int toSkip = size - totalSkipped;
-            long skipped = skip(input, toSkip);
-            if (skipped < 0 || skipped > toSkip) {
-              throw new IllegalStateException(
-                  input.getClass()
-                      + "#skip returned invalid result: "
-                      + skipped
-                      + "\nThe InputStream implementation is buggy.");
-            } else if (skipped == 0) {
-              // The API contract of skip() permits an inputstream to skip zero bytes for any reason
-              // it wants. In particular, ByteArrayInputStream will just return zero over and over
-              // when it's at the end of its input. In order to actually confirm that we've hit the
-              // end of input, we need to issue a read call via the other path.
-              break;
-            }
-            totalSkipped += (int) skipped;
-          }
-        } finally {
-          totalBytesRetired += totalSkipped;
-          recomputeBufferSizeAfterLimit();
-        }
-      }
-      if (totalSkipped < size) {
-        // Skipping more bytes than are in the buffer.  First skip what we have.
-        int tempPos = bufferSize - pos;
-        pos = bufferSize;
-
-        // Keep refilling the buffer until we get to the point we wanted to skip to.
-        // This has the side effect of ensuring the limits are updated correctly.
-        refillBuffer(1);
-        while (size - tempPos > bufferSize) {
-          tempPos += bufferSize;
-          pos = bufferSize;
-          refillBuffer(1);
-        }
-
-        pos = size - tempPos;
-      }
-    }
-  }
-
-  /**
-   * Implementation of {@link CodedInputStream} that uses an {@link Iterable <ByteBuffer>} as the
-   * data source. Requires the use of {@code sun.misc.Unsafe} to perform fast reads on the buffer.
-   */
-  private static final class IterableDirectByteBufferDecoder extends CodedInputStream {
-    /** The object that need to decode. */
-    private Iterable<ByteBuffer> input;
-    /** The {@link Iterator} with type {@link ByteBuffer} of {@code input} */
-    private Iterator<ByteBuffer> iterator;
-    /** The current ByteBuffer; */
-    private ByteBuffer currentByteBuffer;
-    /**
-     * If {@code true}, indicates that all the buffer are backing a {@link ByteString} and are
-     * therefore considered to be an immutable input source.
-     */
-    private boolean immutable;
-    /**
-     * If {@code true}, indicates that calls to read {@link ByteString} or {@code byte[]}
-     * <strong>may</strong> return slices of the underlying buffer, rather than copies.
-     */
-    private boolean enableAliasing;
-    /** The global total message length limit */
-    private int totalBufferSize;
-    /** The amount of available data in the input beyond {@link #currentLimit}. */
-    private int bufferSizeAfterCurrentLimit;
-    /** The absolute position of the end of the current message. */
-    private int currentLimit = Integer.MAX_VALUE;
-    /** The last tag that was read from this stream. */
-    private int lastTag;
-    /** Total Bytes have been Read from the {@link Iterable} {@link ByteBuffer} */
-    private int totalBytesRead;
-    /** The start position offset of the whole message, used as to reset the totalBytesRead */
-    private int startOffset;
-    /** The current position for current ByteBuffer */
-    private long currentByteBufferPos;
-
-    private long currentByteBufferStartPos;
-    /**
-     * If the current ByteBuffer is unsafe-direct based, currentAddress is the start address of this
-     * ByteBuffer; otherwise should be zero.
-     */
-    private long currentAddress;
-    /** The limit position for current ByteBuffer */
-    private long currentByteBufferLimit;
-
-    /**
-     * The constructor of {@code Iterable<ByteBuffer>} decoder.
-     *
-     * @param inputBufs The input data.
-     * @param size The total size of the input data.
-     * @param immutableFlag whether the input data is immutable.
-     */
-    private IterableDirectByteBufferDecoder(
-        Iterable<ByteBuffer> inputBufs, int size, boolean immutableFlag) {
-      totalBufferSize = size;
-      input = inputBufs;
-      iterator = input.iterator();
-      immutable = immutableFlag;
-      startOffset = totalBytesRead = 0;
-      if (size == 0) {
-        currentByteBuffer = EMPTY_BYTE_BUFFER;
-        currentByteBufferPos = 0;
-        currentByteBufferStartPos = 0;
-        currentByteBufferLimit = 0;
-        currentAddress = 0;
-      } else {
-        tryGetNextByteBuffer();
-      }
-    }
-
-    /** To get the next ByteBuffer from {@code input}, and then update the parameters */
-    private void getNextByteBuffer() throws InvalidProtocolBufferException {
-      if (!iterator.hasNext()) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-      tryGetNextByteBuffer();
-    }
-
-    private void tryGetNextByteBuffer() {
-      currentByteBuffer = iterator.next();
-      totalBytesRead += (int) (currentByteBufferPos - currentByteBufferStartPos);
-      currentByteBufferPos = currentByteBuffer.position();
-      currentByteBufferStartPos = currentByteBufferPos;
-      currentByteBufferLimit = currentByteBuffer.limit();
-      currentAddress = UnsafeUtil.addressOffset(currentByteBuffer);
-      currentByteBufferPos += currentAddress;
-      currentByteBufferStartPos += currentAddress;
-      currentByteBufferLimit += currentAddress;
-    }
-
-    @Override
-    public int readTag() throws IOException {
-      if (isAtEnd()) {
-        lastTag = 0;
-        return 0;
-      }
-
-      lastTag = readRawVarint32();
-      if (WireFormat.getTagFieldNumber(lastTag) == 0) {
-        // If we actually read zero (or any tag number corresponding to field
-        // number zero), that's not a valid tag.
-        throw InvalidProtocolBufferException.invalidTag();
-      }
-      return lastTag;
-    }
-
-    @Override
-    public void checkLastTagWas(final int value) throws InvalidProtocolBufferException {
-      if (lastTag != value) {
-        throw InvalidProtocolBufferException.invalidEndTag();
-      }
-    }
-
-    @Override
-    public int getLastTag() {
-      return lastTag;
-    }
-
-    @Override
-    public boolean skipField(final int tag) throws IOException {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WireFormat.WIRETYPE_VARINT:
-          skipRawVarint();
-          return true;
-        case WireFormat.WIRETYPE_FIXED64:
-          skipRawBytes(FIXED64_SIZE);
-          return true;
-        case WireFormat.WIRETYPE_LENGTH_DELIMITED:
-          skipRawBytes(readRawVarint32());
-          return true;
-        case WireFormat.WIRETYPE_START_GROUP:
-          skipMessage();
-          checkLastTagWas(
-              WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));
-          return true;
-        case WireFormat.WIRETYPE_END_GROUP:
-          return false;
-        case WireFormat.WIRETYPE_FIXED32:
-          skipRawBytes(FIXED32_SIZE);
-          return true;
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-
-    @Override
-    public boolean skipField(final int tag, final CodedOutputStream output) throws IOException {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WireFormat.WIRETYPE_VARINT:
-          {
-            long value = readInt64();
-            output.writeRawVarint32(tag);
-            output.writeUInt64NoTag(value);
-            return true;
-          }
-        case WireFormat.WIRETYPE_FIXED64:
-          {
-            long value = readRawLittleEndian64();
-            output.writeRawVarint32(tag);
-            output.writeFixed64NoTag(value);
-            return true;
-          }
-        case WireFormat.WIRETYPE_LENGTH_DELIMITED:
-          {
-            ByteString value = readBytes();
-            output.writeRawVarint32(tag);
-            output.writeBytesNoTag(value);
-            return true;
-          }
-        case WireFormat.WIRETYPE_START_GROUP:
-          {
-            output.writeRawVarint32(tag);
-            skipMessage(output);
-            int endtag =
-                WireFormat.makeTag(
-                    WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP);
-            checkLastTagWas(endtag);
-            output.writeRawVarint32(endtag);
-            return true;
-          }
-        case WireFormat.WIRETYPE_END_GROUP:
-          {
-            return false;
-          }
-        case WireFormat.WIRETYPE_FIXED32:
-          {
-            int value = readRawLittleEndian32();
-            output.writeRawVarint32(tag);
-            output.writeFixed32NoTag(value);
-            return true;
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-
-    @Override
-    public void skipMessage() throws IOException {
-      while (true) {
-        final int tag = readTag();
-        if (tag == 0 || !skipField(tag)) {
-          return;
-        }
-      }
-    }
-
-    @Override
-    public void skipMessage(CodedOutputStream output) throws IOException {
-      while (true) {
-        final int tag = readTag();
-        if (tag == 0 || !skipField(tag, output)) {
-          return;
-        }
-      }
-    }
-
-    // -----------------------------------------------------------------
-
-    @Override
-    public double readDouble() throws IOException {
-      return Double.longBitsToDouble(readRawLittleEndian64());
-    }
-
-    @Override
-    public float readFloat() throws IOException {
-      return Float.intBitsToFloat(readRawLittleEndian32());
-    }
-
-    @Override
-    public long readUInt64() throws IOException {
-      return readRawVarint64();
-    }
-
-    @Override
-    public long readInt64() throws IOException {
-      return readRawVarint64();
-    }
-
-    @Override
-    public int readInt32() throws IOException {
-      return readRawVarint32();
-    }
-
-    @Override
-    public long readFixed64() throws IOException {
-      return readRawLittleEndian64();
-    }
-
-    @Override
-    public int readFixed32() throws IOException {
-      return readRawLittleEndian32();
-    }
-
-    @Override
-    public boolean readBool() throws IOException {
-      return readRawVarint64() != 0;
-    }
-
-    @Override
-    public String readString() throws IOException {
-      final int size = readRawVarint32();
-      if (size > 0 && size <= currentByteBufferLimit - currentByteBufferPos) {
-        byte[] bytes = new byte[size];
-        UnsafeUtil.copyMemory(currentByteBufferPos, bytes, 0, size);
-        String result = new String(bytes, UTF_8);
-        currentByteBufferPos += size;
-        return result;
-      } else if (size > 0 && size <= remaining()) {
-        // TODO(yilunchong): To use an underlying bytes[] instead of allocating a new bytes[]
-        byte[] bytes = new byte[size];
-        readRawBytesTo(bytes, 0, size);
-        String result = new String(bytes, UTF_8);
-        return result;
-      }
-
-      if (size == 0) {
-        return "";
-      }
-      if (size < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-
-    @Override
-    public String readStringRequireUtf8() throws IOException {
-      final int size = readRawVarint32();
-      if (size > 0 && size <= currentByteBufferLimit - currentByteBufferPos) {
-        final int bufferPos = (int) (currentByteBufferPos - currentByteBufferStartPos);
-        String result = Utf8.decodeUtf8(currentByteBuffer, bufferPos, size);
-        currentByteBufferPos += size;
-        return result;
-      }
-      if (size >= 0 && size <= remaining()) {
-        byte[] bytes = new byte[size];
-        readRawBytesTo(bytes, 0, size);
-        return Utf8.decodeUtf8(bytes, 0, size);
-      }
-
-      if (size == 0) {
-        return "";
-      }
-      if (size <= 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-
-    @Override
-    public void readGroup(
-        final int fieldNumber,
-        final MessageLite.Builder builder,
-        final ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.recursionLimitExceeded();
-      }
-      ++recursionDepth;
-      builder.mergeFrom(this, extensionRegistry);
-      checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
-      --recursionDepth;
-    }
-
-
-    @Override
-    public <T extends MessageLite> T readGroup(
-        final int fieldNumber,
-        final Parser<T> parser,
-        final ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.recursionLimitExceeded();
-      }
-      ++recursionDepth;
-      T result = parser.parsePartialFrom(this, extensionRegistry);
-      checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
-      --recursionDepth;
-      return result;
-    }
-
-    @Deprecated
-    @Override
-    public void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
-        throws IOException {
-      readGroup(fieldNumber, builder, ExtensionRegistryLite.getEmptyRegistry());
-    }
-
-    @Override
-    public void readMessage(
-        final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      final int length = readRawVarint32();
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.recursionLimitExceeded();
-      }
-      final int oldLimit = pushLimit(length);
-      ++recursionDepth;
-      builder.mergeFrom(this, extensionRegistry);
-      checkLastTagWas(0);
-      --recursionDepth;
-      popLimit(oldLimit);
-    }
-
-
-    @Override
-    public <T extends MessageLite> T readMessage(
-        final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException {
-      int length = readRawVarint32();
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.recursionLimitExceeded();
-      }
-      final int oldLimit = pushLimit(length);
-      ++recursionDepth;
-      T result = parser.parsePartialFrom(this, extensionRegistry);
-      checkLastTagWas(0);
-      --recursionDepth;
-      popLimit(oldLimit);
-      return result;
-    }
-
-    @Override
-    public ByteString readBytes() throws IOException {
-      final int size = readRawVarint32();
-      if (size > 0 && size <= currentByteBufferLimit - currentByteBufferPos) {
-        if (immutable && enableAliasing) {
-          final int idx = (int) (currentByteBufferPos - currentAddress);
-          final ByteString result = ByteString.wrap(slice(idx, idx + size));
-          currentByteBufferPos += size;
-          return result;
-        } else {
-          byte[] bytes;
-          bytes = new byte[size];
-          UnsafeUtil.copyMemory(currentByteBufferPos, bytes, 0, size);
-          currentByteBufferPos += size;
-          return ByteString.wrap(bytes);
-        }
-      } else if (size > 0 && size <= remaining()) {
-        byte[] temp = new byte[size];
-        readRawBytesTo(temp, 0, size);
-        return ByteString.wrap(temp);
-      }
-
-      if (size == 0) {
-        return ByteString.EMPTY;
-      }
-      if (size < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-
-    @Override
-    public byte[] readByteArray() throws IOException {
-      return readRawBytes(readRawVarint32());
-    }
-
-    @Override
-    public ByteBuffer readByteBuffer() throws IOException {
-      final int size = readRawVarint32();
-      if (size > 0 && size <= currentRemaining()) {
-        if (!immutable && enableAliasing) {
-          currentByteBufferPos += size;
-          return slice(
-              (int) (currentByteBufferPos - currentAddress - size),
-              (int) (currentByteBufferPos - currentAddress));
-        } else {
-          byte[] bytes = new byte[size];
-          UnsafeUtil.copyMemory(currentByteBufferPos, bytes, 0, size);
-          currentByteBufferPos += size;
-          return ByteBuffer.wrap(bytes);
-        }
-      } else if (size > 0 && size <= remaining()) {
-        byte[] temp = new byte[size];
-        readRawBytesTo(temp, 0, size);
-        return ByteBuffer.wrap(temp);
-      }
-
-      if (size == 0) {
-        return EMPTY_BYTE_BUFFER;
-      }
-      if (size < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-
-    @Override
-    public int readUInt32() throws IOException {
-      return readRawVarint32();
-    }
-
-    @Override
-    public int readEnum() throws IOException {
-      return readRawVarint32();
-    }
-
-    @Override
-    public int readSFixed32() throws IOException {
-      return readRawLittleEndian32();
-    }
-
-    @Override
-    public long readSFixed64() throws IOException {
-      return readRawLittleEndian64();
-    }
-
-    @Override
-    public int readSInt32() throws IOException {
-      return decodeZigZag32(readRawVarint32());
-    }
-
-    @Override
-    public long readSInt64() throws IOException {
-      return decodeZigZag64(readRawVarint64());
-    }
-
-    @Override
-    public int readRawVarint32() throws IOException {
-      fastpath:
-      {
-        long tempPos = currentByteBufferPos;
-
-        if (currentByteBufferLimit == currentByteBufferPos) {
-          break fastpath;
-        }
-
-        int x;
-        if ((x = UnsafeUtil.getByte(tempPos++)) >= 0) {
-          currentByteBufferPos++;
-          return x;
-        } else if (currentByteBufferLimit - currentByteBufferPos < 10) {
-          break fastpath;
-        } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 7)) < 0) {
-          x ^= (~0 << 7);
-        } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 14)) >= 0) {
-          x ^= (~0 << 7) ^ (~0 << 14);
-        } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 21)) < 0) {
-          x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
-        } else {
-          int y = UnsafeUtil.getByte(tempPos++);
-          x ^= y << 28;
-          x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
-          if (y < 0
-              && UnsafeUtil.getByte(tempPos++) < 0
-              && UnsafeUtil.getByte(tempPos++) < 0
-              && UnsafeUtil.getByte(tempPos++) < 0
-              && UnsafeUtil.getByte(tempPos++) < 0
-              && UnsafeUtil.getByte(tempPos++) < 0) {
-            break fastpath; // Will throw malformedVarint()
-          }
-        }
-        currentByteBufferPos = tempPos;
-        return x;
-      }
-      return (int) readRawVarint64SlowPath();
-    }
-
-    @Override
-    public long readRawVarint64() throws IOException {
-      fastpath:
-      {
-        long tempPos = currentByteBufferPos;
-
-        if (currentByteBufferLimit == currentByteBufferPos) {
-          break fastpath;
-        }
-
-        long x;
-        int y;
-        if ((y = UnsafeUtil.getByte(tempPos++)) >= 0) {
-          currentByteBufferPos++;
-          return y;
-        } else if (currentByteBufferLimit - currentByteBufferPos < 10) {
-          break fastpath;
-        } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 7)) < 0) {
-          x = y ^ (~0 << 7);
-        } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 14)) >= 0) {
-          x = y ^ ((~0 << 7) ^ (~0 << 14));
-        } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 21)) < 0) {
-          x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
-        } else if ((x = y ^ ((long) UnsafeUtil.getByte(tempPos++) << 28)) >= 0L) {
-          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
-        } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 35)) < 0L) {
-          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
-        } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 42)) >= 0L) {
-          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
-        } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 49)) < 0L) {
-          x ^=
-              (~0L << 7)
-                  ^ (~0L << 14)
-                  ^ (~0L << 21)
-                  ^ (~0L << 28)
-                  ^ (~0L << 35)
-                  ^ (~0L << 42)
-                  ^ (~0L << 49);
-        } else {
-          x ^= ((long) UnsafeUtil.getByte(tempPos++) << 56);
-          x ^=
-              (~0L << 7)
-                  ^ (~0L << 14)
-                  ^ (~0L << 21)
-                  ^ (~0L << 28)
-                  ^ (~0L << 35)
-                  ^ (~0L << 42)
-                  ^ (~0L << 49)
-                  ^ (~0L << 56);
-          if (x < 0L) {
-            if (UnsafeUtil.getByte(tempPos++) < 0L) {
-              break fastpath; // Will throw malformedVarint()
-            }
-          }
-        }
-        currentByteBufferPos = tempPos;
-        return x;
-      }
-      return readRawVarint64SlowPath();
-    }
-
-    @Override
-    long readRawVarint64SlowPath() throws IOException {
-      long result = 0;
-      for (int shift = 0; shift < 64; shift += 7) {
-        final byte b = readRawByte();
-        result |= (long) (b & 0x7F) << shift;
-        if ((b & 0x80) == 0) {
-          return result;
-        }
-      }
-      throw InvalidProtocolBufferException.malformedVarint();
-    }
-
-    @Override
-    public int readRawLittleEndian32() throws IOException {
-      if (currentRemaining() >= FIXED32_SIZE) {
-        long tempPos = currentByteBufferPos;
-        currentByteBufferPos += FIXED32_SIZE;
-        return (((UnsafeUtil.getByte(tempPos) & 0xff))
-            | ((UnsafeUtil.getByte(tempPos + 1) & 0xff) << 8)
-            | ((UnsafeUtil.getByte(tempPos + 2) & 0xff) << 16)
-            | ((UnsafeUtil.getByte(tempPos + 3) & 0xff) << 24));
-      }
-      return ((readRawByte() & 0xff)
-          | ((readRawByte() & 0xff) << 8)
-          | ((readRawByte() & 0xff) << 16)
-          | ((readRawByte() & 0xff) << 24));
-    }
-
-    @Override
-    public long readRawLittleEndian64() throws IOException {
-      if (currentRemaining() >= FIXED64_SIZE) {
-        long tempPos = currentByteBufferPos;
-        currentByteBufferPos += FIXED64_SIZE;
-        return (((UnsafeUtil.getByte(tempPos) & 0xffL))
-            | ((UnsafeUtil.getByte(tempPos + 1) & 0xffL) << 8)
-            | ((UnsafeUtil.getByte(tempPos + 2) & 0xffL) << 16)
-            | ((UnsafeUtil.getByte(tempPos + 3) & 0xffL) << 24)
-            | ((UnsafeUtil.getByte(tempPos + 4) & 0xffL) << 32)
-            | ((UnsafeUtil.getByte(tempPos + 5) & 0xffL) << 40)
-            | ((UnsafeUtil.getByte(tempPos + 6) & 0xffL) << 48)
-            | ((UnsafeUtil.getByte(tempPos + 7) & 0xffL) << 56));
-      }
-      return ((readRawByte() & 0xffL)
-          | ((readRawByte() & 0xffL) << 8)
-          | ((readRawByte() & 0xffL) << 16)
-          | ((readRawByte() & 0xffL) << 24)
-          | ((readRawByte() & 0xffL) << 32)
-          | ((readRawByte() & 0xffL) << 40)
-          | ((readRawByte() & 0xffL) << 48)
-          | ((readRawByte() & 0xffL) << 56));
-    }
-
-    @Override
-    public void enableAliasing(boolean enabled) {
-      this.enableAliasing = enabled;
-    }
-
-    @Override
-    public void resetSizeCounter() {
-      startOffset = (int) (totalBytesRead + currentByteBufferPos - currentByteBufferStartPos);
-    }
-
-    @Override
-    public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
-      if (byteLimit < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-      byteLimit += getTotalBytesRead();
-      final int oldLimit = currentLimit;
-      if (byteLimit > oldLimit) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      }
-      currentLimit = byteLimit;
-
-      recomputeBufferSizeAfterLimit();
-
-      return oldLimit;
-    }
-
-    private void recomputeBufferSizeAfterLimit() {
-      totalBufferSize += bufferSizeAfterCurrentLimit;
-      final int bufferEnd = totalBufferSize - startOffset;
-      if (bufferEnd > currentLimit) {
-        // Limit is in current buffer.
-        bufferSizeAfterCurrentLimit = bufferEnd - currentLimit;
-        totalBufferSize -= bufferSizeAfterCurrentLimit;
-      } else {
-        bufferSizeAfterCurrentLimit = 0;
-      }
-    }
-
-    @Override
-    public void popLimit(final int oldLimit) {
-      currentLimit = oldLimit;
-      recomputeBufferSizeAfterLimit();
-    }
-
-    @Override
-    public int getBytesUntilLimit() {
-      if (currentLimit == Integer.MAX_VALUE) {
-        return -1;
-      }
-
-      return currentLimit - getTotalBytesRead();
-    }
-
-    @Override
-    public boolean isAtEnd() throws IOException {
-      return totalBytesRead + currentByteBufferPos - currentByteBufferStartPos == totalBufferSize;
-    }
-
-    @Override
-    public int getTotalBytesRead() {
-      return (int)
-          (totalBytesRead - startOffset + currentByteBufferPos - currentByteBufferStartPos);
-    }
-
-    @Override
-    public byte readRawByte() throws IOException {
-      if (currentRemaining() == 0) {
-        getNextByteBuffer();
-      }
-      return UnsafeUtil.getByte(currentByteBufferPos++);
-    }
-
-    @Override
-    public byte[] readRawBytes(final int length) throws IOException {
-      if (length >= 0 && length <= currentRemaining()) {
-        byte[] bytes = new byte[length];
-        UnsafeUtil.copyMemory(currentByteBufferPos, bytes, 0, length);
-        currentByteBufferPos += length;
-        return bytes;
-      }
-      if (length >= 0 && length <= remaining()) {
-        byte[] bytes = new byte[length];
-        readRawBytesTo(bytes, 0, length);
-        return bytes;
-      }
-
-      if (length <= 0) {
-        if (length == 0) {
-          return EMPTY_BYTE_ARRAY;
-        } else {
-          throw InvalidProtocolBufferException.negativeSize();
-        }
-      }
-
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-
-    /**
-     * Try to get raw bytes from {@code input} with the size of {@code length} and copy to {@code
-     * bytes} array. If the size is bigger than the number of remaining bytes in the input, then
-     * throw {@code truncatedMessage} exception.
-     *
-     * @param bytes
-     * @param offset
-     * @param length
-     * @throws IOException
-     */
-    private void readRawBytesTo(byte[] bytes, int offset, final int length) throws IOException {
-      if (length >= 0 && length <= remaining()) {
-        int l = length;
-        while (l > 0) {
-          if (currentRemaining() == 0) {
-            getNextByteBuffer();
-          }
-          int bytesToCopy = Math.min(l, (int) currentRemaining());
-          UnsafeUtil.copyMemory(currentByteBufferPos, bytes, length - l + offset, bytesToCopy);
-          l -= bytesToCopy;
-          currentByteBufferPos += bytesToCopy;
-        }
-        return;
-      }
-
-      if (length <= 0) {
-        if (length == 0) {
-          return;
-        } else {
-          throw InvalidProtocolBufferException.negativeSize();
-        }
-      }
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-
-    @Override
-    public void skipRawBytes(final int length) throws IOException {
-      if (length >= 0
-          && length
-              <= (totalBufferSize
-                  - totalBytesRead
-                  - currentByteBufferPos
-                  + currentByteBufferStartPos)) {
-        // We have all the bytes we need already.
-        int l = length;
-        while (l > 0) {
-          if (currentRemaining() == 0) {
-            getNextByteBuffer();
-          }
-          int rl = Math.min(l, (int) currentRemaining());
-          l -= rl;
-          currentByteBufferPos += rl;
-        }
-        return;
-      }
-
-      if (length < 0) {
-        throw InvalidProtocolBufferException.negativeSize();
-      }
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-
-    // TODO: optimize to fastpath
-    private void skipRawVarint() throws IOException {
-      for (int i = 0; i < MAX_VARINT_SIZE; i++) {
-        if (readRawByte() >= 0) {
-          return;
-        }
-      }
-      throw InvalidProtocolBufferException.malformedVarint();
-    }
-
-    /**
-     * Try to get the number of remaining bytes in {@code input}.
-     *
-     * @return the number of remaining bytes in {@code input}.
-     */
-    private int remaining() {
-      return (int)
-          (totalBufferSize - totalBytesRead - currentByteBufferPos + currentByteBufferStartPos);
-    }
-
-    /**
-     * Try to get the number of remaining bytes in {@code currentByteBuffer}.
-     *
-     * @return the number of remaining bytes in {@code currentByteBuffer}
-     */
-    private long currentRemaining() {
-      return (currentByteBufferLimit - currentByteBufferPos);
-    }
-
-    private ByteBuffer slice(int begin, int end) throws IOException {
-      int prevPos = currentByteBuffer.position();
-      int prevLimit = currentByteBuffer.limit();
-      try {
-        ((Buffer) currentByteBuffer).position(begin);
-        ((Buffer) currentByteBuffer).limit(end);
-        return currentByteBuffer.slice();
-      } catch (IllegalArgumentException e) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      } finally {
-        ((Buffer) currentByteBuffer).position(prevPos);
-        ((Buffer) currentByteBuffer).limit(prevLimit);
-      }
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/CodedInputStreamReader.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/CodedInputStreamReader.java
deleted file mode 100644
index 7658f62..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/CodedInputStreamReader.java
+++ /dev/null
@@ -1,1333 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.WireFormat.FIXED32_SIZE;
-import static com.google.protobuf.WireFormat.FIXED64_SIZE;
-import static com.google.protobuf.WireFormat.WIRETYPE_END_GROUP;
-import static com.google.protobuf.WireFormat.WIRETYPE_FIXED32;
-import static com.google.protobuf.WireFormat.WIRETYPE_FIXED64;
-import static com.google.protobuf.WireFormat.WIRETYPE_LENGTH_DELIMITED;
-import static com.google.protobuf.WireFormat.WIRETYPE_START_GROUP;
-import static com.google.protobuf.WireFormat.WIRETYPE_VARINT;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-
-/** An adapter between the {@link Reader} interface and {@link CodedInputStream}. */
-@ExperimentalApi
-final class CodedInputStreamReader implements Reader {
-  private static final int FIXED32_MULTIPLE_MASK = FIXED32_SIZE - 1;
-  private static final int FIXED64_MULTIPLE_MASK = FIXED64_SIZE - 1;
-  private static final int NEXT_TAG_UNSET = 0;
-
-  private final CodedInputStream input;
-  private int tag;
-  private int endGroupTag;
-  private int nextTag = NEXT_TAG_UNSET;
-
-  public static CodedInputStreamReader forCodedInput(CodedInputStream input) {
-    if (input.wrapper != null) {
-      return input.wrapper;
-    }
-    return new CodedInputStreamReader(input);
-  }
-
-  private CodedInputStreamReader(CodedInputStream input) {
-    this.input = Internal.checkNotNull(input, "input");
-    this.input.wrapper = this;
-  }
-
-  @Override
-  public boolean shouldDiscardUnknownFields() {
-    return input.shouldDiscardUnknownFields();
-  }
-
-  @Override
-  public int getFieldNumber() throws IOException {
-    if (nextTag != NEXT_TAG_UNSET) {
-      tag = nextTag;
-      nextTag = NEXT_TAG_UNSET;
-    } else {
-      tag = input.readTag();
-    }
-    if (tag == 0 || tag == endGroupTag) {
-      return Reader.READ_DONE;
-    }
-    return WireFormat.getTagFieldNumber(tag);
-  }
-
-  @Override
-  public int getTag() {
-    return tag;
-  }
-
-  @Override
-  public boolean skipField() throws IOException {
-    if (input.isAtEnd() || tag == endGroupTag) {
-      return false;
-    }
-    return input.skipField(tag);
-  }
-
-  private void requireWireType(int requiredWireType) throws IOException {
-    if (WireFormat.getTagWireType(tag) != requiredWireType) {
-      throw InvalidProtocolBufferException.invalidWireType();
-    }
-  }
-
-  @Override
-  public double readDouble() throws IOException {
-    requireWireType(WIRETYPE_FIXED64);
-    return input.readDouble();
-  }
-
-  @Override
-  public float readFloat() throws IOException {
-    requireWireType(WIRETYPE_FIXED32);
-    return input.readFloat();
-  }
-
-  @Override
-  public long readUInt64() throws IOException {
-    requireWireType(WIRETYPE_VARINT);
-    return input.readUInt64();
-  }
-
-  @Override
-  public long readInt64() throws IOException {
-    requireWireType(WIRETYPE_VARINT);
-    return input.readInt64();
-  }
-
-  @Override
-  public int readInt32() throws IOException {
-    requireWireType(WIRETYPE_VARINT);
-    return input.readInt32();
-  }
-
-  @Override
-  public long readFixed64() throws IOException {
-    requireWireType(WIRETYPE_FIXED64);
-    return input.readFixed64();
-  }
-
-  @Override
-  public int readFixed32() throws IOException {
-    requireWireType(WIRETYPE_FIXED32);
-    return input.readFixed32();
-  }
-
-  @Override
-  public boolean readBool() throws IOException {
-    requireWireType(WIRETYPE_VARINT);
-    return input.readBool();
-  }
-
-  @Override
-  public String readString() throws IOException {
-    requireWireType(WIRETYPE_LENGTH_DELIMITED);
-    return input.readString();
-  }
-
-  @Override
-  public String readStringRequireUtf8() throws IOException {
-    requireWireType(WIRETYPE_LENGTH_DELIMITED);
-    return input.readStringRequireUtf8();
-  }
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public <T> T readMessage(Class<T> clazz, ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    requireWireType(WIRETYPE_LENGTH_DELIMITED);
-    return readMessage(Protobuf.getInstance().schemaFor(clazz), extensionRegistry);
-  }
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public <T> T readMessageBySchemaWithCheck(
-      Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException {
-    requireWireType(WIRETYPE_LENGTH_DELIMITED);
-    return readMessage(schema, extensionRegistry);
-  }
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public <T> T readGroup(Class<T> clazz, ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    requireWireType(WIRETYPE_START_GROUP);
-    return readGroup(Protobuf.getInstance().schemaFor(clazz), extensionRegistry);
-  }
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public <T> T readGroupBySchemaWithCheck(Schema<T> schema, ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    requireWireType(WIRETYPE_START_GROUP);
-    return readGroup(schema, extensionRegistry);
-  }
-
-  // Should have the same semantics of CodedInputStream#readMessage()
-  private <T> T readMessage(Schema<T> schema, ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    int size = input.readUInt32();
-    if (input.recursionDepth >= input.recursionLimit) {
-      throw InvalidProtocolBufferException.recursionLimitExceeded();
-    }
-
-    // Push the new limit.
-    final int prevLimit = input.pushLimit(size);
-    // Allocate and read the message.
-    T message = schema.newInstance();
-    ++input.recursionDepth;
-    schema.mergeFrom(message, this, extensionRegistry);
-    schema.makeImmutable(message);
-    input.checkLastTagWas(0);
-    --input.recursionDepth;
-    // Restore the previous limit.
-    input.popLimit(prevLimit);
-    return message;
-  }
-
-  private <T> T readGroup(Schema<T> schema, ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    int prevEndGroupTag = endGroupTag;
-    endGroupTag = WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WIRETYPE_END_GROUP);
-
-    try {
-      // Allocate and read the message.
-      T message = schema.newInstance();
-      schema.mergeFrom(message, this, extensionRegistry);
-      schema.makeImmutable(message);
-
-      if (tag != endGroupTag) {
-        throw InvalidProtocolBufferException.parseFailure();
-      }
-      return message;
-    } finally {
-      // Restore the old end group tag.
-      endGroupTag = prevEndGroupTag;
-    }
-  }
-
-  @Override
-  public ByteString readBytes() throws IOException {
-    requireWireType(WIRETYPE_LENGTH_DELIMITED);
-    return input.readBytes();
-  }
-
-  @Override
-  public int readUInt32() throws IOException {
-    requireWireType(WIRETYPE_VARINT);
-    return input.readUInt32();
-  }
-
-  @Override
-  public int readEnum() throws IOException {
-    requireWireType(WIRETYPE_VARINT);
-    return input.readEnum();
-  }
-
-  @Override
-  public int readSFixed32() throws IOException {
-    requireWireType(WIRETYPE_FIXED32);
-    return input.readSFixed32();
-  }
-
-  @Override
-  public long readSFixed64() throws IOException {
-    requireWireType(WIRETYPE_FIXED64);
-    return input.readSFixed64();
-  }
-
-  @Override
-  public int readSInt32() throws IOException {
-    requireWireType(WIRETYPE_VARINT);
-    return input.readSInt32();
-  }
-
-  @Override
-  public long readSInt64() throws IOException {
-    requireWireType(WIRETYPE_VARINT);
-    return input.readSInt64();
-  }
-
-  @Override
-  public void readDoubleList(List<Double> target) throws IOException {
-    if (target instanceof DoubleArrayList) {
-      DoubleArrayList plist = (DoubleArrayList) target;
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          verifyPackedFixed64Length(bytes);
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            plist.addDouble(input.readDouble());
-          } while (input.getTotalBytesRead() < endPos);
-          break;
-        case WIRETYPE_FIXED64:
-          while (true) {
-            plist.addDouble(input.readDouble());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    } else {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          verifyPackedFixed64Length(bytes);
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            target.add(input.readDouble());
-          } while (input.getTotalBytesRead() < endPos);
-          break;
-        case WIRETYPE_FIXED64:
-          while (true) {
-            target.add(input.readDouble());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-  }
-
-  @Override
-  public void readFloatList(List<Float> target) throws IOException {
-    if (target instanceof FloatArrayList) {
-      FloatArrayList plist = (FloatArrayList) target;
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          verifyPackedFixed32Length(bytes);
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            plist.addFloat(input.readFloat());
-          } while (input.getTotalBytesRead() < endPos);
-          break;
-        case WIRETYPE_FIXED32:
-          while (true) {
-            plist.addFloat(input.readFloat());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    } else {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          verifyPackedFixed32Length(bytes);
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            target.add(input.readFloat());
-          } while (input.getTotalBytesRead() < endPos);
-          break;
-        case WIRETYPE_FIXED32:
-          while (true) {
-            target.add(input.readFloat());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-  }
-
-  @Override
-  public void readUInt64List(List<Long> target) throws IOException {
-    if (target instanceof LongArrayList) {
-      LongArrayList plist = (LongArrayList) target;
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            plist.addLong(input.readUInt64());
-          } while (input.getTotalBytesRead() < endPos);
-          requirePosition(endPos);
-          break;
-        case WIRETYPE_VARINT:
-          while (true) {
-            plist.addLong(input.readUInt64());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    } else {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            target.add(input.readUInt64());
-          } while (input.getTotalBytesRead() < endPos);
-          requirePosition(endPos);
-          break;
-        case WIRETYPE_VARINT:
-          while (true) {
-            target.add(input.readUInt64());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-  }
-
-  @Override
-  public void readInt64List(List<Long> target) throws IOException {
-    if (target instanceof LongArrayList) {
-      LongArrayList plist = (LongArrayList) target;
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            plist.addLong(input.readInt64());
-          } while (input.getTotalBytesRead() < endPos);
-          requirePosition(endPos);
-          break;
-        case WIRETYPE_VARINT:
-          while (true) {
-            plist.addLong(input.readInt64());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    } else {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            target.add(input.readInt64());
-          } while (input.getTotalBytesRead() < endPos);
-          requirePosition(endPos);
-          break;
-        case WIRETYPE_VARINT:
-          while (true) {
-            target.add(input.readInt64());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-  }
-
-  @Override
-  public void readInt32List(List<Integer> target) throws IOException {
-    if (target instanceof IntArrayList) {
-      IntArrayList plist = (IntArrayList) target;
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            plist.addInt(input.readInt32());
-          } while (input.getTotalBytesRead() < endPos);
-          requirePosition(endPos);
-          break;
-        case WIRETYPE_VARINT:
-          while (true) {
-            plist.addInt(input.readInt32());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    } else {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            target.add(input.readInt32());
-          } while (input.getTotalBytesRead() < endPos);
-          requirePosition(endPos);
-          break;
-        case WIRETYPE_VARINT:
-          while (true) {
-            target.add(input.readInt32());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-  }
-
-  @Override
-  public void readFixed64List(List<Long> target) throws IOException {
-    if (target instanceof LongArrayList) {
-      LongArrayList plist = (LongArrayList) target;
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          verifyPackedFixed64Length(bytes);
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            plist.addLong(input.readFixed64());
-          } while (input.getTotalBytesRead() < endPos);
-          break;
-        case WIRETYPE_FIXED64:
-          while (true) {
-            plist.addLong(input.readFixed64());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    } else {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          verifyPackedFixed64Length(bytes);
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            target.add(input.readFixed64());
-          } while (input.getTotalBytesRead() < endPos);
-          break;
-        case WIRETYPE_FIXED64:
-          while (true) {
-            target.add(input.readFixed64());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-  }
-
-  @Override
-  public void readFixed32List(List<Integer> target) throws IOException {
-    if (target instanceof IntArrayList) {
-      IntArrayList plist = (IntArrayList) target;
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          verifyPackedFixed32Length(bytes);
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            plist.addInt(input.readFixed32());
-          } while (input.getTotalBytesRead() < endPos);
-          break;
-        case WIRETYPE_FIXED32:
-          while (true) {
-            plist.addInt(input.readFixed32());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    } else {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          verifyPackedFixed32Length(bytes);
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            target.add(input.readFixed32());
-          } while (input.getTotalBytesRead() < endPos);
-          break;
-        case WIRETYPE_FIXED32:
-          while (true) {
-            target.add(input.readFixed32());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-  }
-
-  @Override
-  public void readBoolList(List<Boolean> target) throws IOException {
-    if (target instanceof BooleanArrayList) {
-      BooleanArrayList plist = (BooleanArrayList) target;
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            plist.addBoolean(input.readBool());
-          } while (input.getTotalBytesRead() < endPos);
-          requirePosition(endPos);
-          break;
-        case WIRETYPE_VARINT:
-          while (true) {
-            plist.addBoolean(input.readBool());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    } else {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            target.add(input.readBool());
-          } while (input.getTotalBytesRead() < endPos);
-          requirePosition(endPos);
-          break;
-        case WIRETYPE_VARINT:
-          while (true) {
-            target.add(input.readBool());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-  }
-
-  @Override
-  public void readStringList(List<String> target) throws IOException {
-    readStringListInternal(target, false);
-  }
-
-  @Override
-  public void readStringListRequireUtf8(List<String> target) throws IOException {
-    readStringListInternal(target, true);
-  }
-
-  public void readStringListInternal(List<String> target, boolean requireUtf8) throws IOException {
-    if (WireFormat.getTagWireType(tag) != WIRETYPE_LENGTH_DELIMITED) {
-      throw InvalidProtocolBufferException.invalidWireType();
-    }
-
-    if (target instanceof LazyStringList && !requireUtf8) {
-      LazyStringList lazyList = (LazyStringList) target;
-      while (true) {
-        lazyList.add(readBytes());
-        if (input.isAtEnd()) {
-          return;
-        }
-        int nextTag = input.readTag();
-        if (nextTag != tag) {
-          // We've reached the end of the repeated field. Save the next tag value.
-          this.nextTag = nextTag;
-          return;
-        }
-      }
-    } else {
-      while (true) {
-        target.add(requireUtf8 ? readStringRequireUtf8() : readString());
-        if (input.isAtEnd()) {
-          return;
-        }
-        int nextTag = input.readTag();
-        if (nextTag != tag) {
-          // We've reached the end of the repeated field. Save the next tag value.
-          this.nextTag = nextTag;
-          return;
-        }
-      }
-    }
-  }
-
-  @Override
-  public <T> void readMessageList(
-      List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    final Schema<T> schema = Protobuf.getInstance().schemaFor(targetType);
-    readMessageList(target, schema, extensionRegistry);
-  }
-
-  @Override
-  public <T> void readMessageList(
-      List<T> target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    if (WireFormat.getTagWireType(tag) != WIRETYPE_LENGTH_DELIMITED) {
-      throw InvalidProtocolBufferException.invalidWireType();
-    }
-    final int listTag = tag;
-    while (true) {
-      target.add(readMessage(schema, extensionRegistry));
-      if (input.isAtEnd() || nextTag != NEXT_TAG_UNSET) {
-        return;
-      }
-      int nextTag = input.readTag();
-      if (nextTag != listTag) {
-        // We've reached the end of the repeated field. Save the next tag value.
-        this.nextTag = nextTag;
-        return;
-      }
-    }
-  }
-
-  @Override
-  public <T> void readGroupList(
-      List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    final Schema<T> schema = Protobuf.getInstance().schemaFor(targetType);
-    readGroupList(target, schema, extensionRegistry);
-  }
-
-  @Override
-  public <T> void readGroupList(
-      List<T> target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    if (WireFormat.getTagWireType(tag) != WIRETYPE_START_GROUP) {
-      throw InvalidProtocolBufferException.invalidWireType();
-    }
-    final int listTag = tag;
-    while (true) {
-      target.add(readGroup(schema, extensionRegistry));
-      if (input.isAtEnd() || nextTag != NEXT_TAG_UNSET) {
-        return;
-      }
-      int nextTag = input.readTag();
-      if (nextTag != listTag) {
-        // We've reached the end of the repeated field. Save the next tag value.
-        this.nextTag = nextTag;
-        return;
-      }
-    }
-  }
-
-  @Override
-  public void readBytesList(List<ByteString> target) throws IOException {
-    if (WireFormat.getTagWireType(tag) != WIRETYPE_LENGTH_DELIMITED) {
-      throw InvalidProtocolBufferException.invalidWireType();
-    }
-
-    while (true) {
-      target.add(readBytes());
-      if (input.isAtEnd()) {
-        return;
-      }
-      int nextTag = input.readTag();
-      if (nextTag != tag) {
-        // We've reached the end of the repeated field. Save the next tag value.
-        this.nextTag = nextTag;
-        return;
-      }
-    }
-  }
-
-  @Override
-  public void readUInt32List(List<Integer> target) throws IOException {
-    if (target instanceof IntArrayList) {
-      IntArrayList plist = (IntArrayList) target;
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            plist.addInt(input.readUInt32());
-          } while (input.getTotalBytesRead() < endPos);
-          requirePosition(endPos);
-          break;
-        case WIRETYPE_VARINT:
-          while (true) {
-            plist.addInt(input.readUInt32());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    } else {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            target.add(input.readUInt32());
-          } while (input.getTotalBytesRead() < endPos);
-          requirePosition(endPos);
-          break;
-        case WIRETYPE_VARINT:
-          while (true) {
-            target.add(input.readUInt32());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-  }
-
-  @Override
-  public void readEnumList(List<Integer> target) throws IOException {
-    if (target instanceof IntArrayList) {
-      IntArrayList plist = (IntArrayList) target;
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            plist.addInt(input.readEnum());
-          } while (input.getTotalBytesRead() < endPos);
-          requirePosition(endPos);
-          break;
-        case WIRETYPE_VARINT:
-          while (true) {
-            plist.addInt(input.readEnum());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    } else {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            target.add(input.readEnum());
-          } while (input.getTotalBytesRead() < endPos);
-          requirePosition(endPos);
-          break;
-        case WIRETYPE_VARINT:
-          while (true) {
-            target.add(input.readEnum());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-  }
-
-  @Override
-  public void readSFixed32List(List<Integer> target) throws IOException {
-    if (target instanceof IntArrayList) {
-      IntArrayList plist = (IntArrayList) target;
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          verifyPackedFixed32Length(bytes);
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            plist.addInt(input.readSFixed32());
-          } while (input.getTotalBytesRead() < endPos);
-          break;
-        case WIRETYPE_FIXED32:
-          while (true) {
-            plist.addInt(input.readSFixed32());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    } else {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          verifyPackedFixed32Length(bytes);
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            target.add(input.readSFixed32());
-          } while (input.getTotalBytesRead() < endPos);
-          break;
-        case WIRETYPE_FIXED32:
-          while (true) {
-            target.add(input.readSFixed32());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-  }
-
-  @Override
-  public void readSFixed64List(List<Long> target) throws IOException {
-    if (target instanceof LongArrayList) {
-      LongArrayList plist = (LongArrayList) target;
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          verifyPackedFixed64Length(bytes);
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            plist.addLong(input.readSFixed64());
-          } while (input.getTotalBytesRead() < endPos);
-          break;
-        case WIRETYPE_FIXED64:
-          while (true) {
-            plist.addLong(input.readSFixed64());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    } else {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          verifyPackedFixed64Length(bytes);
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            target.add(input.readSFixed64());
-          } while (input.getTotalBytesRead() < endPos);
-          break;
-        case WIRETYPE_FIXED64:
-          while (true) {
-            target.add(input.readSFixed64());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-  }
-
-  @Override
-  public void readSInt32List(List<Integer> target) throws IOException {
-    if (target instanceof IntArrayList) {
-      IntArrayList plist = (IntArrayList) target;
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            plist.addInt(input.readSInt32());
-          } while (input.getTotalBytesRead() < endPos);
-          requirePosition(endPos);
-          break;
-        case WIRETYPE_VARINT:
-          while (true) {
-            plist.addInt(input.readSInt32());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    } else {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            target.add(input.readSInt32());
-          } while (input.getTotalBytesRead() < endPos);
-          requirePosition(endPos);
-          break;
-        case WIRETYPE_VARINT:
-          while (true) {
-            target.add(input.readSInt32());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-  }
-
-  @Override
-  public void readSInt64List(List<Long> target) throws IOException {
-    if (target instanceof LongArrayList) {
-      LongArrayList plist = (LongArrayList) target;
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            plist.addLong(input.readSInt64());
-          } while (input.getTotalBytesRead() < endPos);
-          requirePosition(endPos);
-          break;
-        case WIRETYPE_VARINT:
-          while (true) {
-            plist.addLong(input.readSInt64());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    } else {
-      switch (WireFormat.getTagWireType(tag)) {
-        case WIRETYPE_LENGTH_DELIMITED:
-          final int bytes = input.readUInt32();
-          int endPos = input.getTotalBytesRead() + bytes;
-          do {
-            target.add(input.readSInt64());
-          } while (input.getTotalBytesRead() < endPos);
-          requirePosition(endPos);
-          break;
-        case WIRETYPE_VARINT:
-          while (true) {
-            target.add(input.readSInt64());
-            if (input.isAtEnd()) {
-              return;
-            }
-            int nextTag = input.readTag();
-            if (nextTag != tag) {
-              // We've reached the end of the repeated field. Save the next tag value.
-              this.nextTag = nextTag;
-              return;
-            }
-          }
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-  }
-
-  private void verifyPackedFixed64Length(int bytes) throws IOException {
-    if ((bytes & FIXED64_MULTIPLE_MASK) != 0) {
-      // Require that the number of bytes be a multiple of 8.
-      throw InvalidProtocolBufferException.parseFailure();
-    }
-  }
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public <K, V> void readMap(
-      Map<K, V> target,
-      MapEntryLite.Metadata<K, V> metadata,
-      ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    requireWireType(WIRETYPE_LENGTH_DELIMITED);
-    int size = input.readUInt32();
-    final int prevLimit = input.pushLimit(size);
-    K key = metadata.defaultKey;
-    V value = metadata.defaultValue;
-    try {
-      while (true) {
-        int number = getFieldNumber();
-        if (number == READ_DONE || input.isAtEnd()) {
-          break;
-        }
-        try {
-          switch (number) {
-            case 1:
-              key = (K) readField(metadata.keyType, null, null);
-              break;
-            case 2:
-              value =
-                  (V)
-                      readField(
-                          metadata.valueType, metadata.defaultValue.getClass(), extensionRegistry);
-              break;
-            default:
-              if (!skipField()) {
-                throw new InvalidProtocolBufferException("Unable to parse map entry.");
-              }
-              break;
-          }
-        } catch (InvalidProtocolBufferException.InvalidWireTypeException ignore) {
-          // the type doesn't match, skip the field.
-          if (!skipField()) {
-            throw new InvalidProtocolBufferException("Unable to parse map entry.");
-          }
-        }
-      }
-      target.put(key, value);
-    } finally {
-      // Restore the previous limit.
-      input.popLimit(prevLimit);
-    }
-  }
-
-  private Object readField(
-      WireFormat.FieldType fieldType, Class<?> messageType, ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    switch (fieldType) {
-      case BOOL:
-        return readBool();
-      case BYTES:
-        return readBytes();
-      case DOUBLE:
-        return readDouble();
-      case ENUM:
-        return readEnum();
-      case FIXED32:
-        return readFixed32();
-      case FIXED64:
-        return readFixed64();
-      case FLOAT:
-        return readFloat();
-      case INT32:
-        return readInt32();
-      case INT64:
-        return readInt64();
-      case MESSAGE:
-        return readMessage(messageType, extensionRegistry);
-      case SFIXED32:
-        return readSFixed32();
-      case SFIXED64:
-        return readSFixed64();
-      case SINT32:
-        return readSInt32();
-      case SINT64:
-        return readSInt64();
-      case STRING:
-        return readStringRequireUtf8();
-      case UINT32:
-        return readUInt32();
-      case UINT64:
-        return readUInt64();
-      default:
-        throw new RuntimeException("unsupported field type.");
-    }
-  }
-
-  private void verifyPackedFixed32Length(int bytes) throws IOException {
-    if ((bytes & FIXED32_MULTIPLE_MASK) != 0) {
-      // Require that the number of bytes be a multiple of 4.
-      throw InvalidProtocolBufferException.parseFailure();
-    }
-  }
-
-  private void requirePosition(int expectedPosition) throws IOException {
-    if (input.getTotalBytesRead() != expectedPosition) {
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/CodedOutputStream.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/CodedOutputStream.java
deleted file mode 100644
index a9192d3..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/CodedOutputStream.java
+++ /dev/null
@@ -1,3066 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.WireFormat.FIXED32_SIZE;
-import static com.google.protobuf.WireFormat.FIXED64_SIZE;
-import static com.google.protobuf.WireFormat.MAX_VARINT32_SIZE;
-import static com.google.protobuf.WireFormat.MAX_VARINT_SIZE;
-import static java.lang.Math.max;
-
-import com.google.protobuf.Utf8.UnpairedSurrogateException;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.BufferOverflowException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Encodes and writes protocol message fields.
- *
- * <p>This class contains two kinds of methods: methods that write specific protocol message
- * constructs and field types (e.g. {@link #writeTag} and {@link #writeInt32}) and methods that
- * write low-level values (e.g. {@link #writeRawVarint32} and {@link #writeRawBytes}). If you are
- * writing encoded protocol messages, you should use the former methods, but if you are writing some
- * other format of your own design, use the latter.
- *
- * <p>This class is totally unsynchronized.
- */
-public abstract class CodedOutputStream extends ByteOutput {
-  private static final Logger logger = Logger.getLogger(CodedOutputStream.class.getName());
-  private static final boolean HAS_UNSAFE_ARRAY_OPERATIONS = UnsafeUtil.hasUnsafeArrayOperations();
-
-  /** Used to adapt to the experimental {@link Writer} interface. */
-  CodedOutputStreamWriter wrapper;
-
-  /** @deprecated Use {@link #computeFixed32SizeNoTag(int)} instead. */
-  @Deprecated public static final int LITTLE_ENDIAN_32_SIZE = FIXED32_SIZE;
-
-  /** The buffer size used in {@link #newInstance(OutputStream)}. */
-  public static final int DEFAULT_BUFFER_SIZE = 4096;
-
-  /**
-   * Returns the buffer size to efficiently write dataLength bytes to this CodedOutputStream. Used
-   * by AbstractMessageLite.
-   *
-   * @return the buffer size to efficiently write dataLength bytes to this CodedOutputStream.
-   */
-  static int computePreferredBufferSize(int dataLength) {
-    if (dataLength > DEFAULT_BUFFER_SIZE) {
-      return DEFAULT_BUFFER_SIZE;
-    }
-    return dataLength;
-  }
-
-  /**
-   * Create a new {@code CodedOutputStream} wrapping the given {@code OutputStream}.
-   *
-   * <p>NOTE: The provided {@link OutputStream} <strong>MUST NOT</strong> retain access or modify
-   * the provided byte arrays. Doing so may result in corrupted data, which would be difficult to
-   * debug.
-   */
-  public static CodedOutputStream newInstance(final OutputStream output) {
-    return newInstance(output, DEFAULT_BUFFER_SIZE);
-  }
-
-  /**
-   * Create a new {@code CodedOutputStream} wrapping the given {@code OutputStream} with a given
-   * buffer size.
-   *
-   * <p>NOTE: The provided {@link OutputStream} <strong>MUST NOT</strong> retain access or modify
-   * the provided byte arrays. Doing so may result in corrupted data, which would be difficult to
-   * debug.
-   */
-  public static CodedOutputStream newInstance(final OutputStream output, final int bufferSize) {
-    return new OutputStreamEncoder(output, bufferSize);
-  }
-
-  /**
-   * Create a new {@code CodedOutputStream} that writes directly to the given byte array. If more
-   * bytes are written than fit in the array, {@link OutOfSpaceException} will be thrown. Writing
-   * directly to a flat array is faster than writing to an {@code OutputStream}. See also {@link
-   * ByteString#newCodedBuilder}.
-   */
-  public static CodedOutputStream newInstance(final byte[] flatArray) {
-    return newInstance(flatArray, 0, flatArray.length);
-  }
-
-  /**
-   * Create a new {@code CodedOutputStream} that writes directly to the given byte array slice. If
-   * more bytes are written than fit in the slice, {@link OutOfSpaceException} will be thrown.
-   * Writing directly to a flat array is faster than writing to an {@code OutputStream}. See also
-   * {@link ByteString#newCodedBuilder}.
-   */
-  public static CodedOutputStream newInstance(
-      final byte[] flatArray, final int offset, final int length) {
-    return new ArrayEncoder(flatArray, offset, length);
-  }
-
-  /** Create a new {@code CodedOutputStream} that writes to the given {@link ByteBuffer}. */
-  public static CodedOutputStream newInstance(ByteBuffer buffer) {
-    if (buffer.hasArray()) {
-      return new HeapNioEncoder(buffer);
-    }
-    if (buffer.isDirect() && !buffer.isReadOnly()) {
-      return UnsafeDirectNioEncoder.isSupported()
-          ? newUnsafeInstance(buffer)
-          : newSafeInstance(buffer);
-    }
-    throw new IllegalArgumentException("ByteBuffer is read-only");
-  }
-
-  /** For testing purposes only. */
-  static CodedOutputStream newUnsafeInstance(ByteBuffer buffer) {
-    return new UnsafeDirectNioEncoder(buffer);
-  }
-
-  /** For testing purposes only. */
-  static CodedOutputStream newSafeInstance(ByteBuffer buffer) {
-    return new SafeDirectNioEncoder(buffer);
-  }
-
-  /**
-   * Configures serialization to be deterministic.
-   *
-   * <p>The deterministic serialization guarantees that for a given binary, equal (defined by the
-   * {@code equals()} methods in protos) messages will always be serialized to the same bytes. This
-   * implies:
-   *
-   * <ul>
-   *   <li>repeated serialization of a message will return the same bytes
-   *   <li>different processes of the same binary (which may be executing on different machines)
-   *       will serialize equal messages to the same bytes.
-   * </ul>
-   *
-   * <p>Note the deterministic serialization is NOT canonical across languages; it is also unstable
-   * across different builds with schema changes due to unknown fields. Users who need canonical
-   * serialization, e.g. persistent storage in a canonical form, fingerprinting, etc, should define
-   * their own canonicalization specification and implement the serializer using reflection APIs
-   * rather than relying on this API.
-   *
-   * <p>Once set, the serializer will: (Note this is an implementation detail and may subject to
-   * change in the future)
-   *
-   * <ul>
-   *   <li>sort map entries by keys in lexicographical order or numerical order. Note: For string
-   *       keys, the order is based on comparing the Unicode value of each character in the strings.
-   *       The order may be different from the deterministic serialization in other languages where
-   *       maps are sorted on the lexicographical order of the UTF8 encoded keys.
-   * </ul>
-   */
-  public void useDeterministicSerialization() {
-    serializationDeterministic = true;
-  }
-
-  boolean isSerializationDeterministic() {
-    return serializationDeterministic;
-  }
-
-  private boolean serializationDeterministic;
-
-  /**
-   * Create a new {@code CodedOutputStream} that writes to the given {@link ByteBuffer}.
-   *
-   * @deprecated the size parameter is no longer used since use of an internal buffer is useless
-   *     (and wasteful) when writing to a {@link ByteBuffer}. Use {@link #newInstance(ByteBuffer)}
-   *     instead.
-   */
-  @Deprecated
-  public static CodedOutputStream newInstance(
-      ByteBuffer byteBuffer, @SuppressWarnings("unused") int unused) {
-    return newInstance(byteBuffer);
-  }
-
-  /**
-   * Create a new {@code CodedOutputStream} that writes to the provided {@link ByteOutput}.
-   *
-   * <p>NOTE: The {@link ByteOutput} <strong>MUST NOT</strong> modify the provided buffers. Doing so
-   * may result in corrupted data, which would be difficult to debug.
-   *
-   * @param byteOutput the output target for encoded bytes.
-   * @param bufferSize the size of the internal scratch buffer to be used for string encoding.
-   *     Setting this to {@code 0} will disable buffering, requiring an allocation for each encoded
-   *     string.
-   */
-  static CodedOutputStream newInstance(ByteOutput byteOutput, int bufferSize) {
-    if (bufferSize < 0) {
-      throw new IllegalArgumentException("bufferSize must be positive");
-    }
-
-    return new ByteOutputEncoder(byteOutput, bufferSize);
-  }
-
-  // Disallow construction outside of this class.
-  private CodedOutputStream() {}
-
-  // -----------------------------------------------------------------
-
-  /** Encode and write a tag. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeTag(int fieldNumber, int wireType) throws IOException;
-
-  /** Write an {@code int32} field, including tag, to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeInt32(int fieldNumber, int value) throws IOException;
-
-  /** Write a {@code uint32} field, including tag, to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeUInt32(int fieldNumber, int value) throws IOException;
-
-  /** Write a {@code sint32} field, including tag, to the stream. */
-  public final void writeSInt32(final int fieldNumber, final int value) throws IOException {
-    writeUInt32(fieldNumber, encodeZigZag32(value));
-  }
-
-  /** Write a {@code fixed32} field, including tag, to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeFixed32(int fieldNumber, int value) throws IOException;
-
-  /** Write an {@code sfixed32} field, including tag, to the stream. */
-  public final void writeSFixed32(final int fieldNumber, final int value) throws IOException {
-    writeFixed32(fieldNumber, value);
-  }
-
-  /** Write an {@code int64} field, including tag, to the stream. */
-  public final void writeInt64(final int fieldNumber, final long value) throws IOException {
-    writeUInt64(fieldNumber, value);
-  }
-
-  /** Write a {@code uint64} field, including tag, to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeUInt64(int fieldNumber, long value) throws IOException;
-
-  /** Write an {@code sint64} field, including tag, to the stream. */
-  public final void writeSInt64(final int fieldNumber, final long value) throws IOException {
-    writeUInt64(fieldNumber, encodeZigZag64(value));
-  }
-
-  /** Write a {@code fixed64} field, including tag, to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeFixed64(int fieldNumber, long value) throws IOException;
-
-  /** Write an {@code sfixed64} field, including tag, to the stream. */
-  public final void writeSFixed64(final int fieldNumber, final long value) throws IOException {
-    writeFixed64(fieldNumber, value);
-  }
-
-  /** Write a {@code float} field, including tag, to the stream. */
-  public final void writeFloat(final int fieldNumber, final float value) throws IOException {
-    writeFixed32(fieldNumber, Float.floatToRawIntBits(value));
-  }
-
-  /** Write a {@code double} field, including tag, to the stream. */
-  public final void writeDouble(final int fieldNumber, final double value) throws IOException {
-    writeFixed64(fieldNumber, Double.doubleToRawLongBits(value));
-  }
-
-  /** Write a {@code bool} field, including tag, to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeBool(int fieldNumber, boolean value) throws IOException;
-
-  /**
-   * Write an enum field, including tag, to the stream. The provided value is the numeric value used
-   * to represent the enum value on the wire (not the enum ordinal value).
-   */
-  public final void writeEnum(final int fieldNumber, final int value) throws IOException {
-    writeInt32(fieldNumber, value);
-  }
-
-  /** Write a {@code string} field, including tag, to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeString(int fieldNumber, String value) throws IOException;
-
-  /** Write a {@code bytes} field, including tag, to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeBytes(int fieldNumber, ByteString value) throws IOException;
-
-  /** Write a {@code bytes} field, including tag, to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeByteArray(int fieldNumber, byte[] value) throws IOException;
-
-  /** Write a {@code bytes} field, including tag, to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeByteArray(int fieldNumber, byte[] value, int offset, int length)
-      throws IOException;
-
-  /**
-   * Write a {@code bytes} field, including tag, to the stream. This method will write all content
-   * of the ByteBuffer regardless of the current position and limit (i.e., the number of bytes to be
-   * written is value.capacity(), not value.remaining()). Furthermore, this method doesn't alter the
-   * state of the passed-in ByteBuffer. Its position, limit, mark, etc. will remain unchanged. If
-   * you only want to write the remaining bytes of a ByteBuffer, you can call {@code
-   * writeByteBuffer(fieldNumber, byteBuffer.slice())}.
-   */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeByteBuffer(int fieldNumber, ByteBuffer value) throws IOException;
-
-  /** Write a single byte. */
-  public final void writeRawByte(final byte value) throws IOException {
-    write(value);
-  }
-
-  /** Write a single byte, represented by an integer value. */
-  public final void writeRawByte(final int value) throws IOException {
-    write((byte) value);
-  }
-
-  /** Write an array of bytes. */
-  public final void writeRawBytes(final byte[] value) throws IOException {
-    write(value, 0, value.length);
-  }
-
-  /** Write part of an array of bytes. */
-  public final void writeRawBytes(final byte[] value, int offset, int length) throws IOException {
-    write(value, offset, length);
-  }
-
-  /** Write a byte string. */
-  public final void writeRawBytes(final ByteString value) throws IOException {
-    value.writeTo(this);
-  }
-
-  /**
-   * Write a ByteBuffer. This method will write all content of the ByteBuffer regardless of the
-   * current position and limit (i.e., the number of bytes to be written is value.capacity(), not
-   * value.remaining()). Furthermore, this method doesn't alter the state of the passed-in
-   * ByteBuffer. Its position, limit, mark, etc. will remain unchanged. If you only want to write
-   * the remaining bytes of a ByteBuffer, you can call {@code writeRawBytes(byteBuffer.slice())}.
-   */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeRawBytes(final ByteBuffer value) throws IOException;
-
-  /** Write an embedded message field, including tag, to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeMessage(final int fieldNumber, final MessageLite value)
-      throws IOException;
-
-  /** Write an embedded message field, including tag, to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  abstract void writeMessage(final int fieldNumber, final MessageLite value, Schema schema)
-      throws IOException;
-
-  /**
-   * Write a MessageSet extension field to the stream. For historical reasons, the wire format
-   * differs from normal fields.
-   */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
-      throws IOException;
-
-  /**
-   * Write an unparsed MessageSet extension field to the stream. For historical reasons, the wire
-   * format differs from normal fields.
-   */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeRawMessageSetExtension(final int fieldNumber, final ByteString value)
-      throws IOException;
-
-  // -----------------------------------------------------------------
-
-  /** Write an {@code int32} field to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeInt32NoTag(final int value) throws IOException;
-
-  /** Write a {@code uint32} field to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeUInt32NoTag(int value) throws IOException;
-
-  /** Write a {@code sint32} field to the stream. */
-  public final void writeSInt32NoTag(final int value) throws IOException {
-    writeUInt32NoTag(encodeZigZag32(value));
-  }
-
-  /** Write a {@code fixed32} field to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeFixed32NoTag(int value) throws IOException;
-
-  /** Write a {@code sfixed32} field to the stream. */
-  public final void writeSFixed32NoTag(final int value) throws IOException {
-    writeFixed32NoTag(value);
-  }
-
-  /** Write an {@code int64} field to the stream. */
-  public final void writeInt64NoTag(final long value) throws IOException {
-    writeUInt64NoTag(value);
-  }
-
-  /** Write a {@code uint64} field to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeUInt64NoTag(long value) throws IOException;
-
-  /** Write a {@code sint64} field to the stream. */
-  public final void writeSInt64NoTag(final long value) throws IOException {
-    writeUInt64NoTag(encodeZigZag64(value));
-  }
-
-  /** Write a {@code fixed64} field to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeFixed64NoTag(long value) throws IOException;
-
-  /** Write a {@code sfixed64} field to the stream. */
-  public final void writeSFixed64NoTag(final long value) throws IOException {
-    writeFixed64NoTag(value);
-  }
-
-  /** Write a {@code float} field to the stream. */
-  public final void writeFloatNoTag(final float value) throws IOException {
-    writeFixed32NoTag(Float.floatToRawIntBits(value));
-  }
-
-  /** Write a {@code double} field to the stream. */
-  public final void writeDoubleNoTag(final double value) throws IOException {
-    writeFixed64NoTag(Double.doubleToRawLongBits(value));
-  }
-
-  /** Write a {@code bool} field to the stream. */
-  public final void writeBoolNoTag(final boolean value) throws IOException {
-    write((byte) (value ? 1 : 0));
-  }
-
-  /**
-   * Write an enum field to the stream. The provided value is the numeric value used to represent
-   * the enum value on the wire (not the enum ordinal value).
-   */
-  public final void writeEnumNoTag(final int value) throws IOException {
-    writeInt32NoTag(value);
-  }
-
-  /** Write a {@code string} field to the stream. */
-  // TODO(dweis): Document behavior on ill-formed UTF-16 input.
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeStringNoTag(String value) throws IOException;
-
-  /** Write a {@code bytes} field to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeBytesNoTag(final ByteString value) throws IOException;
-
-  /** Write a {@code bytes} field to the stream. */
-  public final void writeByteArrayNoTag(final byte[] value) throws IOException {
-    writeByteArrayNoTag(value, 0, value.length);
-  }
-
-  /** Write an embedded message field to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  public abstract void writeMessageNoTag(final MessageLite value) throws IOException;
-
-  /** Write an embedded message field to the stream. */
-  // Abstract to avoid overhead of additional virtual method calls.
-  abstract void writeMessageNoTag(final MessageLite value, Schema schema) throws IOException;
-
-  // =================================================================
-
-  @ExperimentalApi
-  @Override
-  public abstract void write(byte value) throws IOException;
-
-  @ExperimentalApi
-  @Override
-  public abstract void write(byte[] value, int offset, int length) throws IOException;
-
-  @ExperimentalApi
-  @Override
-  public abstract void writeLazy(byte[] value, int offset, int length) throws IOException;
-
-  @Override
-  public abstract void write(ByteBuffer value) throws IOException;
-
-  @ExperimentalApi
-  @Override
-  public abstract void writeLazy(ByteBuffer value) throws IOException;
-
-  // =================================================================
-  // =================================================================
-
-  /**
-   * Compute the number of bytes that would be needed to encode an {@code int32} field, including
-   * tag.
-   */
-  public static int computeInt32Size(final int fieldNumber, final int value) {
-    return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a {@code uint32} field, including
-   * tag.
-   */
-  public static int computeUInt32Size(final int fieldNumber, final int value) {
-    return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode an {@code sint32} field, including
-   * tag.
-   */
-  public static int computeSInt32Size(final int fieldNumber, final int value) {
-    return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a {@code fixed32} field, including
-   * tag.
-   */
-  public static int computeFixed32Size(final int fieldNumber, final int value) {
-    return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode an {@code sfixed32} field, including
-   * tag.
-   */
-  public static int computeSFixed32Size(final int fieldNumber, final int value) {
-    return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode an {@code int64} field, including
-   * tag.
-   */
-  public static int computeInt64Size(final int fieldNumber, final long value) {
-    return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a {@code uint64} field, including
-   * tag.
-   */
-  public static int computeUInt64Size(final int fieldNumber, final long value) {
-    return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode an {@code sint64} field, including
-   * tag.
-   */
-  public static int computeSInt64Size(final int fieldNumber, final long value) {
-    return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a {@code fixed64} field, including
-   * tag.
-   */
-  public static int computeFixed64Size(final int fieldNumber, final long value) {
-    return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode an {@code sfixed64} field, including
-   * tag.
-   */
-  public static int computeSFixed64Size(final int fieldNumber, final long value) {
-    return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a {@code float} field, including
-   * tag.
-   */
-  public static int computeFloatSize(final int fieldNumber, final float value) {
-    return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a {@code double} field, including
-   * tag.
-   */
-  public static int computeDoubleSize(final int fieldNumber, final double value) {
-    return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a {@code bool} field, including tag.
-   */
-  public static int computeBoolSize(final int fieldNumber, final boolean value) {
-    return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode an enum field, including tag. The
-   * provided value is the numeric value used to represent the enum value on the wire (not the enum
-   * ordinal value).
-   */
-  public static int computeEnumSize(final int fieldNumber, final int value) {
-    return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a {@code string} field, including
-   * tag.
-   */
-  public static int computeStringSize(final int fieldNumber, final String value) {
-    return computeTagSize(fieldNumber) + computeStringSizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a {@code bytes} field, including
-   * tag.
-   */
-  public static int computeBytesSize(final int fieldNumber, final ByteString value) {
-    return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a {@code bytes} field, including
-   * tag.
-   */
-  public static int computeByteArraySize(final int fieldNumber, final byte[] value) {
-    return computeTagSize(fieldNumber) + computeByteArraySizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a {@code bytes} field, including
-   * tag.
-   */
-  public static int computeByteBufferSize(final int fieldNumber, final ByteBuffer value) {
-    return computeTagSize(fieldNumber) + computeByteBufferSizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode an embedded message in lazy field,
-   * including tag.
-   */
-  public static int computeLazyFieldSize(final int fieldNumber, final LazyFieldLite value) {
-    return computeTagSize(fieldNumber) + computeLazyFieldSizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode an embedded message field, including
-   * tag.
-   */
-  public static int computeMessageSize(final int fieldNumber, final MessageLite value) {
-    return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode an embedded message field, including
-   * tag.
-   */
-  static int computeMessageSize(
-      final int fieldNumber, final MessageLite value, final Schema schema) {
-    return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value, schema);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a MessageSet extension to the
-   * stream. For historical reasons, the wire format differs from normal fields.
-   */
-  public static int computeMessageSetExtensionSize(final int fieldNumber, final MessageLite value) {
-    return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2
-        + computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber)
-        + computeMessageSize(WireFormat.MESSAGE_SET_MESSAGE, value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode an unparsed MessageSet extension
-   * field to the stream. For historical reasons, the wire format differs from normal fields.
-   */
-  public static int computeRawMessageSetExtensionSize(
-      final int fieldNumber, final ByteString value) {
-    return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2
-        + computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber)
-        + computeBytesSize(WireFormat.MESSAGE_SET_MESSAGE, value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode an lazily parsed MessageSet
-   * extension field to the stream. For historical reasons, the wire format differs from normal
-   * fields.
-   */
-  public static int computeLazyFieldMessageSetExtensionSize(
-      final int fieldNumber, final LazyFieldLite value) {
-    return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2
-        + computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber)
-        + computeLazyFieldSize(WireFormat.MESSAGE_SET_MESSAGE, value);
-  }
-
-  // -----------------------------------------------------------------
-
-  /** Compute the number of bytes that would be needed to encode a tag. */
-  public static int computeTagSize(final int fieldNumber) {
-    return computeUInt32SizeNoTag(WireFormat.makeTag(fieldNumber, 0));
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode an {@code int32} field, including
-   * tag.
-   */
-  public static int computeInt32SizeNoTag(final int value) {
-    if (value >= 0) {
-      return computeUInt32SizeNoTag(value);
-    } else {
-      // Must sign-extend.
-      return MAX_VARINT_SIZE;
-    }
-  }
-
-  /** Compute the number of bytes that would be needed to encode a {@code uint32} field. */
-  public static int computeUInt32SizeNoTag(final int value) {
-    if ((value & (~0 << 7)) == 0) {
-      return 1;
-    }
-    if ((value & (~0 << 14)) == 0) {
-      return 2;
-    }
-    if ((value & (~0 << 21)) == 0) {
-      return 3;
-    }
-    if ((value & (~0 << 28)) == 0) {
-      return 4;
-    }
-    return 5;
-  }
-
-  /** Compute the number of bytes that would be needed to encode an {@code sint32} field. */
-  public static int computeSInt32SizeNoTag(final int value) {
-    return computeUInt32SizeNoTag(encodeZigZag32(value));
-  }
-
-  /** Compute the number of bytes that would be needed to encode a {@code fixed32} field. */
-  public static int computeFixed32SizeNoTag(@SuppressWarnings("unused") final int unused) {
-    return FIXED32_SIZE;
-  }
-
-  /** Compute the number of bytes that would be needed to encode an {@code sfixed32} field. */
-  public static int computeSFixed32SizeNoTag(@SuppressWarnings("unused") final int unused) {
-    return FIXED32_SIZE;
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode an {@code int64} field, including
-   * tag.
-   */
-  public static int computeInt64SizeNoTag(final long value) {
-    return computeUInt64SizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a {@code uint64} field, including
-   * tag.
-   */
-  public static int computeUInt64SizeNoTag(long value) {
-    // handle two popular special cases up front ...
-    if ((value & (~0L << 7)) == 0L) {
-      return 1;
-    }
-    if (value < 0L) {
-      return 10;
-    }
-    // ... leaving us with 8 remaining, which we can divide and conquer
-    int n = 2;
-    if ((value & (~0L << 35)) != 0L) {
-      n += 4;
-      value >>>= 28;
-    }
-    if ((value & (~0L << 21)) != 0L) {
-      n += 2;
-      value >>>= 14;
-    }
-    if ((value & (~0L << 14)) != 0L) {
-      n += 1;
-    }
-    return n;
-  }
-
-  /** Compute the number of bytes that would be needed to encode an {@code sint64} field. */
-  public static int computeSInt64SizeNoTag(final long value) {
-    return computeUInt64SizeNoTag(encodeZigZag64(value));
-  }
-
-  /** Compute the number of bytes that would be needed to encode a {@code fixed64} field. */
-  public static int computeFixed64SizeNoTag(@SuppressWarnings("unused") final long unused) {
-    return FIXED64_SIZE;
-  }
-
-  /** Compute the number of bytes that would be needed to encode an {@code sfixed64} field. */
-  public static int computeSFixed64SizeNoTag(@SuppressWarnings("unused") final long unused) {
-    return FIXED64_SIZE;
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a {@code float} field, including
-   * tag.
-   */
-  public static int computeFloatSizeNoTag(@SuppressWarnings("unused") final float unused) {
-    return FIXED32_SIZE;
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a {@code double} field, including
-   * tag.
-   */
-  public static int computeDoubleSizeNoTag(@SuppressWarnings("unused") final double unused) {
-    return FIXED64_SIZE;
-  }
-
-  /** Compute the number of bytes that would be needed to encode a {@code bool} field. */
-  public static int computeBoolSizeNoTag(@SuppressWarnings("unused") final boolean unused) {
-    return 1;
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode an enum field. The provided value is
-   * the numeric value used to represent the enum value on the wire (not the enum ordinal value).
-   */
-  public static int computeEnumSizeNoTag(final int value) {
-    return computeInt32SizeNoTag(value);
-  }
-
-  /** Compute the number of bytes that would be needed to encode a {@code string} field. */
-  public static int computeStringSizeNoTag(final String value) {
-    int length;
-    try {
-      length = Utf8.encodedLength(value);
-    } catch (UnpairedSurrogateException e) {
-      // TODO(dweis): Consider using nio Charset methods instead.
-      final byte[] bytes = value.getBytes(Internal.UTF_8);
-      length = bytes.length;
-    }
-
-    return computeLengthDelimitedFieldSize(length);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode an embedded message stored in lazy
-   * field.
-   */
-  public static int computeLazyFieldSizeNoTag(final LazyFieldLite value) {
-    return computeLengthDelimitedFieldSize(value.getSerializedSize());
-  }
-
-  /** Compute the number of bytes that would be needed to encode a {@code bytes} field. */
-  public static int computeBytesSizeNoTag(final ByteString value) {
-    return computeLengthDelimitedFieldSize(value.size());
-  }
-
-  /** Compute the number of bytes that would be needed to encode a {@code bytes} field. */
-  public static int computeByteArraySizeNoTag(final byte[] value) {
-    return computeLengthDelimitedFieldSize(value.length);
-  }
-
-  /** Compute the number of bytes that would be needed to encode a {@code bytes} field. */
-  public static int computeByteBufferSizeNoTag(final ByteBuffer value) {
-    return computeLengthDelimitedFieldSize(value.capacity());
-  }
-
-  /** Compute the number of bytes that would be needed to encode an embedded message field. */
-  public static int computeMessageSizeNoTag(final MessageLite value) {
-    return computeLengthDelimitedFieldSize(value.getSerializedSize());
-  }
-
-  /** Compute the number of bytes that would be needed to encode an embedded message field. */
-  static int computeMessageSizeNoTag(final MessageLite value, final Schema schema) {
-    return computeLengthDelimitedFieldSize(((AbstractMessageLite) value).getSerializedSize(schema));
-  }
-
-  static int computeLengthDelimitedFieldSize(int fieldLength) {
-    return computeUInt32SizeNoTag(fieldLength) + fieldLength;
-  }
-
-  /**
-   * Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers into values that can be
-   * efficiently encoded with varint. (Otherwise, negative values must be sign-extended to 64 bits
-   * to be varint encoded, thus always taking 10 bytes on the wire.)
-   *
-   * @param n A signed 32-bit integer.
-   * @return An unsigned 32-bit integer, stored in a signed int because Java has no explicit
-   *     unsigned support.
-   */
-  public static int encodeZigZag32(final int n) {
-    // Note:  the right-shift must be arithmetic
-    return (n << 1) ^ (n >> 31);
-  }
-
-  /**
-   * Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers into values that can be
-   * efficiently encoded with varint. (Otherwise, negative values must be sign-extended to 64 bits
-   * to be varint encoded, thus always taking 10 bytes on the wire.)
-   *
-   * @param n A signed 64-bit integer.
-   * @return An unsigned 64-bit integer, stored in a signed int because Java has no explicit
-   *     unsigned support.
-   */
-  public static long encodeZigZag64(final long n) {
-    // Note:  the right-shift must be arithmetic
-    return (n << 1) ^ (n >> 63);
-  }
-
-  // =================================================================
-
-  /**
-   * Flushes the stream and forces any buffered bytes to be written. This does not flush the
-   * underlying OutputStream.
-   */
-  public abstract void flush() throws IOException;
-
-  /**
-   * If writing to a flat array, return the space left in the array. Otherwise, throws {@code
-   * UnsupportedOperationException}.
-   */
-  public abstract int spaceLeft();
-
-  /**
-   * Verifies that {@link #spaceLeft()} returns zero. It's common to create a byte array that is
-   * exactly big enough to hold a message, then write to it with a {@code CodedOutputStream}.
-   * Calling {@code checkNoSpaceLeft()} after writing verifies that the message was actually as big
-   * as expected, which can help catch bugs.
-   */
-  public final void checkNoSpaceLeft() {
-    if (spaceLeft() != 0) {
-      throw new IllegalStateException("Did not write as much data as expected.");
-    }
-  }
-
-  /**
-   * If you create a CodedOutputStream around a simple flat array, you must not attempt to write
-   * more bytes than the array has space. Otherwise, this exception will be thrown.
-   */
-  public static class OutOfSpaceException extends IOException {
-    private static final long serialVersionUID = -6947486886997889499L;
-
-    private static final String MESSAGE =
-        "CodedOutputStream was writing to a flat byte array and ran out of space.";
-
-    OutOfSpaceException() {
-      super(MESSAGE);
-    }
-
-    OutOfSpaceException(String explanationMessage) {
-      super(MESSAGE + ": " + explanationMessage);
-    }
-
-    OutOfSpaceException(Throwable cause) {
-      super(MESSAGE, cause);
-    }
-
-    OutOfSpaceException(String explanationMessage, Throwable cause) {
-      super(MESSAGE + ": " + explanationMessage, cause);
-    }
-  }
-
-  /**
-   * Get the total number of bytes successfully written to this stream. The returned value is not
-   * guaranteed to be accurate if exceptions have been found in the middle of writing.
-   */
-  public abstract int getTotalBytesWritten();
-
-  // =================================================================
-
-  /** Write a {@code bytes} field to the stream. Visible for testing. */
-  abstract void writeByteArrayNoTag(final byte[] value, final int offset, final int length)
-      throws IOException;
-
-  final void inefficientWriteStringNoTag(String value, UnpairedSurrogateException cause)
-      throws IOException {
-    logger.log(
-        Level.WARNING,
-        "Converting ill-formed UTF-16. Your Protocol Buffer will not round trip correctly!",
-        cause);
-
-    // Unfortunately there does not appear to be any way to tell Java to encode
-    // UTF-8 directly into our buffer, so we have to let it create its own byte
-    // array and then copy.
-    // TODO(dweis): Consider using nio Charset methods instead.
-    final byte[] bytes = value.getBytes(Internal.UTF_8);
-    try {
-      writeUInt32NoTag(bytes.length);
-      writeLazy(bytes, 0, bytes.length);
-    } catch (IndexOutOfBoundsException e) {
-      throw new OutOfSpaceException(e);
-    } catch (OutOfSpaceException e) {
-      throw e;
-    }
-  }
-
-  // =================================================================
-
-  /**
-   * Write a {@code group} field, including tag, to the stream.
-   *
-   * @deprecated groups are deprecated.
-   */
-  @Deprecated
-  public final void writeGroup(final int fieldNumber, final MessageLite value) throws IOException {
-    writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP);
-    writeGroupNoTag(value);
-    writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
-  }
-
-  /**
-   * Write a {@code group} field, including tag, to the stream.
-   *
-   * @deprecated groups are deprecated.
-   */
-  @Deprecated
-  final void writeGroup(final int fieldNumber, final MessageLite value, Schema schema)
-      throws IOException {
-    writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP);
-    writeGroupNoTag(value, schema);
-    writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
-  }
-
-  /**
-   * Write a {@code group} field to the stream.
-   *
-   * @deprecated groups are deprecated.
-   */
-  @Deprecated
-  public final void writeGroupNoTag(final MessageLite value) throws IOException {
-    value.writeTo(this);
-  }
-
-  /**
-   * Write a {@code group} field to the stream.
-   *
-   * @deprecated groups are deprecated.
-   */
-  @Deprecated
-  final void writeGroupNoTag(final MessageLite value, Schema schema) throws IOException {
-    schema.writeTo(value, wrapper);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a {@code group} field, including
-   * tag.
-   *
-   * @deprecated groups are deprecated.
-   */
-  @Deprecated
-  public static int computeGroupSize(final int fieldNumber, final MessageLite value) {
-    return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a {@code group} field, including
-   * tag.
-   *
-   * @deprecated groups are deprecated.
-   */
-  @Deprecated
-  static int computeGroupSize(final int fieldNumber, final MessageLite value, Schema schema) {
-    return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value, schema);
-  }
-
-  /** Compute the number of bytes that would be needed to encode a {@code group} field. */
-  @Deprecated
-  public static int computeGroupSizeNoTag(final MessageLite value) {
-    return value.getSerializedSize();
-  }
-
-  /** Compute the number of bytes that would be needed to encode a {@code group} field. */
-  @Deprecated
-  static int computeGroupSizeNoTag(final MessageLite value, Schema schema) {
-    return ((AbstractMessageLite) value).getSerializedSize(schema);
-  }
-
-  /**
-   * Encode and write a varint. {@code value} is treated as unsigned, so it won't be sign-extended
-   * if negative.
-   *
-   * @deprecated use {@link #writeUInt32NoTag} instead.
-   */
-  @Deprecated
-  public final void writeRawVarint32(int value) throws IOException {
-    writeUInt32NoTag(value);
-  }
-
-  /**
-   * Encode and write a varint.
-   *
-   * @deprecated use {@link #writeUInt64NoTag} instead.
-   */
-  @Deprecated
-  public final void writeRawVarint64(long value) throws IOException {
-    writeUInt64NoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a varint. {@code value} is treated
-   * as unsigned, so it won't be sign-extended if negative.
-   *
-   * @deprecated use {@link #computeUInt32SizeNoTag(int)} instead.
-   */
-  @Deprecated
-  public static int computeRawVarint32Size(final int value) {
-    return computeUInt32SizeNoTag(value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a varint.
-   *
-   * @deprecated use {@link #computeUInt64SizeNoTag(long)} instead.
-   */
-  @Deprecated
-  public static int computeRawVarint64Size(long value) {
-    return computeUInt64SizeNoTag(value);
-  }
-
-  /**
-   * Write a little-endian 32-bit integer.
-   *
-   * @deprecated Use {@link #writeFixed32NoTag} instead.
-   */
-  @Deprecated
-  public final void writeRawLittleEndian32(final int value) throws IOException {
-    writeFixed32NoTag(value);
-  }
-
-  /**
-   * Write a little-endian 64-bit integer.
-   *
-   * @deprecated Use {@link #writeFixed64NoTag} instead.
-   */
-  @Deprecated
-  public final void writeRawLittleEndian64(final long value) throws IOException {
-    writeFixed64NoTag(value);
-  }
-
-  // =================================================================
-
-  /** A {@link CodedOutputStream} that writes directly to a byte array. */
-  private static class ArrayEncoder extends CodedOutputStream {
-    private final byte[] buffer;
-    private final int offset;
-    private final int limit;
-    private int position;
-
-    ArrayEncoder(byte[] buffer, int offset, int length) {
-      if (buffer == null) {
-        throw new NullPointerException("buffer");
-      }
-      if ((offset | length | (buffer.length - (offset + length))) < 0) {
-        throw new IllegalArgumentException(
-            String.format(
-                "Array range is invalid. Buffer.length=%d, offset=%d, length=%d",
-                buffer.length, offset, length));
-      }
-      this.buffer = buffer;
-      this.offset = offset;
-      position = offset;
-      limit = offset + length;
-    }
-
-    @Override
-    public final void writeTag(final int fieldNumber, final int wireType) throws IOException {
-      writeUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType));
-    }
-
-    @Override
-    public final void writeInt32(final int fieldNumber, final int value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      writeInt32NoTag(value);
-    }
-
-    @Override
-    public final void writeUInt32(final int fieldNumber, final int value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      writeUInt32NoTag(value);
-    }
-
-    @Override
-    public final void writeFixed32(final int fieldNumber, final int value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
-      writeFixed32NoTag(value);
-    }
-
-    @Override
-    public final void writeUInt64(final int fieldNumber, final long value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      writeUInt64NoTag(value);
-    }
-
-    @Override
-    public final void writeFixed64(final int fieldNumber, final long value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
-      writeFixed64NoTag(value);
-    }
-
-    @Override
-    public final void writeBool(final int fieldNumber, final boolean value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      write((byte) (value ? 1 : 0));
-    }
-
-    @Override
-    public final void writeString(final int fieldNumber, final String value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeStringNoTag(value);
-    }
-
-    @Override
-    public final void writeBytes(final int fieldNumber, final ByteString value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeBytesNoTag(value);
-    }
-
-    @Override
-    public final void writeByteArray(final int fieldNumber, final byte[] value) throws IOException {
-      writeByteArray(fieldNumber, value, 0, value.length);
-    }
-
-    @Override
-    public final void writeByteArray(
-        final int fieldNumber, final byte[] value, final int offset, final int length)
-        throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeByteArrayNoTag(value, offset, length);
-    }
-
-    @Override
-    public final void writeByteBuffer(final int fieldNumber, final ByteBuffer value)
-        throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeUInt32NoTag(value.capacity());
-      writeRawBytes(value);
-    }
-
-    @Override
-    public final void writeBytesNoTag(final ByteString value) throws IOException {
-      writeUInt32NoTag(value.size());
-      value.writeTo(this);
-    }
-
-    @Override
-    public final void writeByteArrayNoTag(final byte[] value, int offset, int length)
-        throws IOException {
-      writeUInt32NoTag(length);
-      write(value, offset, length);
-    }
-
-    @Override
-    public final void writeRawBytes(final ByteBuffer value) throws IOException {
-      if (value.hasArray()) {
-        write(value.array(), value.arrayOffset(), value.capacity());
-      } else {
-        ByteBuffer duplicated = value.duplicate();
-        duplicated.clear();
-        write(duplicated);
-      }
-    }
-
-    @Override
-    public final void writeMessage(final int fieldNumber, final MessageLite value)
-        throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeMessageNoTag(value);
-    }
-
-    @Override
-    final void writeMessage(final int fieldNumber, final MessageLite value, Schema schema)
-        throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeUInt32NoTag(((AbstractMessageLite) value).getSerializedSize(schema));
-      schema.writeTo(value, wrapper);
-    }
-
-    @Override
-    public final void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
-        throws IOException {
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
-      writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
-      writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
-    }
-
-    @Override
-    public final void writeRawMessageSetExtension(final int fieldNumber, final ByteString value)
-        throws IOException {
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
-      writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
-      writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
-    }
-
-    @Override
-    public final void writeMessageNoTag(final MessageLite value) throws IOException {
-      writeUInt32NoTag(value.getSerializedSize());
-      value.writeTo(this);
-    }
-
-    @Override
-    final void writeMessageNoTag(final MessageLite value, Schema schema) throws IOException {
-      writeUInt32NoTag(((AbstractMessageLite) value).getSerializedSize(schema));
-      schema.writeTo(value, wrapper);
-    }
-
-    @Override
-    public final void write(byte value) throws IOException {
-      try {
-        buffer[position++] = value;
-      } catch (IndexOutOfBoundsException e) {
-        throw new OutOfSpaceException(
-            String.format("Pos: %d, limit: %d, len: %d", position, limit, 1), e);
-      }
-    }
-
-    @Override
-    public final void writeInt32NoTag(int value) throws IOException {
-      if (value >= 0) {
-        writeUInt32NoTag(value);
-      } else {
-        // Must sign-extend.
-        writeUInt64NoTag(value);
-      }
-    }
-
-    @Override
-    public final void writeUInt32NoTag(int value) throws IOException {
-      if (HAS_UNSAFE_ARRAY_OPERATIONS
-          && !Android.isOnAndroidDevice()
-          && spaceLeft() >= MAX_VARINT32_SIZE) {
-        if ((value & ~0x7F) == 0) {
-          UnsafeUtil.putByte(buffer, position++, (byte) value);
-          return;
-        }
-        UnsafeUtil.putByte(buffer, position++, (byte) (value | 0x80));
-        value >>>= 7;
-        if ((value & ~0x7F) == 0) {
-          UnsafeUtil.putByte(buffer, position++, (byte) value);
-          return;
-        }
-        UnsafeUtil.putByte(buffer, position++, (byte) (value | 0x80));
-        value >>>= 7;
-        if ((value & ~0x7F) == 0) {
-          UnsafeUtil.putByte(buffer, position++, (byte) value);
-          return;
-        }
-        UnsafeUtil.putByte(buffer, position++, (byte) (value | 0x80));
-        value >>>= 7;
-        if ((value & ~0x7F) == 0) {
-          UnsafeUtil.putByte(buffer, position++, (byte) value);
-          return;
-        }
-        UnsafeUtil.putByte(buffer, position++, (byte) (value | 0x80));
-        value >>>= 7;
-        UnsafeUtil.putByte(buffer, position++, (byte) value);
-      } else {
-        try {
-          while (true) {
-            if ((value & ~0x7F) == 0) {
-              buffer[position++] = (byte) value;
-              return;
-            } else {
-              buffer[position++] = (byte) ((value & 0x7F) | 0x80);
-              value >>>= 7;
-            }
-          }
-        } catch (IndexOutOfBoundsException e) {
-          throw new OutOfSpaceException(
-              String.format("Pos: %d, limit: %d, len: %d", position, limit, 1), e);
-        }
-      }
-    }
-
-    @Override
-    public final void writeFixed32NoTag(int value) throws IOException {
-      try {
-        buffer[position++] = (byte) (value & 0xFF);
-        buffer[position++] = (byte) ((value >> 8) & 0xFF);
-        buffer[position++] = (byte) ((value >> 16) & 0xFF);
-        buffer[position++] = (byte) ((value >> 24) & 0xFF);
-      } catch (IndexOutOfBoundsException e) {
-        throw new OutOfSpaceException(
-            String.format("Pos: %d, limit: %d, len: %d", position, limit, 1), e);
-      }
-    }
-
-    @Override
-    public final void writeUInt64NoTag(long value) throws IOException {
-      if (HAS_UNSAFE_ARRAY_OPERATIONS && spaceLeft() >= MAX_VARINT_SIZE) {
-        while (true) {
-          if ((value & ~0x7FL) == 0) {
-            UnsafeUtil.putByte(buffer, position++, (byte) value);
-            return;
-          } else {
-            UnsafeUtil.putByte(buffer, position++, (byte) (((int) value & 0x7F) | 0x80));
-            value >>>= 7;
-          }
-        }
-      } else {
-        try {
-          while (true) {
-            if ((value & ~0x7FL) == 0) {
-              buffer[position++] = (byte) value;
-              return;
-            } else {
-              buffer[position++] = (byte) (((int) value & 0x7F) | 0x80);
-              value >>>= 7;
-            }
-          }
-        } catch (IndexOutOfBoundsException e) {
-          throw new OutOfSpaceException(
-              String.format("Pos: %d, limit: %d, len: %d", position, limit, 1), e);
-        }
-      }
-    }
-
-    @Override
-    public final void writeFixed64NoTag(long value) throws IOException {
-      try {
-        buffer[position++] = (byte) ((int) (value) & 0xFF);
-        buffer[position++] = (byte) ((int) (value >> 8) & 0xFF);
-        buffer[position++] = (byte) ((int) (value >> 16) & 0xFF);
-        buffer[position++] = (byte) ((int) (value >> 24) & 0xFF);
-        buffer[position++] = (byte) ((int) (value >> 32) & 0xFF);
-        buffer[position++] = (byte) ((int) (value >> 40) & 0xFF);
-        buffer[position++] = (byte) ((int) (value >> 48) & 0xFF);
-        buffer[position++] = (byte) ((int) (value >> 56) & 0xFF);
-      } catch (IndexOutOfBoundsException e) {
-        throw new OutOfSpaceException(
-            String.format("Pos: %d, limit: %d, len: %d", position, limit, 1), e);
-      }
-    }
-
-    @Override
-    public final void write(byte[] value, int offset, int length) throws IOException {
-      try {
-        System.arraycopy(value, offset, buffer, position, length);
-        position += length;
-      } catch (IndexOutOfBoundsException e) {
-        throw new OutOfSpaceException(
-            String.format("Pos: %d, limit: %d, len: %d", position, limit, length), e);
-      }
-    }
-
-    @Override
-    public final void writeLazy(byte[] value, int offset, int length) throws IOException {
-      write(value, offset, length);
-    }
-
-    @Override
-    public final void write(ByteBuffer value) throws IOException {
-      final int length = value.remaining();
-      try {
-        value.get(buffer, position, length);
-        position += length;
-      } catch (IndexOutOfBoundsException e) {
-        throw new OutOfSpaceException(
-            String.format("Pos: %d, limit: %d, len: %d", position, limit, length), e);
-      }
-    }
-
-    @Override
-    public final void writeLazy(ByteBuffer value) throws IOException {
-      write(value);
-    }
-
-    @Override
-    public final void writeStringNoTag(String value) throws IOException {
-      final int oldPosition = position;
-      try {
-        // UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
-        // and at most 3 times of it. We take advantage of this in both branches below.
-        final int maxLength = value.length() * Utf8.MAX_BYTES_PER_CHAR;
-        final int maxLengthVarIntSize = computeUInt32SizeNoTag(maxLength);
-        final int minLengthVarIntSize = computeUInt32SizeNoTag(value.length());
-        if (minLengthVarIntSize == maxLengthVarIntSize) {
-          position = oldPosition + minLengthVarIntSize;
-          int newPosition = Utf8.encode(value, buffer, position, spaceLeft());
-          // Since this class is stateful and tracks the position, we rewind and store the state,
-          // prepend the length, then reset it back to the end of the string.
-          position = oldPosition;
-          int length = newPosition - oldPosition - minLengthVarIntSize;
-          writeUInt32NoTag(length);
-          position = newPosition;
-        } else {
-          int length = Utf8.encodedLength(value);
-          writeUInt32NoTag(length);
-          position = Utf8.encode(value, buffer, position, spaceLeft());
-        }
-      } catch (UnpairedSurrogateException e) {
-        // Roll back the change - we fall back to inefficient path.
-        position = oldPosition;
-
-        // TODO(nathanmittler): We should throw an IOException here instead.
-        inefficientWriteStringNoTag(value, e);
-      } catch (IndexOutOfBoundsException e) {
-        throw new OutOfSpaceException(e);
-      }
-    }
-
-    @Override
-    public void flush() {
-      // Do nothing.
-    }
-
-    @Override
-    public final int spaceLeft() {
-      return limit - position;
-    }
-
-    @Override
-    public final int getTotalBytesWritten() {
-      return position - offset;
-    }
-  }
-
-  /**
-   * A {@link CodedOutputStream} that writes directly to a heap {@link ByteBuffer}. Writes are done
-   * directly to the underlying array. The buffer position is only updated after a flush.
-   */
-  private static final class HeapNioEncoder extends ArrayEncoder {
-    private final ByteBuffer byteBuffer;
-    private int initialPosition;
-
-    HeapNioEncoder(ByteBuffer byteBuffer) {
-      super(
-          byteBuffer.array(),
-          byteBuffer.arrayOffset() + byteBuffer.position(),
-          byteBuffer.remaining());
-      this.byteBuffer = byteBuffer;
-      this.initialPosition = byteBuffer.position();
-    }
-
-    @Override
-    public void flush() {
-      // Update the position on the buffer.
-      byteBuffer.position(initialPosition + getTotalBytesWritten());
-    }
-  }
-
-  /**
-   * A {@link CodedOutputStream} that writes directly to a direct {@link ByteBuffer}, using only
-   * safe operations..
-   */
-  private static final class SafeDirectNioEncoder extends CodedOutputStream {
-    private final ByteBuffer originalBuffer;
-    private final ByteBuffer buffer;
-    private final int initialPosition;
-
-    SafeDirectNioEncoder(ByteBuffer buffer) {
-      this.originalBuffer = buffer;
-      this.buffer = buffer.duplicate().order(ByteOrder.LITTLE_ENDIAN);
-      initialPosition = buffer.position();
-    }
-
-    @Override
-    public void writeTag(final int fieldNumber, final int wireType) throws IOException {
-      writeUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType));
-    }
-
-    @Override
-    public void writeInt32(final int fieldNumber, final int value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      writeInt32NoTag(value);
-    }
-
-    @Override
-    public void writeUInt32(final int fieldNumber, final int value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      writeUInt32NoTag(value);
-    }
-
-    @Override
-    public void writeFixed32(final int fieldNumber, final int value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
-      writeFixed32NoTag(value);
-    }
-
-    @Override
-    public void writeUInt64(final int fieldNumber, final long value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      writeUInt64NoTag(value);
-    }
-
-    @Override
-    public void writeFixed64(final int fieldNumber, final long value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
-      writeFixed64NoTag(value);
-    }
-
-    @Override
-    public void writeBool(final int fieldNumber, final boolean value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      write((byte) (value ? 1 : 0));
-    }
-
-    @Override
-    public void writeString(final int fieldNumber, final String value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeStringNoTag(value);
-    }
-
-    @Override
-    public void writeBytes(final int fieldNumber, final ByteString value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeBytesNoTag(value);
-    }
-
-    @Override
-    public void writeByteArray(final int fieldNumber, final byte[] value) throws IOException {
-      writeByteArray(fieldNumber, value, 0, value.length);
-    }
-
-    @Override
-    public void writeByteArray(
-        final int fieldNumber, final byte[] value, final int offset, final int length)
-        throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeByteArrayNoTag(value, offset, length);
-    }
-
-    @Override
-    public void writeByteBuffer(final int fieldNumber, final ByteBuffer value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeUInt32NoTag(value.capacity());
-      writeRawBytes(value);
-    }
-
-    @Override
-    public void writeMessage(final int fieldNumber, final MessageLite value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeMessageNoTag(value);
-    }
-
-    @Override
-    void writeMessage(final int fieldNumber, final MessageLite value, Schema schema)
-        throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeMessageNoTag(value, schema);
-    }
-
-    @Override
-    public void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
-        throws IOException {
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
-      writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
-      writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
-    }
-
-    @Override
-    public void writeRawMessageSetExtension(final int fieldNumber, final ByteString value)
-        throws IOException {
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
-      writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
-      writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
-    }
-
-    @Override
-    public void writeMessageNoTag(final MessageLite value) throws IOException {
-      writeUInt32NoTag(value.getSerializedSize());
-      value.writeTo(this);
-    }
-
-    @Override
-    void writeMessageNoTag(final MessageLite value, Schema schema) throws IOException {
-      writeUInt32NoTag(((AbstractMessageLite) value).getSerializedSize(schema));
-      schema.writeTo(value, wrapper);
-    }
-
-    @Override
-    public void write(byte value) throws IOException {
-      try {
-        buffer.put(value);
-      } catch (BufferOverflowException e) {
-        throw new OutOfSpaceException(e);
-      }
-    }
-
-    @Override
-    public void writeBytesNoTag(final ByteString value) throws IOException {
-      writeUInt32NoTag(value.size());
-      value.writeTo(this);
-    }
-
-    @Override
-    public void writeByteArrayNoTag(final byte[] value, int offset, int length) throws IOException {
-      writeUInt32NoTag(length);
-      write(value, offset, length);
-    }
-
-    @Override
-    public void writeRawBytes(final ByteBuffer value) throws IOException {
-      if (value.hasArray()) {
-        write(value.array(), value.arrayOffset(), value.capacity());
-      } else {
-        ByteBuffer duplicated = value.duplicate();
-        duplicated.clear();
-        write(duplicated);
-      }
-    }
-
-    @Override
-    public void writeInt32NoTag(int value) throws IOException {
-      if (value >= 0) {
-        writeUInt32NoTag(value);
-      } else {
-        // Must sign-extend.
-        writeUInt64NoTag(value);
-      }
-    }
-
-    @Override
-    public void writeUInt32NoTag(int value) throws IOException {
-      try {
-        while (true) {
-          if ((value & ~0x7F) == 0) {
-            buffer.put((byte) value);
-            return;
-          } else {
-            buffer.put((byte) ((value & 0x7F) | 0x80));
-            value >>>= 7;
-          }
-        }
-      } catch (BufferOverflowException e) {
-        throw new OutOfSpaceException(e);
-      }
-    }
-
-    @Override
-    public void writeFixed32NoTag(int value) throws IOException {
-      try {
-        buffer.putInt(value);
-      } catch (BufferOverflowException e) {
-        throw new OutOfSpaceException(e);
-      }
-    }
-
-    @Override
-    public void writeUInt64NoTag(long value) throws IOException {
-      try {
-        while (true) {
-          if ((value & ~0x7FL) == 0) {
-            buffer.put((byte) value);
-            return;
-          } else {
-            buffer.put((byte) (((int) value & 0x7F) | 0x80));
-            value >>>= 7;
-          }
-        }
-      } catch (BufferOverflowException e) {
-        throw new OutOfSpaceException(e);
-      }
-    }
-
-    @Override
-    public void writeFixed64NoTag(long value) throws IOException {
-      try {
-        buffer.putLong(value);
-      } catch (BufferOverflowException e) {
-        throw new OutOfSpaceException(e);
-      }
-    }
-
-    @Override
-    public void write(byte[] value, int offset, int length) throws IOException {
-      try {
-        buffer.put(value, offset, length);
-      } catch (IndexOutOfBoundsException e) {
-        throw new OutOfSpaceException(e);
-      } catch (BufferOverflowException e) {
-        throw new OutOfSpaceException(e);
-      }
-    }
-
-    @Override
-    public void writeLazy(byte[] value, int offset, int length) throws IOException {
-      write(value, offset, length);
-    }
-
-    @Override
-    public void write(ByteBuffer value) throws IOException {
-      try {
-        buffer.put(value);
-      } catch (BufferOverflowException e) {
-        throw new OutOfSpaceException(e);
-      }
-    }
-
-    @Override
-    public void writeLazy(ByteBuffer value) throws IOException {
-      write(value);
-    }
-
-    @Override
-    public void writeStringNoTag(String value) throws IOException {
-      final int startPos = buffer.position();
-      try {
-        // UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
-        // and at most 3 times of it. We take advantage of this in both branches below.
-        final int maxEncodedSize = value.length() * Utf8.MAX_BYTES_PER_CHAR;
-        final int maxLengthVarIntSize = computeUInt32SizeNoTag(maxEncodedSize);
-        final int minLengthVarIntSize = computeUInt32SizeNoTag(value.length());
-        if (minLengthVarIntSize == maxLengthVarIntSize) {
-          // Save the current position and increment past the length field. We'll come back
-          // and write the length field after the encoding is complete.
-          final int startOfBytes = buffer.position() + minLengthVarIntSize;
-          buffer.position(startOfBytes);
-
-          // Encode the string.
-          encode(value);
-
-          // Now go back to the beginning and write the length.
-          int endOfBytes = buffer.position();
-          buffer.position(startPos);
-          writeUInt32NoTag(endOfBytes - startOfBytes);
-
-          // Reposition the buffer past the written data.
-          buffer.position(endOfBytes);
-        } else {
-          final int length = Utf8.encodedLength(value);
-          writeUInt32NoTag(length);
-          encode(value);
-        }
-      } catch (UnpairedSurrogateException e) {
-        // Roll back the change and convert to an IOException.
-        buffer.position(startPos);
-
-        // TODO(nathanmittler): We should throw an IOException here instead.
-        inefficientWriteStringNoTag(value, e);
-      } catch (IllegalArgumentException e) {
-        // Thrown by buffer.position() if out of range.
-        throw new OutOfSpaceException(e);
-      }
-    }
-
-    @Override
-    public void flush() {
-      // Update the position of the original buffer.
-      originalBuffer.position(buffer.position());
-    }
-
-    @Override
-    public int spaceLeft() {
-      return buffer.remaining();
-    }
-
-    @Override
-    public int getTotalBytesWritten() {
-      return buffer.position() - initialPosition;
-    }
-
-    private void encode(String value) throws IOException {
-      try {
-        Utf8.encodeUtf8(value, buffer);
-      } catch (IndexOutOfBoundsException e) {
-        throw new OutOfSpaceException(e);
-      }
-    }
-  }
-
-  /**
-   * A {@link CodedOutputStream} that writes directly to a direct {@link ByteBuffer} using {@code
-   * sun.misc.Unsafe}.
-   */
-  private static final class UnsafeDirectNioEncoder extends CodedOutputStream {
-    private final ByteBuffer originalBuffer;
-    private final ByteBuffer buffer;
-    private final long address;
-    private final long initialPosition;
-    private final long limit;
-    private final long oneVarintLimit;
-    private long position;
-
-    UnsafeDirectNioEncoder(ByteBuffer buffer) {
-      this.originalBuffer = buffer;
-      this.buffer = buffer.duplicate().order(ByteOrder.LITTLE_ENDIAN);
-      address = UnsafeUtil.addressOffset(buffer);
-      initialPosition = address + buffer.position();
-      limit = address + buffer.limit();
-      oneVarintLimit = limit - MAX_VARINT_SIZE;
-      position = initialPosition;
-    }
-
-    static boolean isSupported() {
-      return UnsafeUtil.hasUnsafeByteBufferOperations();
-    }
-
-    @Override
-    public void writeTag(int fieldNumber, int wireType) throws IOException {
-      writeUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType));
-    }
-
-    @Override
-    public void writeInt32(int fieldNumber, int value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      writeInt32NoTag(value);
-    }
-
-    @Override
-    public void writeUInt32(int fieldNumber, int value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      writeUInt32NoTag(value);
-    }
-
-    @Override
-    public void writeFixed32(int fieldNumber, int value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
-      writeFixed32NoTag(value);
-    }
-
-    @Override
-    public void writeUInt64(int fieldNumber, long value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      writeUInt64NoTag(value);
-    }
-
-    @Override
-    public void writeFixed64(int fieldNumber, long value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
-      writeFixed64NoTag(value);
-    }
-
-    @Override
-    public void writeBool(int fieldNumber, boolean value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      write((byte) (value ? 1 : 0));
-    }
-
-    @Override
-    public void writeString(int fieldNumber, String value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeStringNoTag(value);
-    }
-
-    @Override
-    public void writeBytes(int fieldNumber, ByteString value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeBytesNoTag(value);
-    }
-
-    @Override
-    public void writeByteArray(int fieldNumber, byte[] value) throws IOException {
-      writeByteArray(fieldNumber, value, 0, value.length);
-    }
-
-    @Override
-    public void writeByteArray(int fieldNumber, byte[] value, int offset, int length)
-        throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeByteArrayNoTag(value, offset, length);
-    }
-
-    @Override
-    public void writeByteBuffer(int fieldNumber, ByteBuffer value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeUInt32NoTag(value.capacity());
-      writeRawBytes(value);
-    }
-
-    @Override
-    public void writeMessage(int fieldNumber, MessageLite value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeMessageNoTag(value);
-    }
-
-    @Override
-    void writeMessage(int fieldNumber, MessageLite value, Schema schema) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeMessageNoTag(value, schema);
-    }
-
-    @Override
-    public void writeMessageSetExtension(int fieldNumber, MessageLite value) throws IOException {
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
-      writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
-      writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
-    }
-
-    @Override
-    public void writeRawMessageSetExtension(int fieldNumber, ByteString value) throws IOException {
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
-      writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
-      writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
-    }
-
-    @Override
-    public void writeMessageNoTag(MessageLite value) throws IOException {
-      writeUInt32NoTag(value.getSerializedSize());
-      value.writeTo(this);
-    }
-
-    @Override
-    void writeMessageNoTag(MessageLite value, Schema schema) throws IOException {
-      writeUInt32NoTag(((AbstractMessageLite) value).getSerializedSize(schema));
-      schema.writeTo(value, wrapper);
-    }
-
-    @Override
-    public void write(byte value) throws IOException {
-      if (position >= limit) {
-        throw new OutOfSpaceException(
-            String.format("Pos: %d, limit: %d, len: %d", position, limit, 1));
-      }
-      UnsafeUtil.putByte(position++, value);
-    }
-
-    @Override
-    public void writeBytesNoTag(ByteString value) throws IOException {
-      writeUInt32NoTag(value.size());
-      value.writeTo(this);
-    }
-
-    @Override
-    public void writeByteArrayNoTag(byte[] value, int offset, int length) throws IOException {
-      writeUInt32NoTag(length);
-      write(value, offset, length);
-    }
-
-    @Override
-    public void writeRawBytes(ByteBuffer value) throws IOException {
-      if (value.hasArray()) {
-        write(value.array(), value.arrayOffset(), value.capacity());
-      } else {
-        ByteBuffer duplicated = value.duplicate();
-        duplicated.clear();
-        write(duplicated);
-      }
-    }
-
-    @Override
-    public void writeInt32NoTag(int value) throws IOException {
-      if (value >= 0) {
-        writeUInt32NoTag(value);
-      } else {
-        // Must sign-extend.
-        writeUInt64NoTag(value);
-      }
-    }
-
-    @Override
-    public void writeUInt32NoTag(int value) throws IOException {
-      if (position <= oneVarintLimit) {
-        // Optimization to avoid bounds checks on each iteration.
-        while (true) {
-          if ((value & ~0x7F) == 0) {
-            UnsafeUtil.putByte(position++, (byte) value);
-            return;
-          } else {
-            UnsafeUtil.putByte(position++, (byte) ((value & 0x7F) | 0x80));
-            value >>>= 7;
-          }
-        }
-      } else {
-        while (position < limit) {
-          if ((value & ~0x7F) == 0) {
-            UnsafeUtil.putByte(position++, (byte) value);
-            return;
-          } else {
-            UnsafeUtil.putByte(position++, (byte) ((value & 0x7F) | 0x80));
-            value >>>= 7;
-          }
-        }
-        throw new OutOfSpaceException(
-            String.format("Pos: %d, limit: %d, len: %d", position, limit, 1));
-      }
-    }
-
-    @Override
-    public void writeFixed32NoTag(int value) throws IOException {
-      buffer.putInt(bufferPos(position), value);
-      position += FIXED32_SIZE;
-    }
-
-    @Override
-    public void writeUInt64NoTag(long value) throws IOException {
-      if (position <= oneVarintLimit) {
-        // Optimization to avoid bounds checks on each iteration.
-        while (true) {
-          if ((value & ~0x7FL) == 0) {
-            UnsafeUtil.putByte(position++, (byte) value);
-            return;
-          } else {
-            UnsafeUtil.putByte(position++, (byte) (((int) value & 0x7F) | 0x80));
-            value >>>= 7;
-          }
-        }
-      } else {
-        while (position < limit) {
-          if ((value & ~0x7FL) == 0) {
-            UnsafeUtil.putByte(position++, (byte) value);
-            return;
-          } else {
-            UnsafeUtil.putByte(position++, (byte) (((int) value & 0x7F) | 0x80));
-            value >>>= 7;
-          }
-        }
-        throw new OutOfSpaceException(
-            String.format("Pos: %d, limit: %d, len: %d", position, limit, 1));
-      }
-    }
-
-    @Override
-    public void writeFixed64NoTag(long value) throws IOException {
-      buffer.putLong(bufferPos(position), value);
-      position += FIXED64_SIZE;
-    }
-
-    @Override
-    public void write(byte[] value, int offset, int length) throws IOException {
-      if (value == null
-          || offset < 0
-          || length < 0
-          || (value.length - length) < offset
-          || (limit - length) < position) {
-        if (value == null) {
-          throw new NullPointerException("value");
-        }
-        throw new OutOfSpaceException(
-            String.format("Pos: %d, limit: %d, len: %d", position, limit, length));
-      }
-
-      UnsafeUtil.copyMemory(value, offset, position, length);
-      position += length;
-    }
-
-    @Override
-    public void writeLazy(byte[] value, int offset, int length) throws IOException {
-      write(value, offset, length);
-    }
-
-    @Override
-    public void write(ByteBuffer value) throws IOException {
-      try {
-        int length = value.remaining();
-        repositionBuffer(position);
-        buffer.put(value);
-        position += length;
-      } catch (BufferOverflowException e) {
-        throw new OutOfSpaceException(e);
-      }
-    }
-
-    @Override
-    public void writeLazy(ByteBuffer value) throws IOException {
-      write(value);
-    }
-
-    @Override
-    public void writeStringNoTag(String value) throws IOException {
-      long prevPos = position;
-      try {
-        // UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
-        // and at most 3 times of it. We take advantage of this in both branches below.
-        int maxEncodedSize = value.length() * Utf8.MAX_BYTES_PER_CHAR;
-        int maxLengthVarIntSize = computeUInt32SizeNoTag(maxEncodedSize);
-        int minLengthVarIntSize = computeUInt32SizeNoTag(value.length());
-        if (minLengthVarIntSize == maxLengthVarIntSize) {
-          // Save the current position and increment past the length field. We'll come back
-          // and write the length field after the encoding is complete.
-          int stringStart = bufferPos(position) + minLengthVarIntSize;
-          buffer.position(stringStart);
-
-          // Encode the string.
-          Utf8.encodeUtf8(value, buffer);
-
-          // Write the length and advance the position.
-          int length = buffer.position() - stringStart;
-          writeUInt32NoTag(length);
-          position += length;
-        } else {
-          // Calculate and write the encoded length.
-          int length = Utf8.encodedLength(value);
-          writeUInt32NoTag(length);
-
-          // Write the string and advance the position.
-          repositionBuffer(position);
-          Utf8.encodeUtf8(value, buffer);
-          position += length;
-        }
-      } catch (UnpairedSurrogateException e) {
-        // Roll back the change and convert to an IOException.
-        position = prevPos;
-        repositionBuffer(position);
-
-        // TODO(nathanmittler): We should throw an IOException here instead.
-        inefficientWriteStringNoTag(value, e);
-      } catch (IllegalArgumentException e) {
-        // Thrown by buffer.position() if out of range.
-        throw new OutOfSpaceException(e);
-      } catch (IndexOutOfBoundsException e) {
-        throw new OutOfSpaceException(e);
-      }
-    }
-
-    @Override
-    public void flush() {
-      // Update the position of the original buffer.
-      originalBuffer.position(bufferPos(position));
-    }
-
-    @Override
-    public int spaceLeft() {
-      return (int) (limit - position);
-    }
-
-    @Override
-    public int getTotalBytesWritten() {
-      return (int) (position - initialPosition);
-    }
-
-    private void repositionBuffer(long pos) {
-      buffer.position(bufferPos(pos));
-    }
-
-    private int bufferPos(long pos) {
-      return (int) (pos - address);
-    }
-  }
-
-  /** Abstract base class for buffered encoders. */
-  private abstract static class AbstractBufferedEncoder extends CodedOutputStream {
-    final byte[] buffer;
-    final int limit;
-    int position;
-    int totalBytesWritten;
-
-    AbstractBufferedEncoder(int bufferSize) {
-      if (bufferSize < 0) {
-        throw new IllegalArgumentException("bufferSize must be >= 0");
-      }
-      // As an optimization, we require that the buffer be able to store at least 2
-      // varints so that we can buffer any integer write (tag + value). This reduces the
-      // number of range checks for a single write to 1 (i.e. if there is not enough space
-      // to buffer the tag+value, flush and then buffer it).
-      this.buffer = new byte[max(bufferSize, MAX_VARINT_SIZE * 2)];
-      this.limit = buffer.length;
-    }
-
-    @Override
-    public final int spaceLeft() {
-      throw new UnsupportedOperationException(
-          "spaceLeft() can only be called on CodedOutputStreams that are "
-              + "writing to a flat array or ByteBuffer.");
-    }
-
-    @Override
-    public final int getTotalBytesWritten() {
-      return totalBytesWritten;
-    }
-
-    /**
-     * This method does not perform bounds checking on the array. Checking array bounds is the
-     * responsibility of the caller.
-     */
-    final void buffer(byte value) {
-      buffer[position++] = value;
-      totalBytesWritten++;
-    }
-
-    /**
-     * This method does not perform bounds checking on the array. Checking array bounds is the
-     * responsibility of the caller.
-     */
-    final void bufferTag(final int fieldNumber, final int wireType) {
-      bufferUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType));
-    }
-
-    /**
-     * This method does not perform bounds checking on the array. Checking array bounds is the
-     * responsibility of the caller.
-     */
-    final void bufferInt32NoTag(final int value) {
-      if (value >= 0) {
-        bufferUInt32NoTag(value);
-      } else {
-        // Must sign-extend.
-        bufferUInt64NoTag(value);
-      }
-    }
-
-    /**
-     * This method does not perform bounds checking on the array. Checking array bounds is the
-     * responsibility of the caller.
-     */
-    final void bufferUInt32NoTag(int value) {
-      if (HAS_UNSAFE_ARRAY_OPERATIONS) {
-        final long originalPos = position;
-        while (true) {
-          if ((value & ~0x7F) == 0) {
-            UnsafeUtil.putByte(buffer, position++, (byte) value);
-            break;
-          } else {
-            UnsafeUtil.putByte(buffer, position++, (byte) ((value & 0x7F) | 0x80));
-            value >>>= 7;
-          }
-        }
-        int delta = (int) (position - originalPos);
-        totalBytesWritten += delta;
-      } else {
-        while (true) {
-          if ((value & ~0x7F) == 0) {
-            buffer[position++] = (byte) value;
-            totalBytesWritten++;
-            return;
-          } else {
-            buffer[position++] = (byte) ((value & 0x7F) | 0x80);
-            totalBytesWritten++;
-            value >>>= 7;
-          }
-        }
-      }
-    }
-
-    /**
-     * This method does not perform bounds checking on the array. Checking array bounds is the
-     * responsibility of the caller.
-     */
-    final void bufferUInt64NoTag(long value) {
-      if (HAS_UNSAFE_ARRAY_OPERATIONS) {
-        final long originalPos = position;
-        while (true) {
-          if ((value & ~0x7FL) == 0) {
-            UnsafeUtil.putByte(buffer, position++, (byte) value);
-            break;
-          } else {
-            UnsafeUtil.putByte(buffer, position++, (byte) (((int) value & 0x7F) | 0x80));
-            value >>>= 7;
-          }
-        }
-        int delta = (int) (position - originalPos);
-        totalBytesWritten += delta;
-      } else {
-        while (true) {
-          if ((value & ~0x7FL) == 0) {
-            buffer[position++] = (byte) value;
-            totalBytesWritten++;
-            return;
-          } else {
-            buffer[position++] = (byte) (((int) value & 0x7F) | 0x80);
-            totalBytesWritten++;
-            value >>>= 7;
-          }
-        }
-      }
-    }
-
-    /**
-     * This method does not perform bounds checking on the array. Checking array bounds is the
-     * responsibility of the caller.
-     */
-    final void bufferFixed32NoTag(int value) {
-      buffer[position++] = (byte) (value & 0xFF);
-      buffer[position++] = (byte) ((value >> 8) & 0xFF);
-      buffer[position++] = (byte) ((value >> 16) & 0xFF);
-      buffer[position++] = (byte) ((value >> 24) & 0xFF);
-      totalBytesWritten += FIXED32_SIZE;
-    }
-
-    /**
-     * This method does not perform bounds checking on the array. Checking array bounds is the
-     * responsibility of the caller.
-     */
-    final void bufferFixed64NoTag(long value) {
-      buffer[position++] = (byte) (value & 0xFF);
-      buffer[position++] = (byte) ((value >> 8) & 0xFF);
-      buffer[position++] = (byte) ((value >> 16) & 0xFF);
-      buffer[position++] = (byte) ((value >> 24) & 0xFF);
-      buffer[position++] = (byte) ((int) (value >> 32) & 0xFF);
-      buffer[position++] = (byte) ((int) (value >> 40) & 0xFF);
-      buffer[position++] = (byte) ((int) (value >> 48) & 0xFF);
-      buffer[position++] = (byte) ((int) (value >> 56) & 0xFF);
-      totalBytesWritten += FIXED64_SIZE;
-    }
-  }
-
-  /**
-   * A {@link CodedOutputStream} that decorates a {@link ByteOutput}. It internal buffer only to
-   * support string encoding operations. All other writes are just passed through to the {@link
-   * ByteOutput}.
-   */
-  private static final class ByteOutputEncoder extends AbstractBufferedEncoder {
-    private final ByteOutput out;
-
-    ByteOutputEncoder(ByteOutput out, int bufferSize) {
-      super(bufferSize);
-      if (out == null) {
-        throw new NullPointerException("out");
-      }
-      this.out = out;
-    }
-
-    @Override
-    public void writeTag(final int fieldNumber, final int wireType) throws IOException {
-      writeUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType));
-    }
-
-    @Override
-    public void writeInt32(final int fieldNumber, final int value) throws IOException {
-      flushIfNotAvailable(MAX_VARINT_SIZE * 2);
-      bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      bufferInt32NoTag(value);
-    }
-
-    @Override
-    public void writeUInt32(final int fieldNumber, final int value) throws IOException {
-      flushIfNotAvailable(MAX_VARINT_SIZE * 2);
-      bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      bufferUInt32NoTag(value);
-    }
-
-    @Override
-    public void writeFixed32(final int fieldNumber, final int value) throws IOException {
-      flushIfNotAvailable(MAX_VARINT_SIZE + FIXED32_SIZE);
-      bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
-      bufferFixed32NoTag(value);
-    }
-
-    @Override
-    public void writeUInt64(final int fieldNumber, final long value) throws IOException {
-      flushIfNotAvailable(MAX_VARINT_SIZE * 2);
-      bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      bufferUInt64NoTag(value);
-    }
-
-    @Override
-    public void writeFixed64(final int fieldNumber, final long value) throws IOException {
-      flushIfNotAvailable(MAX_VARINT_SIZE + FIXED64_SIZE);
-      bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
-      bufferFixed64NoTag(value);
-    }
-
-    @Override
-    public void writeBool(final int fieldNumber, final boolean value) throws IOException {
-      flushIfNotAvailable(MAX_VARINT_SIZE + 1);
-      bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      buffer((byte) (value ? 1 : 0));
-    }
-
-    @Override
-    public void writeString(final int fieldNumber, final String value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeStringNoTag(value);
-    }
-
-    @Override
-    public void writeBytes(final int fieldNumber, final ByteString value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeBytesNoTag(value);
-    }
-
-    @Override
-    public void writeByteArray(final int fieldNumber, final byte[] value) throws IOException {
-      writeByteArray(fieldNumber, value, 0, value.length);
-    }
-
-    @Override
-    public void writeByteArray(
-        final int fieldNumber, final byte[] value, final int offset, final int length)
-        throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeByteArrayNoTag(value, offset, length);
-    }
-
-    @Override
-    public void writeByteBuffer(final int fieldNumber, final ByteBuffer value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeUInt32NoTag(value.capacity());
-      writeRawBytes(value);
-    }
-
-    @Override
-    public void writeBytesNoTag(final ByteString value) throws IOException {
-      writeUInt32NoTag(value.size());
-      value.writeTo(this);
-    }
-
-    @Override
-    public void writeByteArrayNoTag(final byte[] value, int offset, int length) throws IOException {
-      writeUInt32NoTag(length);
-      write(value, offset, length);
-    }
-
-    @Override
-    public void writeRawBytes(final ByteBuffer value) throws IOException {
-      if (value.hasArray()) {
-        write(value.array(), value.arrayOffset(), value.capacity());
-      } else {
-        ByteBuffer duplicated = value.duplicate();
-        duplicated.clear();
-        write(duplicated);
-      }
-    }
-
-    @Override
-    public void writeMessage(final int fieldNumber, final MessageLite value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeMessageNoTag(value);
-    }
-
-    @Override
-    void writeMessage(final int fieldNumber, final MessageLite value, Schema schema)
-        throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeMessageNoTag(value, schema);
-    }
-
-    @Override
-    public void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
-        throws IOException {
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
-      writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
-      writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
-    }
-
-    @Override
-    public void writeRawMessageSetExtension(final int fieldNumber, final ByteString value)
-        throws IOException {
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
-      writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
-      writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
-    }
-
-    @Override
-    public void writeMessageNoTag(final MessageLite value) throws IOException {
-      writeUInt32NoTag(value.getSerializedSize());
-      value.writeTo(this);
-    }
-
-    @Override
-    void writeMessageNoTag(final MessageLite value, Schema schema) throws IOException {
-      writeUInt32NoTag(((AbstractMessageLite) value).getSerializedSize(schema));
-      schema.writeTo(value, wrapper);
-    }
-
-    @Override
-    public void write(byte value) throws IOException {
-      if (position == limit) {
-        doFlush();
-      }
-
-      buffer(value);
-    }
-
-    @Override
-    public void writeInt32NoTag(int value) throws IOException {
-      if (value >= 0) {
-        writeUInt32NoTag(value);
-      } else {
-        // Must sign-extend.
-        writeUInt64NoTag(value);
-      }
-    }
-
-    @Override
-    public void writeUInt32NoTag(int value) throws IOException {
-      flushIfNotAvailable(MAX_VARINT32_SIZE);
-      bufferUInt32NoTag(value);
-    }
-
-    @Override
-    public void writeFixed32NoTag(final int value) throws IOException {
-      flushIfNotAvailable(FIXED32_SIZE);
-      bufferFixed32NoTag(value);
-    }
-
-    @Override
-    public void writeUInt64NoTag(long value) throws IOException {
-      flushIfNotAvailable(MAX_VARINT_SIZE);
-      bufferUInt64NoTag(value);
-    }
-
-    @Override
-    public void writeFixed64NoTag(final long value) throws IOException {
-      flushIfNotAvailable(FIXED64_SIZE);
-      bufferFixed64NoTag(value);
-    }
-
-    @Override
-    public void writeStringNoTag(String value) throws IOException {
-      // UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
-      // and at most 3 times of it. We take advantage of this in both branches below.
-      final int maxLength = value.length() * Utf8.MAX_BYTES_PER_CHAR;
-      final int maxLengthVarIntSize = computeUInt32SizeNoTag(maxLength);
-
-      // If we are streaming and the potential length is too big to fit in our buffer, we take the
-      // slower path.
-      if (maxLengthVarIntSize + maxLength > limit) {
-        // Allocate a byte[] that we know can fit the string and encode into it. String.getBytes()
-        // does the same internally and then does *another copy* to return a byte[] of exactly the
-        // right size. We can skip that copy and just writeRawBytes up to the actualLength of the
-        // UTF-8 encoded bytes.
-        final byte[] encodedBytes = new byte[maxLength];
-        int actualLength = Utf8.encode(value, encodedBytes, 0, maxLength);
-        writeUInt32NoTag(actualLength);
-        writeLazy(encodedBytes, 0, actualLength);
-        return;
-      }
-
-      // Fast path: we have enough space available in our buffer for the string...
-      if (maxLengthVarIntSize + maxLength > limit - position) {
-        // Flush to free up space.
-        doFlush();
-      }
-
-      final int oldPosition = position;
-      try {
-        // Optimize for the case where we know this length results in a constant varint length as
-        // this saves a pass for measuring the length of the string.
-        final int minLengthVarIntSize = computeUInt32SizeNoTag(value.length());
-
-        if (minLengthVarIntSize == maxLengthVarIntSize) {
-          position = oldPosition + minLengthVarIntSize;
-          int newPosition = Utf8.encode(value, buffer, position, limit - position);
-          // Since this class is stateful and tracks the position, we rewind and store the state,
-          // prepend the length, then reset it back to the end of the string.
-          position = oldPosition;
-          int length = newPosition - oldPosition - minLengthVarIntSize;
-          bufferUInt32NoTag(length);
-          position = newPosition;
-          totalBytesWritten += length;
-        } else {
-          int length = Utf8.encodedLength(value);
-          bufferUInt32NoTag(length);
-          position = Utf8.encode(value, buffer, position, length);
-          totalBytesWritten += length;
-        }
-      } catch (UnpairedSurrogateException e) {
-        // Roll back the change and convert to an IOException.
-        totalBytesWritten -= position - oldPosition;
-        position = oldPosition;
-
-        // TODO(nathanmittler): We should throw an IOException here instead.
-        inefficientWriteStringNoTag(value, e);
-      } catch (IndexOutOfBoundsException e) {
-        throw new OutOfSpaceException(e);
-      }
-    }
-
-    @Override
-    public void flush() throws IOException {
-      if (position > 0) {
-        // Flush the buffer.
-        doFlush();
-      }
-    }
-
-    @Override
-    public void write(byte[] value, int offset, int length) throws IOException {
-      flush();
-      out.write(value, offset, length);
-      totalBytesWritten += length;
-    }
-
-    @Override
-    public void writeLazy(byte[] value, int offset, int length) throws IOException {
-      flush();
-      out.writeLazy(value, offset, length);
-      totalBytesWritten += length;
-    }
-
-    @Override
-    public void write(ByteBuffer value) throws IOException {
-      flush();
-      int length = value.remaining();
-      out.write(value);
-      totalBytesWritten += length;
-    }
-
-    @Override
-    public void writeLazy(ByteBuffer value) throws IOException {
-      flush();
-      int length = value.remaining();
-      out.writeLazy(value);
-      totalBytesWritten += length;
-    }
-
-    private void flushIfNotAvailable(int requiredSize) throws IOException {
-      if (limit - position < requiredSize) {
-        doFlush();
-      }
-    }
-
-    private void doFlush() throws IOException {
-      out.write(buffer, 0, position);
-      position = 0;
-    }
-  }
-
-  /**
-   * An {@link CodedOutputStream} that decorates an {@link OutputStream}. It performs internal
-   * buffering to optimize writes to the {@link OutputStream}.
-   */
-  private static final class OutputStreamEncoder extends AbstractBufferedEncoder {
-    private final OutputStream out;
-
-    OutputStreamEncoder(OutputStream out, int bufferSize) {
-      super(bufferSize);
-      if (out == null) {
-        throw new NullPointerException("out");
-      }
-      this.out = out;
-    }
-
-    @Override
-    public void writeTag(final int fieldNumber, final int wireType) throws IOException {
-      writeUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType));
-    }
-
-    @Override
-    public void writeInt32(final int fieldNumber, final int value) throws IOException {
-      flushIfNotAvailable(MAX_VARINT_SIZE * 2);
-      bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      bufferInt32NoTag(value);
-    }
-
-    @Override
-    public void writeUInt32(final int fieldNumber, final int value) throws IOException {
-      flushIfNotAvailable(MAX_VARINT_SIZE * 2);
-      bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      bufferUInt32NoTag(value);
-    }
-
-    @Override
-    public void writeFixed32(final int fieldNumber, final int value) throws IOException {
-      flushIfNotAvailable(MAX_VARINT_SIZE + FIXED32_SIZE);
-      bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
-      bufferFixed32NoTag(value);
-    }
-
-    @Override
-    public void writeUInt64(final int fieldNumber, final long value) throws IOException {
-      flushIfNotAvailable(MAX_VARINT_SIZE * 2);
-      bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      bufferUInt64NoTag(value);
-    }
-
-    @Override
-    public void writeFixed64(final int fieldNumber, final long value) throws IOException {
-      flushIfNotAvailable(MAX_VARINT_SIZE + FIXED64_SIZE);
-      bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
-      bufferFixed64NoTag(value);
-    }
-
-    @Override
-    public void writeBool(final int fieldNumber, final boolean value) throws IOException {
-      flushIfNotAvailable(MAX_VARINT_SIZE + 1);
-      bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
-      buffer((byte) (value ? 1 : 0));
-    }
-
-    @Override
-    public void writeString(final int fieldNumber, final String value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeStringNoTag(value);
-    }
-
-    @Override
-    public void writeBytes(final int fieldNumber, final ByteString value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeBytesNoTag(value);
-    }
-
-    @Override
-    public void writeByteArray(final int fieldNumber, final byte[] value) throws IOException {
-      writeByteArray(fieldNumber, value, 0, value.length);
-    }
-
-    @Override
-    public void writeByteArray(
-        final int fieldNumber, final byte[] value, final int offset, final int length)
-        throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeByteArrayNoTag(value, offset, length);
-    }
-
-    @Override
-    public void writeByteBuffer(final int fieldNumber, final ByteBuffer value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeUInt32NoTag(value.capacity());
-      writeRawBytes(value);
-    }
-
-    @Override
-    public void writeBytesNoTag(final ByteString value) throws IOException {
-      writeUInt32NoTag(value.size());
-      value.writeTo(this);
-    }
-
-    @Override
-    public void writeByteArrayNoTag(final byte[] value, int offset, int length) throws IOException {
-      writeUInt32NoTag(length);
-      write(value, offset, length);
-    }
-
-    @Override
-    public void writeRawBytes(final ByteBuffer value) throws IOException {
-      if (value.hasArray()) {
-        write(value.array(), value.arrayOffset(), value.capacity());
-      } else {
-        ByteBuffer duplicated = value.duplicate();
-        duplicated.clear();
-        write(duplicated);
-      }
-    }
-
-    @Override
-    public void writeMessage(final int fieldNumber, final MessageLite value) throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeMessageNoTag(value);
-    }
-
-    @Override
-    void writeMessage(final int fieldNumber, final MessageLite value, Schema schema)
-        throws IOException {
-      writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      writeMessageNoTag(value, schema);
-    }
-
-    @Override
-    public void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
-        throws IOException {
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
-      writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
-      writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
-    }
-
-    @Override
-    public void writeRawMessageSetExtension(final int fieldNumber, final ByteString value)
-        throws IOException {
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
-      writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
-      writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
-      writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
-    }
-
-    @Override
-    public void writeMessageNoTag(final MessageLite value) throws IOException {
-      writeUInt32NoTag(value.getSerializedSize());
-      value.writeTo(this);
-    }
-
-    @Override
-    void writeMessageNoTag(final MessageLite value, Schema schema) throws IOException {
-      writeUInt32NoTag(((AbstractMessageLite) value).getSerializedSize(schema));
-      schema.writeTo(value, wrapper);
-    }
-
-    @Override
-    public void write(byte value) throws IOException {
-      if (position == limit) {
-        doFlush();
-      }
-
-      buffer(value);
-    }
-
-    @Override
-    public void writeInt32NoTag(int value) throws IOException {
-      if (value >= 0) {
-        writeUInt32NoTag(value);
-      } else {
-        // Must sign-extend.
-        writeUInt64NoTag(value);
-      }
-    }
-
-    @Override
-    public void writeUInt32NoTag(int value) throws IOException {
-      flushIfNotAvailable(MAX_VARINT32_SIZE);
-      bufferUInt32NoTag(value);
-    }
-
-    @Override
-    public void writeFixed32NoTag(final int value) throws IOException {
-      flushIfNotAvailable(FIXED32_SIZE);
-      bufferFixed32NoTag(value);
-    }
-
-    @Override
-    public void writeUInt64NoTag(long value) throws IOException {
-      flushIfNotAvailable(MAX_VARINT_SIZE);
-      bufferUInt64NoTag(value);
-    }
-
-    @Override
-    public void writeFixed64NoTag(final long value) throws IOException {
-      flushIfNotAvailable(FIXED64_SIZE);
-      bufferFixed64NoTag(value);
-    }
-
-    @Override
-    public void writeStringNoTag(String value) throws IOException {
-      try {
-        // UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
-        // and at most 3 times of it. We take advantage of this in both branches below.
-        final int maxLength = value.length() * Utf8.MAX_BYTES_PER_CHAR;
-        final int maxLengthVarIntSize = computeUInt32SizeNoTag(maxLength);
-
-        // If we are streaming and the potential length is too big to fit in our buffer, we take the
-        // slower path.
-        if (maxLengthVarIntSize + maxLength > limit) {
-          // Allocate a byte[] that we know can fit the string and encode into it. String.getBytes()
-          // does the same internally and then does *another copy* to return a byte[] of exactly the
-          // right size. We can skip that copy and just writeRawBytes up to the actualLength of the
-          // UTF-8 encoded bytes.
-          final byte[] encodedBytes = new byte[maxLength];
-          int actualLength = Utf8.encode(value, encodedBytes, 0, maxLength);
-          writeUInt32NoTag(actualLength);
-          writeLazy(encodedBytes, 0, actualLength);
-          return;
-        }
-
-        // Fast path: we have enough space available in our buffer for the string...
-        if (maxLengthVarIntSize + maxLength > limit - position) {
-          // Flush to free up space.
-          doFlush();
-        }
-
-        // Optimize for the case where we know this length results in a constant varint length as
-        // this saves a pass for measuring the length of the string.
-        final int minLengthVarIntSize = computeUInt32SizeNoTag(value.length());
-        int oldPosition = position;
-        final int length;
-        try {
-          if (minLengthVarIntSize == maxLengthVarIntSize) {
-            position = oldPosition + minLengthVarIntSize;
-            int newPosition = Utf8.encode(value, buffer, position, limit - position);
-            // Since this class is stateful and tracks the position, we rewind and store the
-            // state, prepend the length, then reset it back to the end of the string.
-            position = oldPosition;
-            length = newPosition - oldPosition - minLengthVarIntSize;
-            bufferUInt32NoTag(length);
-            position = newPosition;
-          } else {
-            length = Utf8.encodedLength(value);
-            bufferUInt32NoTag(length);
-            position = Utf8.encode(value, buffer, position, length);
-          }
-          totalBytesWritten += length;
-        } catch (UnpairedSurrogateException e) {
-          // Be extra careful and restore the original position for retrying the write with the
-          // less efficient path.
-          totalBytesWritten -= position - oldPosition;
-          position = oldPosition;
-          throw e;
-        } catch (ArrayIndexOutOfBoundsException e) {
-          throw new OutOfSpaceException(e);
-        }
-      } catch (UnpairedSurrogateException e) {
-        inefficientWriteStringNoTag(value, e);
-      }
-    }
-
-    @Override
-    public void flush() throws IOException {
-      if (position > 0) {
-        // Flush the buffer.
-        doFlush();
-      }
-    }
-
-    @Override
-    public void write(byte[] value, int offset, int length) throws IOException {
-      if (limit - position >= length) {
-        // We have room in the current buffer.
-        System.arraycopy(value, offset, buffer, position, length);
-        position += length;
-        totalBytesWritten += length;
-      } else {
-        // Write extends past current buffer.  Fill the rest of this buffer and
-        // flush.
-        final int bytesWritten = limit - position;
-        System.arraycopy(value, offset, buffer, position, bytesWritten);
-        offset += bytesWritten;
-        length -= bytesWritten;
-        position = limit;
-        totalBytesWritten += bytesWritten;
-        doFlush();
-
-        // Now deal with the rest.
-        // Since we have an output stream, this is our buffer
-        // and buffer offset == 0
-        if (length <= limit) {
-          // Fits in new buffer.
-          System.arraycopy(value, offset, buffer, 0, length);
-          position = length;
-        } else {
-          // Write is very big.  Let's do it all at once.
-          out.write(value, offset, length);
-        }
-        totalBytesWritten += length;
-      }
-    }
-
-    @Override
-    public void writeLazy(byte[] value, int offset, int length) throws IOException {
-      write(value, offset, length);
-    }
-
-    @Override
-    public void write(ByteBuffer value) throws IOException {
-      int length = value.remaining();
-      if (limit - position >= length) {
-        // We have room in the current buffer.
-        value.get(buffer, position, length);
-        position += length;
-        totalBytesWritten += length;
-      } else {
-        // Write extends past current buffer.  Fill the rest of this buffer and
-        // flush.
-        final int bytesWritten = limit - position;
-        value.get(buffer, position, bytesWritten);
-        length -= bytesWritten;
-        position = limit;
-        totalBytesWritten += bytesWritten;
-        doFlush();
-
-        // Now deal with the rest.
-        // Since we have an output stream, this is our buffer
-        // and buffer offset == 0
-        while (length > limit) {
-          // Copy data into the buffer before writing it to OutputStream.
-          value.get(buffer, 0, limit);
-          out.write(buffer, 0, limit);
-          length -= limit;
-          totalBytesWritten += limit;
-        }
-        value.get(buffer, 0, length);
-        position = length;
-        totalBytesWritten += length;
-      }
-    }
-
-    @Override
-    public void writeLazy(ByteBuffer value) throws IOException {
-      write(value);
-    }
-
-    private void flushIfNotAvailable(int requiredSize) throws IOException {
-      if (limit - position < requiredSize) {
-        doFlush();
-      }
-    }
-
-    private void doFlush() throws IOException {
-      out.write(buffer, 0, position);
-      position = 0;
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/CodedOutputStreamWriter.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/CodedOutputStreamWriter.java
deleted file mode 100644
index 0d1983c..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/CodedOutputStreamWriter.java
+++ /dev/null
@@ -1,691 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.Internal.checkNotNull;
-import static com.google.protobuf.WireFormat.WIRETYPE_LENGTH_DELIMITED;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-/** An adapter between the {@link Writer} interface and {@link CodedOutputStream}. */
-@ExperimentalApi
-final class CodedOutputStreamWriter implements Writer {
-  private final CodedOutputStream output;
-
-  public static CodedOutputStreamWriter forCodedOutput(CodedOutputStream output) {
-    if (output.wrapper != null) {
-      return output.wrapper;
-    }
-    return new CodedOutputStreamWriter(output);
-  }
-
-  private CodedOutputStreamWriter(CodedOutputStream output) {
-    this.output = checkNotNull(output, "output");
-    this.output.wrapper = this;
-  }
-
-  @Override
-  public FieldOrder fieldOrder() {
-    return FieldOrder.ASCENDING;
-  }
-
-  public int getTotalBytesWritten() {
-    return output.getTotalBytesWritten();
-  }
-
-  @Override
-  public void writeSFixed32(int fieldNumber, int value) throws IOException {
-    output.writeSFixed32(fieldNumber, value);
-  }
-
-  @Override
-  public void writeInt64(int fieldNumber, long value) throws IOException {
-    output.writeInt64(fieldNumber, value);
-  }
-
-  @Override
-  public void writeSFixed64(int fieldNumber, long value) throws IOException {
-    output.writeSFixed64(fieldNumber, value);
-  }
-
-  @Override
-  public void writeFloat(int fieldNumber, float value) throws IOException {
-    output.writeFloat(fieldNumber, value);
-  }
-
-  @Override
-  public void writeDouble(int fieldNumber, double value) throws IOException {
-    output.writeDouble(fieldNumber, value);
-  }
-
-  @Override
-  public void writeEnum(int fieldNumber, int value) throws IOException {
-    output.writeEnum(fieldNumber, value);
-  }
-
-  @Override
-  public void writeUInt64(int fieldNumber, long value) throws IOException {
-    output.writeUInt64(fieldNumber, value);
-  }
-
-  @Override
-  public void writeInt32(int fieldNumber, int value) throws IOException {
-    output.writeInt32(fieldNumber, value);
-  }
-
-  @Override
-  public void writeFixed64(int fieldNumber, long value) throws IOException {
-    output.writeFixed64(fieldNumber, value);
-  }
-
-  @Override
-  public void writeFixed32(int fieldNumber, int value) throws IOException {
-    output.writeFixed32(fieldNumber, value);
-  }
-
-  @Override
-  public void writeBool(int fieldNumber, boolean value) throws IOException {
-    output.writeBool(fieldNumber, value);
-  }
-
-  @Override
-  public void writeString(int fieldNumber, String value) throws IOException {
-    output.writeString(fieldNumber, value);
-  }
-
-  @Override
-  public void writeBytes(int fieldNumber, ByteString value) throws IOException {
-    output.writeBytes(fieldNumber, value);
-  }
-
-  @Override
-  public void writeUInt32(int fieldNumber, int value) throws IOException {
-    output.writeUInt32(fieldNumber, value);
-  }
-
-  @Override
-  public void writeSInt32(int fieldNumber, int value) throws IOException {
-    output.writeSInt32(fieldNumber, value);
-  }
-
-  @Override
-  public void writeSInt64(int fieldNumber, long value) throws IOException {
-    output.writeSInt64(fieldNumber, value);
-  }
-
-  @Override
-  public void writeMessage(int fieldNumber, Object value) throws IOException {
-    output.writeMessage(fieldNumber, (MessageLite) value);
-  }
-
-  @Override
-  public void writeMessage(int fieldNumber, Object value, Schema schema) throws IOException {
-    output.writeMessage(fieldNumber, (MessageLite) value, schema);
-  }
-
-  @Override
-  public void writeGroup(int fieldNumber, Object value) throws IOException {
-    output.writeGroup(fieldNumber, (MessageLite) value);
-  }
-
-  @Override
-  public void writeGroup(int fieldNumber, Object value, Schema schema) throws IOException {
-    output.writeGroup(fieldNumber, (MessageLite) value, schema);
-  }
-
-  @Override
-  public void writeStartGroup(int fieldNumber) throws IOException {
-    output.writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP);
-  }
-
-  @Override
-  public void writeEndGroup(int fieldNumber) throws IOException {
-    output.writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
-  }
-
-  @Override
-  public final void writeMessageSetItem(int fieldNumber, Object value) throws IOException {
-    if (value instanceof ByteString) {
-      output.writeRawMessageSetExtension(fieldNumber, (ByteString) value);
-    } else {
-      output.writeMessageSetExtension(fieldNumber, (MessageLite) value);
-    }
-  }
-
-  @Override
-  public void writeInt32List(int fieldNumber, List<Integer> value, boolean packed)
-      throws IOException {
-    if (packed) {
-      output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-
-      // Compute and write the length of the data.
-      int dataSize = 0;
-      for (int i = 0; i < value.size(); ++i) {
-        dataSize += CodedOutputStream.computeInt32SizeNoTag(value.get(i));
-      }
-      output.writeUInt32NoTag(dataSize);
-
-      // Write the data itself, without any tags.
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeInt32NoTag(value.get(i));
-      }
-    } else {
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeInt32(fieldNumber, value.get(i));
-      }
-    }
-  }
-
-  @Override
-  public void writeFixed32List(int fieldNumber, List<Integer> value, boolean packed)
-      throws IOException {
-    if (packed) {
-      output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-
-      // Compute and write the length of the data.
-      int dataSize = 0;
-      for (int i = 0; i < value.size(); ++i) {
-        dataSize += CodedOutputStream.computeFixed32SizeNoTag(value.get(i));
-      }
-      output.writeUInt32NoTag(dataSize);
-
-      // Write the data itself, without any tags.
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeFixed32NoTag(value.get(i));
-      }
-    } else {
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeFixed32(fieldNumber, value.get(i));
-      }
-    }
-  }
-
-  @Override
-  public void writeInt64List(int fieldNumber, List<Long> value, boolean packed) throws IOException {
-    if (packed) {
-      output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-
-      // Compute and write the length of the data.
-      int dataSize = 0;
-      for (int i = 0; i < value.size(); ++i) {
-        dataSize += CodedOutputStream.computeInt64SizeNoTag(value.get(i));
-      }
-      output.writeUInt32NoTag(dataSize);
-
-      // Write the data itself, without any tags.
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeInt64NoTag(value.get(i));
-      }
-    } else {
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeInt64(fieldNumber, value.get(i));
-      }
-    }
-  }
-
-  @Override
-  public void writeUInt64List(int fieldNumber, List<Long> value, boolean packed)
-      throws IOException {
-    if (packed) {
-      output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-
-      // Compute and write the length of the data.
-      int dataSize = 0;
-      for (int i = 0; i < value.size(); ++i) {
-        dataSize += CodedOutputStream.computeUInt64SizeNoTag(value.get(i));
-      }
-      output.writeUInt32NoTag(dataSize);
-
-      // Write the data itself, without any tags.
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeUInt64NoTag(value.get(i));
-      }
-    } else {
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeUInt64(fieldNumber, value.get(i));
-      }
-    }
-  }
-
-  @Override
-  public void writeFixed64List(int fieldNumber, List<Long> value, boolean packed)
-      throws IOException {
-    if (packed) {
-      output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-
-      // Compute and write the length of the data.
-      int dataSize = 0;
-      for (int i = 0; i < value.size(); ++i) {
-        dataSize += CodedOutputStream.computeFixed64SizeNoTag(value.get(i));
-      }
-      output.writeUInt32NoTag(dataSize);
-
-      // Write the data itself, without any tags.
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeFixed64NoTag(value.get(i));
-      }
-    } else {
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeFixed64(fieldNumber, value.get(i));
-      }
-    }
-  }
-
-  @Override
-  public void writeFloatList(int fieldNumber, List<Float> value, boolean packed)
-      throws IOException {
-    if (packed) {
-      output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-
-      // Compute and write the length of the data.
-      int dataSize = 0;
-      for (int i = 0; i < value.size(); ++i) {
-        dataSize += CodedOutputStream.computeFloatSizeNoTag(value.get(i));
-      }
-      output.writeUInt32NoTag(dataSize);
-
-      // Write the data itself, without any tags.
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeFloatNoTag(value.get(i));
-      }
-    } else {
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeFloat(fieldNumber, value.get(i));
-      }
-    }
-  }
-
-  @Override
-  public void writeDoubleList(int fieldNumber, List<Double> value, boolean packed)
-      throws IOException {
-    if (packed) {
-      output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-
-      // Compute and write the length of the data.
-      int dataSize = 0;
-      for (int i = 0; i < value.size(); ++i) {
-        dataSize += CodedOutputStream.computeDoubleSizeNoTag(value.get(i));
-      }
-      output.writeUInt32NoTag(dataSize);
-
-      // Write the data itself, without any tags.
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeDoubleNoTag(value.get(i));
-      }
-    } else {
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeDouble(fieldNumber, value.get(i));
-      }
-    }
-  }
-
-  @Override
-  public void writeEnumList(int fieldNumber, List<Integer> value, boolean packed)
-      throws IOException {
-    if (packed) {
-      output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-
-      // Compute and write the length of the data.
-      int dataSize = 0;
-      for (int i = 0; i < value.size(); ++i) {
-        dataSize += CodedOutputStream.computeEnumSizeNoTag(value.get(i));
-      }
-      output.writeUInt32NoTag(dataSize);
-
-      // Write the data itself, without any tags.
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeEnumNoTag(value.get(i));
-      }
-    } else {
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeEnum(fieldNumber, value.get(i));
-      }
-    }
-  }
-
-  @Override
-  public void writeBoolList(int fieldNumber, List<Boolean> value, boolean packed)
-      throws IOException {
-    if (packed) {
-      output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-
-      // Compute and write the length of the data.
-      int dataSize = 0;
-      for (int i = 0; i < value.size(); ++i) {
-        dataSize += CodedOutputStream.computeBoolSizeNoTag(value.get(i));
-      }
-      output.writeUInt32NoTag(dataSize);
-
-      // Write the data itself, without any tags.
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeBoolNoTag(value.get(i));
-      }
-    } else {
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeBool(fieldNumber, value.get(i));
-      }
-    }
-  }
-
-  @Override
-  public void writeStringList(int fieldNumber, List<String> value) throws IOException {
-    if (value instanceof LazyStringList) {
-      final LazyStringList lazyList = (LazyStringList) value;
-      for (int i = 0; i < value.size(); ++i) {
-        writeLazyString(fieldNumber, lazyList.getRaw(i));
-      }
-    } else {
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeString(fieldNumber, value.get(i));
-      }
-    }
-  }
-
-  private void writeLazyString(int fieldNumber, Object value) throws IOException {
-    if (value instanceof String) {
-      output.writeString(fieldNumber, (String) value);
-    } else {
-      output.writeBytes(fieldNumber, (ByteString) value);
-    }
-  }
-
-  @Override
-  public void writeBytesList(int fieldNumber, List<ByteString> value) throws IOException {
-    for (int i = 0; i < value.size(); ++i) {
-      output.writeBytes(fieldNumber, value.get(i));
-    }
-  }
-
-  @Override
-  public void writeUInt32List(int fieldNumber, List<Integer> value, boolean packed)
-      throws IOException {
-    if (packed) {
-      output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-
-      // Compute and write the length of the data.
-      int dataSize = 0;
-      for (int i = 0; i < value.size(); ++i) {
-        dataSize += CodedOutputStream.computeUInt32SizeNoTag(value.get(i));
-      }
-      output.writeUInt32NoTag(dataSize);
-
-      // Write the data itself, without any tags.
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeUInt32NoTag(value.get(i));
-      }
-    } else {
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeUInt32(fieldNumber, value.get(i));
-      }
-    }
-  }
-
-  @Override
-  public void writeSFixed32List(int fieldNumber, List<Integer> value, boolean packed)
-      throws IOException {
-    if (packed) {
-      output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-
-      // Compute and write the length of the data.
-      int dataSize = 0;
-      for (int i = 0; i < value.size(); ++i) {
-        dataSize += CodedOutputStream.computeSFixed32SizeNoTag(value.get(i));
-      }
-      output.writeUInt32NoTag(dataSize);
-
-      // Write the data itself, without any tags.
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeSFixed32NoTag(value.get(i));
-      }
-    } else {
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeSFixed32(fieldNumber, value.get(i));
-      }
-    }
-  }
-
-  @Override
-  public void writeSFixed64List(int fieldNumber, List<Long> value, boolean packed)
-      throws IOException {
-    if (packed) {
-      output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-
-      // Compute and write the length of the data.
-      int dataSize = 0;
-      for (int i = 0; i < value.size(); ++i) {
-        dataSize += CodedOutputStream.computeSFixed64SizeNoTag(value.get(i));
-      }
-      output.writeUInt32NoTag(dataSize);
-
-      // Write the data itself, without any tags.
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeSFixed64NoTag(value.get(i));
-      }
-    } else {
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeSFixed64(fieldNumber, value.get(i));
-      }
-    }
-  }
-
-  @Override
-  public void writeSInt32List(int fieldNumber, List<Integer> value, boolean packed)
-      throws IOException {
-    if (packed) {
-      output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-
-      // Compute and write the length of the data.
-      int dataSize = 0;
-      for (int i = 0; i < value.size(); ++i) {
-        dataSize += CodedOutputStream.computeSInt32SizeNoTag(value.get(i));
-      }
-      output.writeUInt32NoTag(dataSize);
-
-      // Write the data itself, without any tags.
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeSInt32NoTag(value.get(i));
-      }
-    } else {
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeSInt32(fieldNumber, value.get(i));
-      }
-    }
-  }
-
-  @Override
-  public void writeSInt64List(int fieldNumber, List<Long> value, boolean packed)
-      throws IOException {
-    if (packed) {
-      output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-
-      // Compute and write the length of the data.
-      int dataSize = 0;
-      for (int i = 0; i < value.size(); ++i) {
-        dataSize += CodedOutputStream.computeSInt64SizeNoTag(value.get(i));
-      }
-      output.writeUInt32NoTag(dataSize);
-
-      // Write the data itself, without any tags.
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeSInt64NoTag(value.get(i));
-      }
-    } else {
-      for (int i = 0; i < value.size(); ++i) {
-        output.writeSInt64(fieldNumber, value.get(i));
-      }
-    }
-  }
-
-  @Override
-  public void writeMessageList(int fieldNumber, List<?> value) throws IOException {
-    for (int i = 0; i < value.size(); ++i) {
-      writeMessage(fieldNumber, value.get(i));
-    }
-  }
-
-  @Override
-  public void writeMessageList(int fieldNumber, List<?> value, Schema schema) throws IOException {
-    for (int i = 0; i < value.size(); ++i) {
-      writeMessage(fieldNumber, value.get(i), schema);
-    }
-  }
-
-  @Override
-  public void writeGroupList(int fieldNumber, List<?> value) throws IOException {
-    for (int i = 0; i < value.size(); ++i) {
-      writeGroup(fieldNumber, value.get(i));
-    }
-  }
-
-  @Override
-  public void writeGroupList(int fieldNumber, List<?> value, Schema schema) throws IOException {
-    for (int i = 0; i < value.size(); ++i) {
-      writeGroup(fieldNumber, value.get(i), schema);
-    }
-  }
-
-  @Override
-  public <K, V> void writeMap(int fieldNumber, MapEntryLite.Metadata<K, V> metadata, Map<K, V> map)
-      throws IOException {
-    if (output.isSerializationDeterministic()) {
-      writeDeterministicMap(fieldNumber, metadata, map);
-      return;
-    }
-    for (Map.Entry<K, V> entry : map.entrySet()) {
-      output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-      output.writeUInt32NoTag(
-          MapEntryLite.computeSerializedSize(metadata, entry.getKey(), entry.getValue()));
-      MapEntryLite.writeTo(output, metadata, entry.getKey(), entry.getValue());
-    }
-  }
-
-  @SuppressWarnings("unchecked")
-  private <K, V> void writeDeterministicMap(
-      int fieldNumber, MapEntryLite.Metadata<K, V> metadata, Map<K, V> map) throws IOException {
-    switch (metadata.keyType) {
-      case BOOL:
-        V value;
-        if ((value = map.get(Boolean.FALSE)) != null) {
-          writeDeterministicBooleanMapEntry(
-              fieldNumber, /* key= */ false, value, (MapEntryLite.Metadata<Boolean, V>) metadata);
-        }
-        if ((value = map.get(Boolean.TRUE)) != null) {
-          writeDeterministicBooleanMapEntry(
-              fieldNumber, /* key= */ true, value, (MapEntryLite.Metadata<Boolean, V>) metadata);
-        }
-        break;
-      case FIXED32:
-      case INT32:
-      case SFIXED32:
-      case SINT32:
-      case UINT32:
-        writeDeterministicIntegerMap(
-            fieldNumber, (MapEntryLite.Metadata<Integer, V>) metadata, (Map<Integer, V>) map);
-        break;
-      case FIXED64:
-      case INT64:
-      case SFIXED64:
-      case SINT64:
-      case UINT64:
-        writeDeterministicLongMap(
-            fieldNumber, (MapEntryLite.Metadata<Long, V>) metadata, (Map<Long, V>) map);
-        break;
-      case STRING:
-        writeDeterministicStringMap(
-            fieldNumber, (MapEntryLite.Metadata<String, V>) metadata, (Map<String, V>) map);
-        break;
-      default:
-        throw new IllegalArgumentException("does not support key type: " + metadata.keyType);
-    }
-  }
-
-  private <V> void writeDeterministicBooleanMapEntry(
-      int fieldNumber, boolean key, V value, MapEntryLite.Metadata<Boolean, V> metadata)
-      throws IOException {
-    output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-    output.writeUInt32NoTag(MapEntryLite.computeSerializedSize(metadata, key, value));
-    MapEntryLite.writeTo(output, metadata, key, value);
-  }
-
-  private <V> void writeDeterministicIntegerMap(
-      int fieldNumber, MapEntryLite.Metadata<Integer, V> metadata, Map<Integer, V> map)
-      throws IOException {
-    int[] keys = new int[map.size()];
-    int index = 0;
-    for (int k : map.keySet()) {
-      keys[index++] = k;
-    }
-    Arrays.sort(keys);
-    for (int key : keys) {
-      V value = map.get(key);
-      output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-      output.writeUInt32NoTag(MapEntryLite.computeSerializedSize(metadata, key, value));
-      MapEntryLite.writeTo(output, metadata, key, value);
-    }
-  }
-
-  private <V> void writeDeterministicLongMap(
-      int fieldNumber, MapEntryLite.Metadata<Long, V> metadata, Map<Long, V> map)
-      throws IOException {
-    long[] keys = new long[map.size()];
-    int index = 0;
-    for (long k : map.keySet()) {
-      keys[index++] = k;
-    }
-    Arrays.sort(keys);
-    for (long key : keys) {
-      V value = map.get(key);
-      output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-      output.writeUInt32NoTag(MapEntryLite.computeSerializedSize(metadata, key, value));
-      MapEntryLite.writeTo(output, metadata, key, value);
-    }
-  }
-
-  private <V> void writeDeterministicStringMap(
-      int fieldNumber, MapEntryLite.Metadata<String, V> metadata, Map<String, V> map)
-      throws IOException {
-    String[] keys = new String[map.size()];
-    int index = 0;
-    for (String k : map.keySet()) {
-      keys[index++] = k;
-    }
-    Arrays.sort(keys);
-    for (String key : keys) {
-      V value = map.get(key);
-      output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
-      output.writeUInt32NoTag(MapEntryLite.computeSerializedSize(metadata, key, value));
-      MapEntryLite.writeTo(output, metadata, key, value);
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/DoubleArrayList.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/DoubleArrayList.java
deleted file mode 100644
index 4085653..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/DoubleArrayList.java
+++ /dev/null
@@ -1,298 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.Internal.checkNotNull;
-
-import com.google.protobuf.Internal.DoubleList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.RandomAccess;
-
-/**
- * An implementation of {@link DoubleList} on top of a primitive array.
- *
- * @author dweis@google.com (Daniel Weis)
- */
-final class DoubleArrayList extends AbstractProtobufList<Double>
-    implements DoubleList, RandomAccess, PrimitiveNonBoxingCollection {
-
-  private static final DoubleArrayList EMPTY_LIST = new DoubleArrayList(new double[0], 0);
-  static {
-    EMPTY_LIST.makeImmutable();
-  }
-
-  public static DoubleArrayList emptyList() {
-    return EMPTY_LIST;
-  }
-
-  /** The backing store for the list. */
-  private double[] array;
-
-  /**
-   * The size of the list distinct from the length of the array. That is, it is the number of
-   * elements set in the list.
-   */
-  private int size;
-
-  /** Constructs a new mutable {@code DoubleArrayList} with default capacity. */
-  DoubleArrayList() {
-    this(new double[DEFAULT_CAPACITY], 0);
-  }
-
-  /**
-   * Constructs a new mutable {@code DoubleArrayList} containing the same elements as {@code other}.
-   */
-  private DoubleArrayList(double[] other, int size) {
-    array = other;
-    this.size = size;
-  }
-
-  @Override
-  protected void removeRange(int fromIndex, int toIndex) {
-    ensureIsMutable();
-    if (toIndex < fromIndex) {
-      throw new IndexOutOfBoundsException("toIndex < fromIndex");
-    }
-
-    System.arraycopy(array, toIndex, array, fromIndex, size - toIndex);
-    size -= (toIndex - fromIndex);
-    modCount++;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (!(o instanceof DoubleArrayList)) {
-      return super.equals(o);
-    }
-    DoubleArrayList other = (DoubleArrayList) o;
-    if (size != other.size) {
-      return false;
-    }
-
-    final double[] arr = other.array;
-    for (int i = 0; i < size; i++) {
-      if (Double.doubleToLongBits(array[i]) != Double.doubleToLongBits(arr[i])) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = 1;
-    for (int i = 0; i < size; i++) {
-      long bits = Double.doubleToLongBits(array[i]);
-      result = (31 * result) + Internal.hashLong(bits);
-    }
-    return result;
-  }
-
-  @Override
-  public DoubleList mutableCopyWithCapacity(int capacity) {
-    if (capacity < size) {
-      throw new IllegalArgumentException();
-    }
-    return new DoubleArrayList(Arrays.copyOf(array, capacity), size);
-  }
-
-  @Override
-  public Double get(int index) {
-    return getDouble(index);
-  }
-
-  @Override
-  public double getDouble(int index) {
-    ensureIndexInRange(index);
-    return array[index];
-  }
-
-  @Override
-  public int indexOf(Object element) {
-    if (!(element instanceof Double)) {
-      return -1;
-    }
-    double unboxedElement = (Double) element;
-    int numElems = size();
-    for (int i = 0; i < numElems; i++) {
-      if (array[i] == unboxedElement) {
-        return i;
-      }
-    }
-    return -1;
-  }
-
-  @Override
-  public boolean contains(Object element) {
-    return indexOf(element) != -1;
-  }
-
-  @Override
-  public int size() {
-    return size;
-  }
-
-  @Override
-  public Double set(int index, Double element) {
-    return setDouble(index, element);
-  }
-
-  @Override
-  public double setDouble(int index, double element) {
-    ensureIsMutable();
-    ensureIndexInRange(index);
-    double previousValue = array[index];
-    array[index] = element;
-    return previousValue;
-  }
-
-  @Override
-  public boolean add(Double element) {
-    addDouble(element);
-    return true;
-  }
-
-  @Override
-  public void add(int index, Double element) {
-    addDouble(index, element);
-  }
-
-  /** Like {@link #add(Double)} but more efficient in that it doesn't box the element. */
-  @Override
-  public void addDouble(double element) {
-    ensureIsMutable();
-    if (size == array.length) {
-      // Resize to 1.5x the size
-      int length = ((size * 3) / 2) + 1;
-      double[] newArray = new double[length];
-
-      System.arraycopy(array, 0, newArray, 0, size);
-      array = newArray;
-    }
-
-    array[size++] = element;
-  }
-
-  /** Like {@link #add(int, Double)} but more efficient in that it doesn't box the element. */
-  private void addDouble(int index, double element) {
-    ensureIsMutable();
-    if (index < 0 || index > size) {
-      throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index));
-    }
-
-    if (size < array.length) {
-      // Shift everything over to make room
-      System.arraycopy(array, index, array, index + 1, size - index);
-    } else {
-      // Resize to 1.5x the size
-      int length = ((size * 3) / 2) + 1;
-      double[] newArray = new double[length];
-
-      // Copy the first part directly
-      System.arraycopy(array, 0, newArray, 0, index);
-
-      // Copy the rest shifted over by one to make room
-      System.arraycopy(array, index, newArray, index + 1, size - index);
-      array = newArray;
-    }
-
-    array[index] = element;
-    size++;
-    modCount++;
-  }
-
-  @Override
-  public boolean addAll(Collection<? extends Double> collection) {
-    ensureIsMutable();
-
-    checkNotNull(collection);
-
-    // We specialize when adding another DoubleArrayList to avoid boxing elements.
-    if (!(collection instanceof DoubleArrayList)) {
-      return super.addAll(collection);
-    }
-
-    DoubleArrayList list = (DoubleArrayList) collection;
-    if (list.size == 0) {
-      return false;
-    }
-
-    int overflow = Integer.MAX_VALUE - size;
-    if (overflow < list.size) {
-      // We can't actually represent a list this large.
-      throw new OutOfMemoryError();
-    }
-
-    int newSize = size + list.size;
-    if (newSize > array.length) {
-      array = Arrays.copyOf(array, newSize);
-    }
-
-    System.arraycopy(list.array, 0, array, size, list.size);
-    size = newSize;
-    modCount++;
-    return true;
-  }
-
-  @Override
-  public Double remove(int index) {
-    ensureIsMutable();
-    ensureIndexInRange(index);
-    double value = array[index];
-    if (index < size - 1) {
-      System.arraycopy(array, index + 1, array, index, size - index - 1);
-    }
-    size--;
-    modCount++;
-    return value;
-  }
-
-  /**
-   * Ensures that the provided {@code index} is within the range of {@code [0, size]}. Throws an
-   * {@link IndexOutOfBoundsException} if it is not.
-   *
-   * @param index the index to verify is in range
-   */
-  private void ensureIndexInRange(int index) {
-    if (index < 0 || index >= size) {
-      throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index));
-    }
-  }
-
-  private String makeOutOfBoundsExceptionMessage(int index) {
-    return "Index:" + index + ", Size:" + size;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/DoubleValue.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/DoubleValue.java
deleted file mode 100644
index bf64582..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/DoubleValue.java
+++ /dev/null
@@ -1,276 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/wrappers.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * Wrapper message for `double`.
- * The JSON representation for `DoubleValue` is JSON number.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.DoubleValue}
- */
-public  final class DoubleValue extends
-    com.google.protobuf.GeneratedMessageLite<
-        DoubleValue, DoubleValue.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.DoubleValue)
-    DoubleValueOrBuilder {
-  private DoubleValue() {
-  }
-  public static final int VALUE_FIELD_NUMBER = 1;
-  private double value_;
-  /**
-   * <pre>
-   * The double value.
-   * </pre>
-   *
-   * <code>double value = 1;</code>
-   * @return The value.
-   */
-  @java.lang.Override
-  public double getValue() {
-    return value_;
-  }
-  /**
-   * <pre>
-   * The double value.
-   * </pre>
-   *
-   * <code>double value = 1;</code>
-   * @param value The value to set.
-   */
-  private void setValue(double value) {
-    
-    value_ = value;
-  }
-  /**
-   * <pre>
-   * The double value.
-   * </pre>
-   *
-   * <code>double value = 1;</code>
-   */
-  private void clearValue() {
-    
-    value_ = 0D;
-  }
-
-  public static com.google.protobuf.DoubleValue parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.DoubleValue parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.DoubleValue parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.DoubleValue parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.DoubleValue parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.DoubleValue parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.DoubleValue parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.DoubleValue parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.DoubleValue parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.DoubleValue parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.DoubleValue parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.DoubleValue parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.DoubleValue prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * Wrapper message for `double`.
-   * The JSON representation for `DoubleValue` is JSON number.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.DoubleValue}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.DoubleValue, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.DoubleValue)
-      com.google.protobuf.DoubleValueOrBuilder {
-    // Construct using com.google.protobuf.DoubleValue.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * The double value.
-     * </pre>
-     *
-     * <code>double value = 1;</code>
-     * @return The value.
-     */
-    @java.lang.Override
-    public double getValue() {
-      return instance.getValue();
-    }
-    /**
-     * <pre>
-     * The double value.
-     * </pre>
-     *
-     * <code>double value = 1;</code>
-     * @param value The value to set.
-     * @return This builder for chaining.
-     */
-    public Builder setValue(double value) {
-      copyOnWrite();
-      instance.setValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The double value.
-     * </pre>
-     *
-     * <code>double value = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearValue() {
-      copyOnWrite();
-      instance.clearValue();
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.DoubleValue)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.DoubleValue();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "value_",
-          };
-          java.lang.String info =
-              "\u0000\u0001\u0000\u0000\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u0000";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.DoubleValue> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.DoubleValue.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.DoubleValue>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.DoubleValue)
-  private static final com.google.protobuf.DoubleValue DEFAULT_INSTANCE;
-  static {
-    DoubleValue defaultInstance = new DoubleValue();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      DoubleValue.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.DoubleValue getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  public static com.google.protobuf.DoubleValue of(double value) {
-    return newBuilder().setValue(value).build();
-  }
-
-  private static volatile com.google.protobuf.Parser<DoubleValue> PARSER;
-
-  public static com.google.protobuf.Parser<DoubleValue> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/DoubleValueOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/DoubleValueOrBuilder.java
deleted file mode 100644
index 21562f4..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/DoubleValueOrBuilder.java
+++ /dev/null
@@ -1,19 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/wrappers.proto
-
-package com.google.protobuf;
-
-public interface DoubleValueOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.DoubleValue)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * The double value.
-   * </pre>
-   *
-   * <code>double value = 1;</code>
-   * @return The value.
-   */
-  double getValue();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/DslList.kt b/java/kotlin-lite/target/generated-sources/com/google/protobuf/DslList.kt
deleted file mode 100644
index 54a64af..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/DslList.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.google.protobuf.kotlin
-
-/**
- * A simple wrapper around a [List] with an extra generic parameter that can be used to disambiguate
- * extension methods.
- *
- * <p>This class is used by Kotlin protocol buffer extensions, and its constructor is public only
- * because generated message code is in a different compilation unit.  Others should not use this
- * class directly in any way.
- */
-@Suppress("unused") // the unused type parameter
-class DslList<E, P : DslProxy> @OnlyForUseByGeneratedProtoCode constructor(
-  private val delegate: List<E>
-) : List<E> by delegate {
-  override fun iterator(): Iterator<E> = UnmodifiableIterator(delegate.iterator())
-
-  override fun listIterator(): ListIterator<E> = UnmodifiableListIterator(delegate.listIterator())
-
-  override fun listIterator(index: Int): ListIterator<E> =
-    UnmodifiableListIterator(delegate.listIterator(index))
-
-  override fun equals(other: Any?): Boolean = delegate == other
-
-  override fun hashCode(): Int = delegate.hashCode()
-
-  override fun toString(): String = delegate.toString()
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/DslMap.kt b/java/kotlin-lite/target/generated-sources/com/google/protobuf/DslMap.kt
deleted file mode 100644
index 9949fb4..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/DslMap.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.google.protobuf.kotlin
-
-/**
- * A simple wrapper around a [Map] with an extra generic parameter that can be used to disambiguate
- * extension methods.
- *
- * <p>This class is used by Kotlin protocol buffer extensions, and its constructor is public only
- * because generated message code is in a different compilation unit.  Others should not use this
- * class directly in any way.
- */
-@Suppress("unused") // the unused type parameter
-class DslMap<K, V, P : DslProxy> @OnlyForUseByGeneratedProtoCode constructor(
-  private val delegate: Map<K, V>
-) : Map<K, V> by delegate {
-  // We allocate the wrappers on calls to get, not with lazy {...}, because lazy allocates
-  // a few objects up front, and any kind of query operation on this object should be rare.
-
-  override val entries: Set<Map.Entry<K, V>>
-    get() = UnmodifiableMapEntries(delegate.entries)
-  override val keys: Set<K>
-    get() = UnmodifiableSet(delegate.keys)
-  override val values: Collection<V>
-    get() = UnmodifiableCollection(delegate.values)
-
-  override fun equals(other: Any?): Boolean = delegate == other
-
-  override fun hashCode(): Int = delegate.hashCode()
-
-  override fun toString(): String = delegate.toString()
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/DslProxy.kt b/java/kotlin-lite/target/generated-sources/com/google/protobuf/DslProxy.kt
deleted file mode 100644
index 7d14e95..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/DslProxy.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.google.protobuf.kotlin
-
-/**
- * A type meaningful only for its existence, never intended to be instantiated.  For example,
- * a `DslList<Int, FooProxy>` can be given different extension methods than a
- * `DslList<Int, BarProxy>`.
- */
-abstract class DslProxy @OnlyForUseByGeneratedProtoCode protected constructor() {
-  init {
-    throw UnsupportedOperationException("A DslProxy should never be instantiated")
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Duration.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Duration.java
deleted file mode 100644
index e59f2ad..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Duration.java
+++ /dev/null
@@ -1,480 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/duration.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * A Duration represents a signed, fixed-length span of time represented
- * as a count of seconds and fractions of seconds at nanosecond
- * resolution. It is independent of any calendar and concepts like "day"
- * or "month". It is related to Timestamp in that the difference between
- * two Timestamp values is a Duration and it can be added or subtracted
- * from a Timestamp. Range is approximately +-10,000 years.
- * # Examples
- * Example 1: Compute Duration from two Timestamps in pseudo code.
- *     Timestamp start = ...;
- *     Timestamp end = ...;
- *     Duration duration = ...;
- *     duration.seconds = end.seconds - start.seconds;
- *     duration.nanos = end.nanos - start.nanos;
- *     if (duration.seconds &lt; 0 &amp;&amp; duration.nanos &gt; 0) {
- *       duration.seconds += 1;
- *       duration.nanos -= 1000000000;
- *     } else if (duration.seconds &gt; 0 &amp;&amp; duration.nanos &lt; 0) {
- *       duration.seconds -= 1;
- *       duration.nanos += 1000000000;
- *     }
- * Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
- *     Timestamp start = ...;
- *     Duration duration = ...;
- *     Timestamp end = ...;
- *     end.seconds = start.seconds + duration.seconds;
- *     end.nanos = start.nanos + duration.nanos;
- *     if (end.nanos &lt; 0) {
- *       end.seconds -= 1;
- *       end.nanos += 1000000000;
- *     } else if (end.nanos &gt;= 1000000000) {
- *       end.seconds += 1;
- *       end.nanos -= 1000000000;
- *     }
- * Example 3: Compute Duration from datetime.timedelta in Python.
- *     td = datetime.timedelta(days=3, minutes=10)
- *     duration = Duration()
- *     duration.FromTimedelta(td)
- * # JSON Mapping
- * In JSON format, the Duration type is encoded as a string rather than an
- * object, where the string ends in the suffix "s" (indicating seconds) and
- * is preceded by the number of seconds, with nanoseconds expressed as
- * fractional seconds. For example, 3 seconds with 0 nanoseconds should be
- * encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should
- * be expressed in JSON format as "3.000000001s", and 3 seconds and 1
- * microsecond should be expressed in JSON format as "3.000001s".
- * </pre>
- *
- * Protobuf type {@code google.protobuf.Duration}
- */
-public  final class Duration extends
-    com.google.protobuf.GeneratedMessageLite<
-        Duration, Duration.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.Duration)
-    DurationOrBuilder {
-  private Duration() {
-  }
-  public static final int SECONDS_FIELD_NUMBER = 1;
-  private long seconds_;
-  /**
-   * <pre>
-   * Signed seconds of the span of time. Must be from -315,576,000,000
-   * to +315,576,000,000 inclusive. Note: these bounds are computed from:
-   * 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
-   * </pre>
-   *
-   * <code>int64 seconds = 1;</code>
-   * @return The seconds.
-   */
-  @java.lang.Override
-  public long getSeconds() {
-    return seconds_;
-  }
-  /**
-   * <pre>
-   * Signed seconds of the span of time. Must be from -315,576,000,000
-   * to +315,576,000,000 inclusive. Note: these bounds are computed from:
-   * 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
-   * </pre>
-   *
-   * <code>int64 seconds = 1;</code>
-   * @param value The seconds to set.
-   */
-  private void setSeconds(long value) {
-    
-    seconds_ = value;
-  }
-  /**
-   * <pre>
-   * Signed seconds of the span of time. Must be from -315,576,000,000
-   * to +315,576,000,000 inclusive. Note: these bounds are computed from:
-   * 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
-   * </pre>
-   *
-   * <code>int64 seconds = 1;</code>
-   */
-  private void clearSeconds() {
-    
-    seconds_ = 0L;
-  }
-
-  public static final int NANOS_FIELD_NUMBER = 2;
-  private int nanos_;
-  /**
-   * <pre>
-   * Signed fractions of a second at nanosecond resolution of the span
-   * of time. Durations less than one second are represented with a 0
-   * `seconds` field and a positive or negative `nanos` field. For durations
-   * of one second or more, a non-zero value for the `nanos` field must be
-   * of the same sign as the `seconds` field. Must be from -999,999,999
-   * to +999,999,999 inclusive.
-   * </pre>
-   *
-   * <code>int32 nanos = 2;</code>
-   * @return The nanos.
-   */
-  @java.lang.Override
-  public int getNanos() {
-    return nanos_;
-  }
-  /**
-   * <pre>
-   * Signed fractions of a second at nanosecond resolution of the span
-   * of time. Durations less than one second are represented with a 0
-   * `seconds` field and a positive or negative `nanos` field. For durations
-   * of one second or more, a non-zero value for the `nanos` field must be
-   * of the same sign as the `seconds` field. Must be from -999,999,999
-   * to +999,999,999 inclusive.
-   * </pre>
-   *
-   * <code>int32 nanos = 2;</code>
-   * @param value The nanos to set.
-   */
-  private void setNanos(int value) {
-    
-    nanos_ = value;
-  }
-  /**
-   * <pre>
-   * Signed fractions of a second at nanosecond resolution of the span
-   * of time. Durations less than one second are represented with a 0
-   * `seconds` field and a positive or negative `nanos` field. For durations
-   * of one second or more, a non-zero value for the `nanos` field must be
-   * of the same sign as the `seconds` field. Must be from -999,999,999
-   * to +999,999,999 inclusive.
-   * </pre>
-   *
-   * <code>int32 nanos = 2;</code>
-   */
-  private void clearNanos() {
-    
-    nanos_ = 0;
-  }
-
-  public static com.google.protobuf.Duration parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Duration parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Duration parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Duration parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Duration parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Duration parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Duration parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Duration parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Duration parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Duration parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Duration parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Duration parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.Duration prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * A Duration represents a signed, fixed-length span of time represented
-   * as a count of seconds and fractions of seconds at nanosecond
-   * resolution. It is independent of any calendar and concepts like "day"
-   * or "month". It is related to Timestamp in that the difference between
-   * two Timestamp values is a Duration and it can be added or subtracted
-   * from a Timestamp. Range is approximately +-10,000 years.
-   * # Examples
-   * Example 1: Compute Duration from two Timestamps in pseudo code.
-   *     Timestamp start = ...;
-   *     Timestamp end = ...;
-   *     Duration duration = ...;
-   *     duration.seconds = end.seconds - start.seconds;
-   *     duration.nanos = end.nanos - start.nanos;
-   *     if (duration.seconds &lt; 0 &amp;&amp; duration.nanos &gt; 0) {
-   *       duration.seconds += 1;
-   *       duration.nanos -= 1000000000;
-   *     } else if (duration.seconds &gt; 0 &amp;&amp; duration.nanos &lt; 0) {
-   *       duration.seconds -= 1;
-   *       duration.nanos += 1000000000;
-   *     }
-   * Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
-   *     Timestamp start = ...;
-   *     Duration duration = ...;
-   *     Timestamp end = ...;
-   *     end.seconds = start.seconds + duration.seconds;
-   *     end.nanos = start.nanos + duration.nanos;
-   *     if (end.nanos &lt; 0) {
-   *       end.seconds -= 1;
-   *       end.nanos += 1000000000;
-   *     } else if (end.nanos &gt;= 1000000000) {
-   *       end.seconds += 1;
-   *       end.nanos -= 1000000000;
-   *     }
-   * Example 3: Compute Duration from datetime.timedelta in Python.
-   *     td = datetime.timedelta(days=3, minutes=10)
-   *     duration = Duration()
-   *     duration.FromTimedelta(td)
-   * # JSON Mapping
-   * In JSON format, the Duration type is encoded as a string rather than an
-   * object, where the string ends in the suffix "s" (indicating seconds) and
-   * is preceded by the number of seconds, with nanoseconds expressed as
-   * fractional seconds. For example, 3 seconds with 0 nanoseconds should be
-   * encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should
-   * be expressed in JSON format as "3.000000001s", and 3 seconds and 1
-   * microsecond should be expressed in JSON format as "3.000001s".
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.Duration}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.Duration, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.Duration)
-      com.google.protobuf.DurationOrBuilder {
-    // Construct using com.google.protobuf.Duration.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * Signed seconds of the span of time. Must be from -315,576,000,000
-     * to +315,576,000,000 inclusive. Note: these bounds are computed from:
-     * 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
-     * </pre>
-     *
-     * <code>int64 seconds = 1;</code>
-     * @return The seconds.
-     */
-    @java.lang.Override
-    public long getSeconds() {
-      return instance.getSeconds();
-    }
-    /**
-     * <pre>
-     * Signed seconds of the span of time. Must be from -315,576,000,000
-     * to +315,576,000,000 inclusive. Note: these bounds are computed from:
-     * 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
-     * </pre>
-     *
-     * <code>int64 seconds = 1;</code>
-     * @param value The seconds to set.
-     * @return This builder for chaining.
-     */
-    public Builder setSeconds(long value) {
-      copyOnWrite();
-      instance.setSeconds(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Signed seconds of the span of time. Must be from -315,576,000,000
-     * to +315,576,000,000 inclusive. Note: these bounds are computed from:
-     * 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
-     * </pre>
-     *
-     * <code>int64 seconds = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearSeconds() {
-      copyOnWrite();
-      instance.clearSeconds();
-      return this;
-    }
-
-    /**
-     * <pre>
-     * Signed fractions of a second at nanosecond resolution of the span
-     * of time. Durations less than one second are represented with a 0
-     * `seconds` field and a positive or negative `nanos` field. For durations
-     * of one second or more, a non-zero value for the `nanos` field must be
-     * of the same sign as the `seconds` field. Must be from -999,999,999
-     * to +999,999,999 inclusive.
-     * </pre>
-     *
-     * <code>int32 nanos = 2;</code>
-     * @return The nanos.
-     */
-    @java.lang.Override
-    public int getNanos() {
-      return instance.getNanos();
-    }
-    /**
-     * <pre>
-     * Signed fractions of a second at nanosecond resolution of the span
-     * of time. Durations less than one second are represented with a 0
-     * `seconds` field and a positive or negative `nanos` field. For durations
-     * of one second or more, a non-zero value for the `nanos` field must be
-     * of the same sign as the `seconds` field. Must be from -999,999,999
-     * to +999,999,999 inclusive.
-     * </pre>
-     *
-     * <code>int32 nanos = 2;</code>
-     * @param value The nanos to set.
-     * @return This builder for chaining.
-     */
-    public Builder setNanos(int value) {
-      copyOnWrite();
-      instance.setNanos(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Signed fractions of a second at nanosecond resolution of the span
-     * of time. Durations less than one second are represented with a 0
-     * `seconds` field and a positive or negative `nanos` field. For durations
-     * of one second or more, a non-zero value for the `nanos` field must be
-     * of the same sign as the `seconds` field. Must be from -999,999,999
-     * to +999,999,999 inclusive.
-     * </pre>
-     *
-     * <code>int32 nanos = 2;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearNanos() {
-      copyOnWrite();
-      instance.clearNanos();
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.Duration)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.Duration();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "seconds_",
-            "nanos_",
-          };
-          java.lang.String info =
-              "\u0000\u0002\u0000\u0000\u0001\u0002\u0002\u0000\u0000\u0000\u0001\u0002\u0002\u0004" +
-              "";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.Duration> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.Duration.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.Duration>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.Duration)
-  private static final com.google.protobuf.Duration DEFAULT_INSTANCE;
-  static {
-    Duration defaultInstance = new Duration();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      Duration.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.Duration getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<Duration> PARSER;
-
-  public static com.google.protobuf.Parser<Duration> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/DurationOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/DurationOrBuilder.java
deleted file mode 100644
index 2716dcb..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/DurationOrBuilder.java
+++ /dev/null
@@ -1,36 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/duration.proto
-
-package com.google.protobuf;
-
-public interface DurationOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.Duration)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * Signed seconds of the span of time. Must be from -315,576,000,000
-   * to +315,576,000,000 inclusive. Note: these bounds are computed from:
-   * 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
-   * </pre>
-   *
-   * <code>int64 seconds = 1;</code>
-   * @return The seconds.
-   */
-  long getSeconds();
-
-  /**
-   * <pre>
-   * Signed fractions of a second at nanosecond resolution of the span
-   * of time. Durations less than one second are represented with a 0
-   * `seconds` field and a positive or negative `nanos` field. For durations
-   * of one second or more, a non-zero value for the `nanos` field must be
-   * of the same sign as the `seconds` field. Must be from -999,999,999
-   * to +999,999,999 inclusive.
-   * </pre>
-   *
-   * <code>int32 nanos = 2;</code>
-   * @return The nanos.
-   */
-  int getNanos();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/DurationProto.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/DurationProto.java
deleted file mode 100644
index dcdd86a..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/DurationProto.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/duration.proto
-
-package com.google.protobuf;
-
-public final class DurationProto {
-  private DurationProto() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Empty.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Empty.java
deleted file mode 100644
index 92f0834..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Empty.java
+++ /dev/null
@@ -1,201 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/empty.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * A generic empty message that you can re-use to avoid defining duplicated
- * empty messages in your APIs. A typical example is to use it as the request
- * or the response type of an API method. For instance:
- *     service Foo {
- *       rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
- *     }
- * The JSON representation for `Empty` is empty JSON object `{}`.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.Empty}
- */
-public  final class Empty extends
-    com.google.protobuf.GeneratedMessageLite<
-        Empty, Empty.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.Empty)
-    EmptyOrBuilder {
-  private Empty() {
-  }
-  public static com.google.protobuf.Empty parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Empty parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Empty parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Empty parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Empty parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Empty parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Empty parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Empty parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Empty parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Empty parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Empty parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Empty parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.Empty prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * A generic empty message that you can re-use to avoid defining duplicated
-   * empty messages in your APIs. A typical example is to use it as the request
-   * or the response type of an API method. For instance:
-   *     service Foo {
-   *       rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
-   *     }
-   * The JSON representation for `Empty` is empty JSON object `{}`.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.Empty}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.Empty, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.Empty)
-      com.google.protobuf.EmptyOrBuilder {
-    // Construct using com.google.protobuf.Empty.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.Empty)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.Empty();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = null;java.lang.String info =
-              "\u0000\u0000";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.Empty> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.Empty.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.Empty>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.Empty)
-  private static final com.google.protobuf.Empty DEFAULT_INSTANCE;
-  static {
-    Empty defaultInstance = new Empty();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      Empty.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.Empty getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<Empty> PARSER;
-
-  public static com.google.protobuf.Parser<Empty> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/EmptyOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/EmptyOrBuilder.java
deleted file mode 100644
index f970a06..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/EmptyOrBuilder.java
+++ /dev/null
@@ -1,9 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/empty.proto
-
-package com.google.protobuf;
-
-public interface EmptyOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.Empty)
-    com.google.protobuf.MessageLiteOrBuilder {
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/EmptyProto.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/EmptyProto.java
deleted file mode 100644
index eeed3be..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/EmptyProto.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/empty.proto
-
-package com.google.protobuf;
-
-public final class EmptyProto {
-  private EmptyProto() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Enum.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Enum.java
deleted file mode 100644
index 79df393..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Enum.java
+++ /dev/null
@@ -1,1179 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/type.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * Enum type definition.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.Enum}
- */
-public  final class Enum extends
-    com.google.protobuf.GeneratedMessageLite<
-        Enum, Enum.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.Enum)
-    EnumOrBuilder {
-  private Enum() {
-    name_ = "";
-    enumvalue_ = emptyProtobufList();
-    options_ = emptyProtobufList();
-  }
-  public static final int NAME_FIELD_NUMBER = 1;
-  private java.lang.String name_;
-  /**
-   * <pre>
-   * Enum type name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The name.
-   */
-  @java.lang.Override
-  public java.lang.String getName() {
-    return name_;
-  }
-  /**
-   * <pre>
-   * Enum type name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The bytes for name.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getNameBytes() {
-    return com.google.protobuf.ByteString.copyFromUtf8(name_);
-  }
-  /**
-   * <pre>
-   * Enum type name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @param value The name to set.
-   */
-  private void setName(
-      java.lang.String value) {
-    value.getClass();
-  
-    name_ = value;
-  }
-  /**
-   * <pre>
-   * Enum type name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   */
-  private void clearName() {
-    
-    name_ = getDefaultInstance().getName();
-  }
-  /**
-   * <pre>
-   * Enum type name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @param value The bytes for name to set.
-   */
-  private void setNameBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    name_ = value.toStringUtf8();
-    
-  }
-
-  public static final int ENUMVALUE_FIELD_NUMBER = 2;
-  private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.EnumValue> enumvalue_;
-  /**
-   * <pre>
-   * Enum value definitions.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-   */
-  @java.lang.Override
-  public java.util.List<com.google.protobuf.EnumValue> getEnumvalueList() {
-    return enumvalue_;
-  }
-  /**
-   * <pre>
-   * Enum value definitions.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-   */
-  public java.util.List<? extends com.google.protobuf.EnumValueOrBuilder> 
-      getEnumvalueOrBuilderList() {
-    return enumvalue_;
-  }
-  /**
-   * <pre>
-   * Enum value definitions.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-   */
-  @java.lang.Override
-  public int getEnumvalueCount() {
-    return enumvalue_.size();
-  }
-  /**
-   * <pre>
-   * Enum value definitions.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-   */
-  @java.lang.Override
-  public com.google.protobuf.EnumValue getEnumvalue(int index) {
-    return enumvalue_.get(index);
-  }
-  /**
-   * <pre>
-   * Enum value definitions.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-   */
-  public com.google.protobuf.EnumValueOrBuilder getEnumvalueOrBuilder(
-      int index) {
-    return enumvalue_.get(index);
-  }
-  private void ensureEnumvalueIsMutable() {
-    com.google.protobuf.Internal.ProtobufList<com.google.protobuf.EnumValue> tmp = enumvalue_;
-    if (!tmp.isModifiable()) {
-      enumvalue_ =
-          com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-     }
-  }
-
-  /**
-   * <pre>
-   * Enum value definitions.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-   */
-  private void setEnumvalue(
-      int index, com.google.protobuf.EnumValue value) {
-    value.getClass();
-  ensureEnumvalueIsMutable();
-    enumvalue_.set(index, value);
-  }
-  /**
-   * <pre>
-   * Enum value definitions.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-   */
-  private void addEnumvalue(com.google.protobuf.EnumValue value) {
-    value.getClass();
-  ensureEnumvalueIsMutable();
-    enumvalue_.add(value);
-  }
-  /**
-   * <pre>
-   * Enum value definitions.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-   */
-  private void addEnumvalue(
-      int index, com.google.protobuf.EnumValue value) {
-    value.getClass();
-  ensureEnumvalueIsMutable();
-    enumvalue_.add(index, value);
-  }
-  /**
-   * <pre>
-   * Enum value definitions.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-   */
-  private void addAllEnumvalue(
-      java.lang.Iterable<? extends com.google.protobuf.EnumValue> values) {
-    ensureEnumvalueIsMutable();
-    com.google.protobuf.AbstractMessageLite.addAll(
-        values, enumvalue_);
-  }
-  /**
-   * <pre>
-   * Enum value definitions.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-   */
-  private void clearEnumvalue() {
-    enumvalue_ = emptyProtobufList();
-  }
-  /**
-   * <pre>
-   * Enum value definitions.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-   */
-  private void removeEnumvalue(int index) {
-    ensureEnumvalueIsMutable();
-    enumvalue_.remove(index);
-  }
-
-  public static final int OPTIONS_FIELD_NUMBER = 3;
-  private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Option> options_;
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  @java.lang.Override
-  public java.util.List<com.google.protobuf.Option> getOptionsList() {
-    return options_;
-  }
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  public java.util.List<? extends com.google.protobuf.OptionOrBuilder> 
-      getOptionsOrBuilderList() {
-    return options_;
-  }
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  @java.lang.Override
-  public int getOptionsCount() {
-    return options_.size();
-  }
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  @java.lang.Override
-  public com.google.protobuf.Option getOptions(int index) {
-    return options_.get(index);
-  }
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  public com.google.protobuf.OptionOrBuilder getOptionsOrBuilder(
-      int index) {
-    return options_.get(index);
-  }
-  private void ensureOptionsIsMutable() {
-    com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Option> tmp = options_;
-    if (!tmp.isModifiable()) {
-      options_ =
-          com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-     }
-  }
-
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  private void setOptions(
-      int index, com.google.protobuf.Option value) {
-    value.getClass();
-  ensureOptionsIsMutable();
-    options_.set(index, value);
-  }
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  private void addOptions(com.google.protobuf.Option value) {
-    value.getClass();
-  ensureOptionsIsMutable();
-    options_.add(value);
-  }
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  private void addOptions(
-      int index, com.google.protobuf.Option value) {
-    value.getClass();
-  ensureOptionsIsMutable();
-    options_.add(index, value);
-  }
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  private void addAllOptions(
-      java.lang.Iterable<? extends com.google.protobuf.Option> values) {
-    ensureOptionsIsMutable();
-    com.google.protobuf.AbstractMessageLite.addAll(
-        values, options_);
-  }
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  private void clearOptions() {
-    options_ = emptyProtobufList();
-  }
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  private void removeOptions(int index) {
-    ensureOptionsIsMutable();
-    options_.remove(index);
-  }
-
-  public static final int SOURCE_CONTEXT_FIELD_NUMBER = 4;
-  private com.google.protobuf.SourceContext sourceContext_;
-  /**
-   * <pre>
-   * The source context.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 4;</code>
-   */
-  @java.lang.Override
-  public boolean hasSourceContext() {
-    return sourceContext_ != null;
-  }
-  /**
-   * <pre>
-   * The source context.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 4;</code>
-   */
-  @java.lang.Override
-  public com.google.protobuf.SourceContext getSourceContext() {
-    return sourceContext_ == null ? com.google.protobuf.SourceContext.getDefaultInstance() : sourceContext_;
-  }
-  /**
-   * <pre>
-   * The source context.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 4;</code>
-   */
-  private void setSourceContext(com.google.protobuf.SourceContext value) {
-    value.getClass();
-  sourceContext_ = value;
-    
-    }
-  /**
-   * <pre>
-   * The source context.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 4;</code>
-   */
-  @java.lang.SuppressWarnings({"ReferenceEquality"})
-  private void mergeSourceContext(com.google.protobuf.SourceContext value) {
-    value.getClass();
-  if (sourceContext_ != null &&
-        sourceContext_ != com.google.protobuf.SourceContext.getDefaultInstance()) {
-      sourceContext_ =
-        com.google.protobuf.SourceContext.newBuilder(sourceContext_).mergeFrom(value).buildPartial();
-    } else {
-      sourceContext_ = value;
-    }
-    
-  }
-  /**
-   * <pre>
-   * The source context.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 4;</code>
-   */
-  private void clearSourceContext() {  sourceContext_ = null;
-    
-  }
-
-  public static final int SYNTAX_FIELD_NUMBER = 5;
-  private int syntax_;
-  /**
-   * <pre>
-   * The source syntax.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 5;</code>
-   * @return The enum numeric value on the wire for syntax.
-   */
-  @java.lang.Override
-  public int getSyntaxValue() {
-    return syntax_;
-  }
-  /**
-   * <pre>
-   * The source syntax.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 5;</code>
-   * @return The syntax.
-   */
-  @java.lang.Override
-  public com.google.protobuf.Syntax getSyntax() {
-    com.google.protobuf.Syntax result = com.google.protobuf.Syntax.forNumber(syntax_);
-    return result == null ? com.google.protobuf.Syntax.UNRECOGNIZED : result;
-  }
-  /**
-   * <pre>
-   * The source syntax.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 5;</code>
-   * @param value The enum numeric value on the wire for syntax to set.
-   */
-  private void setSyntaxValue(int value) {
-      syntax_ = value;
-  }
-  /**
-   * <pre>
-   * The source syntax.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 5;</code>
-   * @param value The syntax to set.
-   */
-  private void setSyntax(com.google.protobuf.Syntax value) {
-    syntax_ = value.getNumber();
-    
-  }
-  /**
-   * <pre>
-   * The source syntax.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 5;</code>
-   */
-  private void clearSyntax() {
-    
-    syntax_ = 0;
-  }
-
-  public static com.google.protobuf.Enum parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Enum parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Enum parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Enum parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Enum parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Enum parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Enum parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Enum parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Enum parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Enum parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Enum parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Enum parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.Enum prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * Enum type definition.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.Enum}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.Enum, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.Enum)
-      com.google.protobuf.EnumOrBuilder {
-    // Construct using com.google.protobuf.Enum.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * Enum type name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return The name.
-     */
-    @java.lang.Override
-    public java.lang.String getName() {
-      return instance.getName();
-    }
-    /**
-     * <pre>
-     * Enum type name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return The bytes for name.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getNameBytes() {
-      return instance.getNameBytes();
-    }
-    /**
-     * <pre>
-     * Enum type name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @param value The name to set.
-     * @return This builder for chaining.
-     */
-    public Builder setName(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.setName(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Enum type name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearName() {
-      copyOnWrite();
-      instance.clearName();
-      return this;
-    }
-    /**
-     * <pre>
-     * Enum type name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @param value The bytes for name to set.
-     * @return This builder for chaining.
-     */
-    public Builder setNameBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setNameBytes(value);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * Enum value definitions.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.EnumValue> getEnumvalueList() {
-      return java.util.Collections.unmodifiableList(
-          instance.getEnumvalueList());
-    }
-    /**
-     * <pre>
-     * Enum value definitions.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-     */
-    @java.lang.Override
-    public int getEnumvalueCount() {
-      return instance.getEnumvalueCount();
-    }/**
-     * <pre>
-     * Enum value definitions.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.EnumValue getEnumvalue(int index) {
-      return instance.getEnumvalue(index);
-    }
-    /**
-     * <pre>
-     * Enum value definitions.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-     */
-    public Builder setEnumvalue(
-        int index, com.google.protobuf.EnumValue value) {
-      copyOnWrite();
-      instance.setEnumvalue(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Enum value definitions.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-     */
-    public Builder setEnumvalue(
-        int index, com.google.protobuf.EnumValue.Builder builderForValue) {
-      copyOnWrite();
-      instance.setEnumvalue(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Enum value definitions.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-     */
-    public Builder addEnumvalue(com.google.protobuf.EnumValue value) {
-      copyOnWrite();
-      instance.addEnumvalue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Enum value definitions.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-     */
-    public Builder addEnumvalue(
-        int index, com.google.protobuf.EnumValue value) {
-      copyOnWrite();
-      instance.addEnumvalue(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Enum value definitions.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-     */
-    public Builder addEnumvalue(
-        com.google.protobuf.EnumValue.Builder builderForValue) {
-      copyOnWrite();
-      instance.addEnumvalue(builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Enum value definitions.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-     */
-    public Builder addEnumvalue(
-        int index, com.google.protobuf.EnumValue.Builder builderForValue) {
-      copyOnWrite();
-      instance.addEnumvalue(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Enum value definitions.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-     */
-    public Builder addAllEnumvalue(
-        java.lang.Iterable<? extends com.google.protobuf.EnumValue> values) {
-      copyOnWrite();
-      instance.addAllEnumvalue(values);
-      return this;
-    }
-    /**
-     * <pre>
-     * Enum value definitions.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-     */
-    public Builder clearEnumvalue() {
-      copyOnWrite();
-      instance.clearEnumvalue();
-      return this;
-    }
-    /**
-     * <pre>
-     * Enum value definitions.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-     */
-    public Builder removeEnumvalue(int index) {
-      copyOnWrite();
-      instance.removeEnumvalue(index);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.Option> getOptionsList() {
-      return java.util.Collections.unmodifiableList(
-          instance.getOptionsList());
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    @java.lang.Override
-    public int getOptionsCount() {
-      return instance.getOptionsCount();
-    }/**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.Option getOptions(int index) {
-      return instance.getOptions(index);
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder setOptions(
-        int index, com.google.protobuf.Option value) {
-      copyOnWrite();
-      instance.setOptions(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder setOptions(
-        int index, com.google.protobuf.Option.Builder builderForValue) {
-      copyOnWrite();
-      instance.setOptions(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder addOptions(com.google.protobuf.Option value) {
-      copyOnWrite();
-      instance.addOptions(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder addOptions(
-        int index, com.google.protobuf.Option value) {
-      copyOnWrite();
-      instance.addOptions(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder addOptions(
-        com.google.protobuf.Option.Builder builderForValue) {
-      copyOnWrite();
-      instance.addOptions(builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder addOptions(
-        int index, com.google.protobuf.Option.Builder builderForValue) {
-      copyOnWrite();
-      instance.addOptions(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder addAllOptions(
-        java.lang.Iterable<? extends com.google.protobuf.Option> values) {
-      copyOnWrite();
-      instance.addAllOptions(values);
-      return this;
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder clearOptions() {
-      copyOnWrite();
-      instance.clearOptions();
-      return this;
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder removeOptions(int index) {
-      copyOnWrite();
-      instance.removeOptions(index);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The source context.
-     * </pre>
-     *
-     * <code>.google.protobuf.SourceContext source_context = 4;</code>
-     */
-    @java.lang.Override
-    public boolean hasSourceContext() {
-      return instance.hasSourceContext();
-    }
-    /**
-     * <pre>
-     * The source context.
-     * </pre>
-     *
-     * <code>.google.protobuf.SourceContext source_context = 4;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.SourceContext getSourceContext() {
-      return instance.getSourceContext();
-    }
-    /**
-     * <pre>
-     * The source context.
-     * </pre>
-     *
-     * <code>.google.protobuf.SourceContext source_context = 4;</code>
-     */
-    public Builder setSourceContext(com.google.protobuf.SourceContext value) {
-      copyOnWrite();
-      instance.setSourceContext(value);
-      return this;
-      }
-    /**
-     * <pre>
-     * The source context.
-     * </pre>
-     *
-     * <code>.google.protobuf.SourceContext source_context = 4;</code>
-     */
-    public Builder setSourceContext(
-        com.google.protobuf.SourceContext.Builder builderForValue) {
-      copyOnWrite();
-      instance.setSourceContext(builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * The source context.
-     * </pre>
-     *
-     * <code>.google.protobuf.SourceContext source_context = 4;</code>
-     */
-    public Builder mergeSourceContext(com.google.protobuf.SourceContext value) {
-      copyOnWrite();
-      instance.mergeSourceContext(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The source context.
-     * </pre>
-     *
-     * <code>.google.protobuf.SourceContext source_context = 4;</code>
-     */
-    public Builder clearSourceContext() {  copyOnWrite();
-      instance.clearSourceContext();
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The source syntax.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 5;</code>
-     * @return The enum numeric value on the wire for syntax.
-     */
-    @java.lang.Override
-    public int getSyntaxValue() {
-      return instance.getSyntaxValue();
-    }
-    /**
-     * <pre>
-     * The source syntax.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 5;</code>
-     * @param value The syntax to set.
-     * @return This builder for chaining.
-     */
-    public Builder setSyntaxValue(int value) {
-      copyOnWrite();
-      instance.setSyntaxValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The source syntax.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 5;</code>
-     * @return The syntax.
-     */
-    @java.lang.Override
-    public com.google.protobuf.Syntax getSyntax() {
-      return instance.getSyntax();
-    }
-    /**
-     * <pre>
-     * The source syntax.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 5;</code>
-     * @param value The enum numeric value on the wire for syntax to set.
-     * @return This builder for chaining.
-     */
-    public Builder setSyntax(com.google.protobuf.Syntax value) {
-      copyOnWrite();
-      instance.setSyntax(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The source syntax.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 5;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearSyntax() {
-      copyOnWrite();
-      instance.clearSyntax();
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.Enum)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.Enum();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "name_",
-            "enumvalue_",
-            com.google.protobuf.EnumValue.class,
-            "options_",
-            com.google.protobuf.Option.class,
-            "sourceContext_",
-            "syntax_",
-          };
-          java.lang.String info =
-              "\u0000\u0005\u0000\u0000\u0001\u0005\u0005\u0000\u0002\u0000\u0001\u0208\u0002\u001b" +
-              "\u0003\u001b\u0004\t\u0005\f";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.Enum> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.Enum.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.Enum>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.Enum)
-  private static final com.google.protobuf.Enum DEFAULT_INSTANCE;
-  static {
-    Enum defaultInstance = new Enum();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      Enum.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.Enum getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<Enum> PARSER;
-
-  public static com.google.protobuf.Parser<Enum> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/EnumOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/EnumOrBuilder.java
deleted file mode 100644
index 80fa317..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/EnumOrBuilder.java
+++ /dev/null
@@ -1,119 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/type.proto
-
-package com.google.protobuf;
-
-public interface EnumOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.Enum)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * Enum type name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The name.
-   */
-  java.lang.String getName();
-  /**
-   * <pre>
-   * Enum type name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The bytes for name.
-   */
-  com.google.protobuf.ByteString
-      getNameBytes();
-
-  /**
-   * <pre>
-   * Enum value definitions.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-   */
-  java.util.List<com.google.protobuf.EnumValue> 
-      getEnumvalueList();
-  /**
-   * <pre>
-   * Enum value definitions.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-   */
-  com.google.protobuf.EnumValue getEnumvalue(int index);
-  /**
-   * <pre>
-   * Enum value definitions.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
-   */
-  int getEnumvalueCount();
-
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  java.util.List<com.google.protobuf.Option> 
-      getOptionsList();
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  com.google.protobuf.Option getOptions(int index);
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  int getOptionsCount();
-
-  /**
-   * <pre>
-   * The source context.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 4;</code>
-   * @return Whether the sourceContext field is set.
-   */
-  boolean hasSourceContext();
-  /**
-   * <pre>
-   * The source context.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 4;</code>
-   * @return The sourceContext.
-   */
-  com.google.protobuf.SourceContext getSourceContext();
-
-  /**
-   * <pre>
-   * The source syntax.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 5;</code>
-   * @return The enum numeric value on the wire for syntax.
-   */
-  int getSyntaxValue();
-  /**
-   * <pre>
-   * The source syntax.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 5;</code>
-   * @return The syntax.
-   */
-  com.google.protobuf.Syntax getSyntax();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/EnumValue.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/EnumValue.java
deleted file mode 100644
index 2b27887..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/EnumValue.java
+++ /dev/null
@@ -1,700 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/type.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * Enum value definition.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.EnumValue}
- */
-public  final class EnumValue extends
-    com.google.protobuf.GeneratedMessageLite<
-        EnumValue, EnumValue.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.EnumValue)
-    EnumValueOrBuilder {
-  private EnumValue() {
-    name_ = "";
-    options_ = emptyProtobufList();
-  }
-  public static final int NAME_FIELD_NUMBER = 1;
-  private java.lang.String name_;
-  /**
-   * <pre>
-   * Enum value name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The name.
-   */
-  @java.lang.Override
-  public java.lang.String getName() {
-    return name_;
-  }
-  /**
-   * <pre>
-   * Enum value name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The bytes for name.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getNameBytes() {
-    return com.google.protobuf.ByteString.copyFromUtf8(name_);
-  }
-  /**
-   * <pre>
-   * Enum value name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @param value The name to set.
-   */
-  private void setName(
-      java.lang.String value) {
-    value.getClass();
-  
-    name_ = value;
-  }
-  /**
-   * <pre>
-   * Enum value name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   */
-  private void clearName() {
-    
-    name_ = getDefaultInstance().getName();
-  }
-  /**
-   * <pre>
-   * Enum value name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @param value The bytes for name to set.
-   */
-  private void setNameBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    name_ = value.toStringUtf8();
-    
-  }
-
-  public static final int NUMBER_FIELD_NUMBER = 2;
-  private int number_;
-  /**
-   * <pre>
-   * Enum value number.
-   * </pre>
-   *
-   * <code>int32 number = 2;</code>
-   * @return The number.
-   */
-  @java.lang.Override
-  public int getNumber() {
-    return number_;
-  }
-  /**
-   * <pre>
-   * Enum value number.
-   * </pre>
-   *
-   * <code>int32 number = 2;</code>
-   * @param value The number to set.
-   */
-  private void setNumber(int value) {
-    
-    number_ = value;
-  }
-  /**
-   * <pre>
-   * Enum value number.
-   * </pre>
-   *
-   * <code>int32 number = 2;</code>
-   */
-  private void clearNumber() {
-    
-    number_ = 0;
-  }
-
-  public static final int OPTIONS_FIELD_NUMBER = 3;
-  private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Option> options_;
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  @java.lang.Override
-  public java.util.List<com.google.protobuf.Option> getOptionsList() {
-    return options_;
-  }
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  public java.util.List<? extends com.google.protobuf.OptionOrBuilder> 
-      getOptionsOrBuilderList() {
-    return options_;
-  }
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  @java.lang.Override
-  public int getOptionsCount() {
-    return options_.size();
-  }
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  @java.lang.Override
-  public com.google.protobuf.Option getOptions(int index) {
-    return options_.get(index);
-  }
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  public com.google.protobuf.OptionOrBuilder getOptionsOrBuilder(
-      int index) {
-    return options_.get(index);
-  }
-  private void ensureOptionsIsMutable() {
-    com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Option> tmp = options_;
-    if (!tmp.isModifiable()) {
-      options_ =
-          com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-     }
-  }
-
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  private void setOptions(
-      int index, com.google.protobuf.Option value) {
-    value.getClass();
-  ensureOptionsIsMutable();
-    options_.set(index, value);
-  }
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  private void addOptions(com.google.protobuf.Option value) {
-    value.getClass();
-  ensureOptionsIsMutable();
-    options_.add(value);
-  }
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  private void addOptions(
-      int index, com.google.protobuf.Option value) {
-    value.getClass();
-  ensureOptionsIsMutable();
-    options_.add(index, value);
-  }
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  private void addAllOptions(
-      java.lang.Iterable<? extends com.google.protobuf.Option> values) {
-    ensureOptionsIsMutable();
-    com.google.protobuf.AbstractMessageLite.addAll(
-        values, options_);
-  }
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  private void clearOptions() {
-    options_ = emptyProtobufList();
-  }
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  private void removeOptions(int index) {
-    ensureOptionsIsMutable();
-    options_.remove(index);
-  }
-
-  public static com.google.protobuf.EnumValue parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.EnumValue parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.EnumValue parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.EnumValue parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.EnumValue parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.EnumValue parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.EnumValue parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.EnumValue parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.EnumValue parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.EnumValue parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.EnumValue parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.EnumValue parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.EnumValue prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * Enum value definition.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.EnumValue}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.EnumValue, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.EnumValue)
-      com.google.protobuf.EnumValueOrBuilder {
-    // Construct using com.google.protobuf.EnumValue.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * Enum value name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return The name.
-     */
-    @java.lang.Override
-    public java.lang.String getName() {
-      return instance.getName();
-    }
-    /**
-     * <pre>
-     * Enum value name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return The bytes for name.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getNameBytes() {
-      return instance.getNameBytes();
-    }
-    /**
-     * <pre>
-     * Enum value name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @param value The name to set.
-     * @return This builder for chaining.
-     */
-    public Builder setName(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.setName(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Enum value name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearName() {
-      copyOnWrite();
-      instance.clearName();
-      return this;
-    }
-    /**
-     * <pre>
-     * Enum value name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @param value The bytes for name to set.
-     * @return This builder for chaining.
-     */
-    public Builder setNameBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setNameBytes(value);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * Enum value number.
-     * </pre>
-     *
-     * <code>int32 number = 2;</code>
-     * @return The number.
-     */
-    @java.lang.Override
-    public int getNumber() {
-      return instance.getNumber();
-    }
-    /**
-     * <pre>
-     * Enum value number.
-     * </pre>
-     *
-     * <code>int32 number = 2;</code>
-     * @param value The number to set.
-     * @return This builder for chaining.
-     */
-    public Builder setNumber(int value) {
-      copyOnWrite();
-      instance.setNumber(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Enum value number.
-     * </pre>
-     *
-     * <code>int32 number = 2;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearNumber() {
-      copyOnWrite();
-      instance.clearNumber();
-      return this;
-    }
-
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.Option> getOptionsList() {
-      return java.util.Collections.unmodifiableList(
-          instance.getOptionsList());
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    @java.lang.Override
-    public int getOptionsCount() {
-      return instance.getOptionsCount();
-    }/**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.Option getOptions(int index) {
-      return instance.getOptions(index);
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder setOptions(
-        int index, com.google.protobuf.Option value) {
-      copyOnWrite();
-      instance.setOptions(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder setOptions(
-        int index, com.google.protobuf.Option.Builder builderForValue) {
-      copyOnWrite();
-      instance.setOptions(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder addOptions(com.google.protobuf.Option value) {
-      copyOnWrite();
-      instance.addOptions(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder addOptions(
-        int index, com.google.protobuf.Option value) {
-      copyOnWrite();
-      instance.addOptions(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder addOptions(
-        com.google.protobuf.Option.Builder builderForValue) {
-      copyOnWrite();
-      instance.addOptions(builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder addOptions(
-        int index, com.google.protobuf.Option.Builder builderForValue) {
-      copyOnWrite();
-      instance.addOptions(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder addAllOptions(
-        java.lang.Iterable<? extends com.google.protobuf.Option> values) {
-      copyOnWrite();
-      instance.addAllOptions(values);
-      return this;
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder clearOptions() {
-      copyOnWrite();
-      instance.clearOptions();
-      return this;
-    }
-    /**
-     * <pre>
-     * Protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 3;</code>
-     */
-    public Builder removeOptions(int index) {
-      copyOnWrite();
-      instance.removeOptions(index);
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.EnumValue)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.EnumValue();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "name_",
-            "number_",
-            "options_",
-            com.google.protobuf.Option.class,
-          };
-          java.lang.String info =
-              "\u0000\u0003\u0000\u0000\u0001\u0003\u0003\u0000\u0001\u0000\u0001\u0208\u0002\u0004" +
-              "\u0003\u001b";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.EnumValue> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.EnumValue.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.EnumValue>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.EnumValue)
-  private static final com.google.protobuf.EnumValue DEFAULT_INSTANCE;
-  static {
-    EnumValue defaultInstance = new EnumValue();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      EnumValue.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.EnumValue getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<EnumValue> PARSER;
-
-  public static com.google.protobuf.Parser<EnumValue> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/EnumValueOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/EnumValueOrBuilder.java
deleted file mode 100644
index bf2eb46..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/EnumValueOrBuilder.java
+++ /dev/null
@@ -1,65 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/type.proto
-
-package com.google.protobuf;
-
-public interface EnumValueOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.EnumValue)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * Enum value name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The name.
-   */
-  java.lang.String getName();
-  /**
-   * <pre>
-   * Enum value name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The bytes for name.
-   */
-  com.google.protobuf.ByteString
-      getNameBytes();
-
-  /**
-   * <pre>
-   * Enum value number.
-   * </pre>
-   *
-   * <code>int32 number = 2;</code>
-   * @return The number.
-   */
-  int getNumber();
-
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  java.util.List<com.google.protobuf.Option> 
-      getOptionsList();
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  com.google.protobuf.Option getOptions(int index);
-  /**
-   * <pre>
-   * Protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 3;</code>
-   */
-  int getOptionsCount();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExperimentalApi.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExperimentalApi.java
deleted file mode 100644
index d55b278..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExperimentalApi.java
+++ /dev/null
@@ -1,65 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Indicates a public API that can change at any time, and has no guarantee of API stability and
- * backward-compatibility.
- *
- * <p>Usage guidelines:
- *
- * <ol>
- *   <li>This annotation is used only on public API. Internal interfaces should not use it.
- *   <li>This annotation should only be added to new APIs. Adding it to an existing API is
- *       considered API-breaking.
- *   <li>Removing this annotation from an API gives it stable status.
- * </ol>
- */
-@Retention(RetentionPolicy.SOURCE)
-@Target({
-  ElementType.ANNOTATION_TYPE,
-  ElementType.CONSTRUCTOR,
-  ElementType.FIELD,
-  ElementType.METHOD,
-  ElementType.PACKAGE,
-  ElementType.TYPE
-})
-@Documented
-public @interface ExperimentalApi {
-  /** Context information such as links to discussion thread, tracking issue etc. */
-  String value() default "";
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtendableMessageLiteExtensions.kt b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtendableMessageLiteExtensions.kt
deleted file mode 100644
index 8bd8ed3..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtendableMessageLiteExtensions.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.google.protobuf.kotlin
-
-import com.google.protobuf.ExtensionLite
-import com.google.protobuf.GeneratedMessageLite
-
-/** Gets the value of the proto extension. */
-operator fun <
-  M : GeneratedMessageLite.ExtendableMessage<M, *>,
-  MOrBT : GeneratedMessageLite.ExtendableMessageOrBuilder<M, *>,
-  T
-  > MOrBT.get(extension: ExtensionLite<M, T>): T = getExtension(extension)
-
-/** Sets the current value of the proto extension in this builder. */
-operator fun <
-  M : GeneratedMessageLite.ExtendableMessage<M, B>,
-  B : GeneratedMessageLite.ExtendableBuilder<M, B>,
-  T
-  > B.set(extension: ExtensionLite<M, T>, value: T) {
-  setExtension(extension, value)
-}
-
-/** Returns true if the specified extension is set. */
-operator fun <
-  M : GeneratedMessageLite.ExtendableMessage<M, *>,
-  MorBT : GeneratedMessageLite.ExtendableMessageOrBuilder<M, *>
-  > MorBT.contains(
-  extension: ExtensionLite<M, *>
-): Boolean = hasExtension(extension)
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionList.kt b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionList.kt
deleted file mode 100644
index 03764e1..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionList.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.google.protobuf.kotlin
-
-import com.google.protobuf.ExtensionLite
-import com.google.protobuf.MessageLite
-
-/**
- * Implementation for ExtensionList and ExtensionListLite.  Like [DslList], represents an
- * unmodifiable view of a repeated proto field -- in this case, an extension field -- but
- * supports querying the extension.
- */
-class ExtensionList<E, M : MessageLite> @OnlyForUseByGeneratedProtoCode constructor(
-  val extension: ExtensionLite<M, List<E>>,
-  @JvmField private val delegate: List<E>
-) : List<E> by delegate {
-  override fun iterator(): Iterator<E> = UnmodifiableIterator(delegate.iterator())
-
-  override fun listIterator(): ListIterator<E> = UnmodifiableListIterator(delegate.listIterator())
-
-  override fun listIterator(index: Int): ListIterator<E> =
-    UnmodifiableListIterator(delegate.listIterator(index))
-
-  override fun equals(other: Any?): Boolean = delegate == other
-
-  override fun hashCode(): Int = delegate.hashCode()
-
-  override fun toString(): String = delegate.toString()
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionLite.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionLite.java
deleted file mode 100644
index 0fb5f49..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionLite.java
+++ /dev/null
@@ -1,60 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-/**
- * Lite interface that generated extensions implement.
- *
- * <p>Methods are for use by generated code only. You can hold a reference to extensions using this
- * type name.
- */
-public abstract class ExtensionLite<ContainingType extends MessageLite, Type> {
-
-  /** Returns the field number of the extension. */
-  public abstract int getNumber();
-
-  /** Returns the type of the field. */
-  public abstract WireFormat.FieldType getLiteType();
-
-  /** Returns whether it is a repeated field. */
-  public abstract boolean isRepeated();
-
-  /** Returns the default value of the extension field. */
-  public abstract Type getDefaultValue();
-
-  /** Returns the default instance of the extension field, if it's a message extension. */
-  public abstract MessageLite getMessageDefaultInstance();
-
-  /** Returns whether or not this extension is a Lite Extension. */
-  boolean isLite() {
-    return true;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionRegistryFactory.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionRegistryFactory.java
deleted file mode 100644
index 0a63fad..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionRegistryFactory.java
+++ /dev/null
@@ -1,91 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.ExtensionRegistryLite.EMPTY_REGISTRY_LITE;
-
-/**
- * A factory object to create instances of {@link ExtensionRegistryLite}.
- *
- * <p>This factory detects (via reflection) if the full (non-Lite) protocol buffer libraries are
- * available, and if so, the instances returned are actually {@link ExtensionRegistry}.
- */
-final class ExtensionRegistryFactory {
-
-  static final String FULL_REGISTRY_CLASS_NAME = "com.google.protobuf.ExtensionRegistry";
-
-  /* Visible for Testing
-  @Nullable */
-  static final Class<?> EXTENSION_REGISTRY_CLASS = reflectExtensionRegistry();
-
-  static Class<?> reflectExtensionRegistry() {
-    try {
-      return Class.forName(FULL_REGISTRY_CLASS_NAME);
-    } catch (ClassNotFoundException e) {
-      // The exception allocation is potentially expensive on Android (where it can be triggered
-      // many times at start up). Is there a way to ameliorate this?
-      return null;
-    }
-  }
-
-  /** Construct a new, empty instance. */
-  public static ExtensionRegistryLite create() {
-    ExtensionRegistryLite result = invokeSubclassFactory("newInstance");
-
-    return result != null ? result : new ExtensionRegistryLite();
-  }
-
-  /** Get the unmodifiable singleton empty instance. */
-  public static ExtensionRegistryLite createEmpty() {
-    ExtensionRegistryLite result = invokeSubclassFactory("getEmptyRegistry");
-
-    return result != null ? result : EMPTY_REGISTRY_LITE;
-  }
-
-
-  static boolean isFullRegistry(ExtensionRegistryLite registry) {
-    return EXTENSION_REGISTRY_CLASS != null
-        && EXTENSION_REGISTRY_CLASS.isAssignableFrom(registry.getClass());
-  }
-
-  private static final ExtensionRegistryLite invokeSubclassFactory(String methodName) {
-    if (EXTENSION_REGISTRY_CLASS == null) {
-      return null;
-    }
-
-    try {
-      return (ExtensionRegistryLite)
-          EXTENSION_REGISTRY_CLASS.getDeclaredMethod(methodName).invoke(null);
-    } catch (Exception e) {
-      return null;
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionRegistryLite.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionRegistryLite.java
deleted file mode 100644
index caa58e1..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionRegistryLite.java
+++ /dev/null
@@ -1,238 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Equivalent to {@link ExtensionRegistry} but supports only "lite" types.
- *
- * <p>If all of your types are lite types, then you only need to use {@code ExtensionRegistryLite}.
- * Similarly, if all your types are regular types, then you only need {@link ExtensionRegistry}.
- * Typically it does not make sense to mix the two, since if you have any regular types in your
- * program, you then require the full runtime and lose all the benefits of the lite runtime, so you
- * might as well make all your types be regular types. However, in some cases (e.g. when depending
- * on multiple third-party libraries where one uses lite types and one uses regular), you may find
- * yourself wanting to mix the two. In this case things get more complicated.
- *
- * <p>There are three factors to consider: Whether the type being extended is lite, whether the
- * embedded type (in the case of a message-typed extension) is lite, and whether the extension
- * itself is lite. Since all three are declared in different files, they could all be different.
- * Here are all the combinations and which type of registry to use:
- *
- * <pre>
- *   Extended type     Inner type    Extension         Use registry
- *   =======================================================================
- *   lite              lite          lite              ExtensionRegistryLite
- *   lite              regular       lite              ExtensionRegistry
- *   regular           regular       regular           ExtensionRegistry
- *   all other combinations                            not supported
- * </pre>
- *
- * <p>Note that just as regular types are not allowed to contain lite-type fields, they are also not
- * allowed to contain lite-type extensions. This is because regular types must be fully accessible
- * via reflection, which in turn means that all the inner messages must also support reflection. On
- * the other hand, since regular types implement the entire lite interface, there is no problem with
- * embedding regular types inside lite types.
- *
- * @author kenton@google.com Kenton Varda
- */
-public class ExtensionRegistryLite {
-
-  // Set true to enable lazy parsing feature for MessageSet.
-  //
-  // TODO(xiangl): Now we use a global flag to control whether enable lazy
-  // parsing feature for MessageSet, which may be too crude for some
-  // applications. Need to support this feature on smaller granularity.
-  private static volatile boolean eagerlyParseMessageSets = false;
-
-  // short circuit the ExtensionRegistryFactory via assumevalues trickery
-  @SuppressWarnings("JavaOptionalSuggestions")
-  private static boolean doFullRuntimeInheritanceCheck = true;
-
-  // Visible for testing.
-  static final String EXTENSION_CLASS_NAME = "com.google.protobuf.Extension";
-
-  private static class ExtensionClassHolder {
-    static final Class<?> INSTANCE = resolveExtensionClass();
-
-    static Class<?> resolveExtensionClass() {
-      try {
-        return Class.forName(EXTENSION_CLASS_NAME);
-      } catch (ClassNotFoundException e) {
-        // See comment in ExtensionRegistryFactory on the potential expense of this.
-        return null;
-      }
-    }
-  }
-
-  public static boolean isEagerlyParseMessageSets() {
-    return eagerlyParseMessageSets;
-  }
-
-  public static void setEagerlyParseMessageSets(boolean isEagerlyParse) {
-    eagerlyParseMessageSets = isEagerlyParse;
-  }
-
-  /**
-   * Construct a new, empty instance.
-   *
-   * <p>This may be an {@code ExtensionRegistry} if the full (non-Lite) proto libraries are
-   * available.
-   */
-  public static ExtensionRegistryLite newInstance() {
-    return doFullRuntimeInheritanceCheck
-        ? ExtensionRegistryFactory.create()
-        : new ExtensionRegistryLite();
-  }
-
-  private static volatile ExtensionRegistryLite emptyRegistry;
-
-  /**
-   * Get the unmodifiable singleton empty instance of either ExtensionRegistryLite or {@code
-   * ExtensionRegistry} (if the full (non-Lite) proto libraries are available).
-   */
-  public static ExtensionRegistryLite getEmptyRegistry() {
-    ExtensionRegistryLite result = emptyRegistry;
-    if (result == null) {
-      synchronized (ExtensionRegistryLite.class) {
-        result = emptyRegistry;
-        if (result == null) {
-          result =
-              emptyRegistry =
-                  doFullRuntimeInheritanceCheck
-                      ? ExtensionRegistryFactory.createEmpty()
-                      : EMPTY_REGISTRY_LITE;
-        }
-      }
-    }
-    return result;
-  }
-
-
-  /** Returns an unmodifiable view of the registry. */
-  public ExtensionRegistryLite getUnmodifiable() {
-    return new ExtensionRegistryLite(this);
-  }
-
-  /**
-   * Find an extension by containing type and field number.
-   *
-   * @return Information about the extension if found, or {@code null} otherwise.
-   */
-  @SuppressWarnings("unchecked")
-  public <ContainingType extends MessageLite>
-      GeneratedMessageLite.GeneratedExtension<ContainingType, ?> findLiteExtensionByNumber(
-          final ContainingType containingTypeDefaultInstance, final int fieldNumber) {
-    return (GeneratedMessageLite.GeneratedExtension<ContainingType, ?>)
-        extensionsByNumber.get(new ObjectIntPair(containingTypeDefaultInstance, fieldNumber));
-  }
-
-  /** Add an extension from a lite generated file to the registry. */
-  public final void add(final GeneratedMessageLite.GeneratedExtension<?, ?> extension) {
-    extensionsByNumber.put(
-        new ObjectIntPair(extension.getContainingTypeDefaultInstance(), extension.getNumber()),
-        extension);
-  }
-
-  /**
-   * Add an extension from a lite generated file to the registry only if it is a non-lite extension
-   * i.e. {@link GeneratedMessageLite.GeneratedExtension}.
-   */
-  public final void add(ExtensionLite<?, ?> extension) {
-    if (GeneratedMessageLite.GeneratedExtension.class.isAssignableFrom(extension.getClass())) {
-      add((GeneratedMessageLite.GeneratedExtension<?, ?>) extension);
-    }
-    if (doFullRuntimeInheritanceCheck && ExtensionRegistryFactory.isFullRegistry(this)) {
-      try {
-        this.getClass().getMethod("add", ExtensionClassHolder.INSTANCE).invoke(this, extension);
-      } catch (Exception e) {
-        throw new IllegalArgumentException(
-            String.format("Could not invoke ExtensionRegistry#add for %s", extension), e);
-      }
-    }
-  }
-
-  // =================================================================
-  // Private stuff.
-
-  // Constructors are package-private so that ExtensionRegistry can subclass
-  // this.
-
-  ExtensionRegistryLite() {
-    this.extensionsByNumber =
-        new HashMap<ObjectIntPair, GeneratedMessageLite.GeneratedExtension<?, ?>>();
-  }
-
-  static final ExtensionRegistryLite EMPTY_REGISTRY_LITE = new ExtensionRegistryLite(true);
-
-  ExtensionRegistryLite(ExtensionRegistryLite other) {
-    if (other == EMPTY_REGISTRY_LITE) {
-      this.extensionsByNumber = Collections.emptyMap();
-    } else {
-      this.extensionsByNumber = Collections.unmodifiableMap(other.extensionsByNumber);
-    }
-  }
-
-  private final Map<ObjectIntPair, GeneratedMessageLite.GeneratedExtension<?, ?>>
-      extensionsByNumber;
-
-  ExtensionRegistryLite(boolean empty) {
-    this.extensionsByNumber = Collections.emptyMap();
-  }
-
-  /** A (Object, int) pair, used as a map key. */
-  private static final class ObjectIntPair {
-    private final Object object;
-    private final int number;
-
-    ObjectIntPair(final Object object, final int number) {
-      this.object = object;
-      this.number = number;
-    }
-
-    @Override
-    public int hashCode() {
-      return System.identityHashCode(object) * ((1 << 16) - 1) + number;
-    }
-
-    @Override
-    public boolean equals(final Object obj) {
-      if (!(obj instanceof ObjectIntPair)) {
-        return false;
-      }
-      final ObjectIntPair other = (ObjectIntPair) obj;
-      return object == other.object && number == other.number;
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionSchema.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionSchema.java
deleted file mode 100644
index 2eae22d..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionSchema.java
+++ /dev/null
@@ -1,98 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.io.IOException;
-import java.util.Map;
-
-abstract class ExtensionSchema<T extends FieldSet.FieldDescriptorLite<T>> {
-
-  /** Returns true for messages that support extensions. */
-  abstract boolean hasExtensions(MessageLite prototype);
-
-  /** Returns the extension {@link FieldSet} for the message instance. */
-  abstract FieldSet<T> getExtensions(Object message);
-
-  /** Replaces the extension {@link FieldSet} for the message instance. */
-  abstract void setExtensions(Object message, FieldSet<T> extensions);
-
-  /** Returns the extension {@link FieldSet} and ensures it's mutable. */
-  abstract FieldSet<T> getMutableExtensions(Object message);
-
-  /** Marks the extension {@link FieldSet} as immutable. */
-  abstract void makeImmutable(Object message);
-
-  /**
-   * Parses an extension. Returns the passed-in unknownFields parameter if no unknown enum value is
-   * found or a modified unknownFields (a new instance if the passed-in unknownFields is null)
-   * containing unknown enum values found while parsing.
-   *
-   * @param <UT> The type used to store unknown fields. It's either UnknownFieldSet in full runtime
-   *     or UnknownFieldSetLite in lite runtime.
-   */
-  abstract <UT, UB> UB parseExtension(
-      Reader reader,
-      Object extension,
-      ExtensionRegistryLite extensionRegistry,
-      FieldSet<T> extensions,
-      UB unknownFields,
-      UnknownFieldSchema<UT, UB> unknownFieldSchema)
-      throws IOException;
-
-  /** Gets the field number of an extension entry. */
-  abstract int extensionNumber(Map.Entry<?, ?> extension);
-
-  /** Serializes one extension entry. */
-  abstract void serializeExtension(Writer writer, Map.Entry<?, ?> extension) throws IOException;
-
-  /** Finds an extension by field number. */
-  abstract Object findExtensionByNumber(
-      ExtensionRegistryLite extensionRegistry, MessageLite defaultInstance, int number);
-
-  /** Parses a length-prefixed MessageSet item from the reader. */
-  abstract void parseLengthPrefixedMessageSetItem(
-      Reader reader,
-      Object extension,
-      ExtensionRegistryLite extensionRegistry,
-      FieldSet<T> extensions)
-      throws IOException;
-
-  /**
-   * Parses the entire content of a {@link ByteString} as one MessageSet item. Unlike {@link
-   * #parseLengthPrefixedMessageSetItem}, there isn't a length-prefix.
-   */
-  abstract void parseMessageSetItem(
-      ByteString data,
-      Object extension,
-      ExtensionRegistryLite extensionRegistry,
-      FieldSet<T> extensions)
-      throws IOException;
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionSchemaLite.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionSchemaLite.java
deleted file mode 100644
index 437cca2..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionSchemaLite.java
+++ /dev/null
@@ -1,541 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import com.google.protobuf.GeneratedMessageLite.ExtensionDescriptor;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-@SuppressWarnings("unchecked")
-final class ExtensionSchemaLite extends ExtensionSchema<ExtensionDescriptor> {
-
-  @Override
-  boolean hasExtensions(MessageLite prototype) {
-    return prototype instanceof GeneratedMessageLite.ExtendableMessage;
-  }
-
-  @Override
-  FieldSet<ExtensionDescriptor> getExtensions(Object message) {
-    return ((GeneratedMessageLite.ExtendableMessage<?, ?>) message).extensions;
-  }
-
-  @Override
-  void setExtensions(Object message, FieldSet<ExtensionDescriptor> extensions) {
-    ((GeneratedMessageLite.ExtendableMessage<?, ?>) message).extensions = extensions;
-  }
-
-  @Override
-  FieldSet<ExtensionDescriptor> getMutableExtensions(Object message) {
-    return ((GeneratedMessageLite.ExtendableMessage<?, ?>) message).ensureExtensionsAreMutable();
-  }
-
-  @Override
-  void makeImmutable(Object message) {
-    getExtensions(message).makeImmutable();
-  }
-
-  @Override
-  <UT, UB> UB parseExtension(
-      Reader reader,
-      Object extensionObject,
-      ExtensionRegistryLite extensionRegistry,
-      FieldSet<ExtensionDescriptor> extensions,
-      UB unknownFields,
-      UnknownFieldSchema<UT, UB> unknownFieldSchema)
-      throws IOException {
-    GeneratedMessageLite.GeneratedExtension<?, ?> extension =
-        (GeneratedMessageLite.GeneratedExtension<?, ?>) extensionObject;
-    int fieldNumber = extension.getNumber();
-
-    if (extension.descriptor.isRepeated() && extension.descriptor.isPacked()) {
-      Object value = null;
-      switch (extension.getLiteType()) {
-        case DOUBLE:
-          {
-            List<Double> list = new ArrayList<Double>();
-            reader.readDoubleList(list);
-            value = list;
-            break;
-          }
-        case FLOAT:
-          {
-            List<Float> list = new ArrayList<Float>();
-            reader.readFloatList(list);
-            value = list;
-            break;
-          }
-        case INT64:
-          {
-            List<Long> list = new ArrayList<Long>();
-            reader.readInt64List(list);
-            value = list;
-            break;
-          }
-        case UINT64:
-          {
-            List<Long> list = new ArrayList<Long>();
-            reader.readUInt64List(list);
-            value = list;
-            break;
-          }
-        case INT32:
-          {
-            List<Integer> list = new ArrayList<Integer>();
-            reader.readInt32List(list);
-            value = list;
-            break;
-          }
-        case FIXED64:
-          {
-            List<Long> list = new ArrayList<Long>();
-            reader.readFixed64List(list);
-            value = list;
-            break;
-          }
-        case FIXED32:
-          {
-            List<Integer> list = new ArrayList<Integer>();
-            reader.readFixed32List(list);
-            value = list;
-            break;
-          }
-        case BOOL:
-          {
-            List<Boolean> list = new ArrayList<Boolean>();
-            reader.readBoolList(list);
-            value = list;
-            break;
-          }
-        case UINT32:
-          {
-            List<Integer> list = new ArrayList<Integer>();
-            reader.readUInt32List(list);
-            value = list;
-            break;
-          }
-        case SFIXED32:
-          {
-            List<Integer> list = new ArrayList<Integer>();
-            reader.readSFixed32List(list);
-            value = list;
-            break;
-          }
-        case SFIXED64:
-          {
-            List<Long> list = new ArrayList<Long>();
-            reader.readSFixed64List(list);
-            value = list;
-            break;
-          }
-        case SINT32:
-          {
-            List<Integer> list = new ArrayList<Integer>();
-            reader.readSInt32List(list);
-            value = list;
-            break;
-          }
-        case SINT64:
-          {
-            List<Long> list = new ArrayList<Long>();
-            reader.readSInt64List(list);
-            value = list;
-            break;
-          }
-        case ENUM:
-          {
-            List<Integer> list = new ArrayList<Integer>();
-            reader.readEnumList(list);
-            unknownFields =
-                SchemaUtil.filterUnknownEnumList(
-                    fieldNumber,
-                    list,
-                    extension.descriptor.getEnumType(),
-                    unknownFields,
-                    unknownFieldSchema);
-            value = list;
-            break;
-          }
-        default:
-          throw new IllegalStateException(
-              "Type cannot be packed: " + extension.descriptor.getLiteType());
-      }
-      extensions.setField(extension.descriptor, value);
-    } else {
-      Object value = null;
-      // Enum is a special case because unknown enum values will be put into UnknownFieldSetLite.
-      if (extension.getLiteType() == WireFormat.FieldType.ENUM) {
-        int number = reader.readInt32();
-        Object enumValue = extension.descriptor.getEnumType().findValueByNumber(number);
-        if (enumValue == null) {
-          return SchemaUtil.storeUnknownEnum(
-              fieldNumber, number, unknownFields, unknownFieldSchema);
-        }
-        // Note, we store the integer value instead of the actual enum object in FieldSet.
-        // This is also different from full-runtime where we store EnumValueDescriptor.
-        value = number;
-      } else {
-        switch (extension.getLiteType()) {
-          case DOUBLE:
-            value = reader.readDouble();
-            break;
-          case FLOAT:
-            value = reader.readFloat();
-            break;
-          case INT64:
-            value = reader.readInt64();
-            break;
-          case UINT64:
-            value = reader.readUInt64();
-            break;
-          case INT32:
-            value = reader.readInt32();
-            break;
-          case FIXED64:
-            value = reader.readFixed64();
-            break;
-          case FIXED32:
-            value = reader.readFixed32();
-            break;
-          case BOOL:
-            value = reader.readBool();
-            break;
-          case BYTES:
-            value = reader.readBytes();
-            break;
-          case UINT32:
-            value = reader.readUInt32();
-            break;
-          case SFIXED32:
-            value = reader.readSFixed32();
-            break;
-          case SFIXED64:
-            value = reader.readSFixed64();
-            break;
-          case SINT32:
-            value = reader.readSInt32();
-            break;
-          case SINT64:
-            value = reader.readSInt64();
-            break;
-
-          case STRING:
-            value = reader.readString();
-            break;
-          case GROUP:
-            value =
-                reader.readGroup(
-                    extension.getMessageDefaultInstance().getClass(), extensionRegistry);
-            break;
-
-          case MESSAGE:
-            value =
-                reader.readMessage(
-                    extension.getMessageDefaultInstance().getClass(), extensionRegistry);
-            break;
-
-          case ENUM:
-            throw new IllegalStateException("Shouldn't reach here.");
-        }
-      }
-      if (extension.isRepeated()) {
-        extensions.addRepeatedField(extension.descriptor, value);
-      } else {
-        switch (extension.getLiteType()) {
-          case MESSAGE:
-          case GROUP:
-            Object oldValue = extensions.getField(extension.descriptor);
-            if (oldValue != null) {
-              value = Internal.mergeMessage(oldValue, value);
-            }
-            break;
-          default:
-            break;
-        }
-        extensions.setField(extension.descriptor, value);
-      }
-    }
-    return unknownFields;
-  }
-
-  @Override
-  int extensionNumber(Map.Entry<?, ?> extension) {
-    GeneratedMessageLite.ExtensionDescriptor descriptor =
-        (GeneratedMessageLite.ExtensionDescriptor) extension.getKey();
-    return descriptor.getNumber();
-  }
-
-  @Override
-  void serializeExtension(Writer writer, Map.Entry<?, ?> extension) throws IOException {
-    GeneratedMessageLite.ExtensionDescriptor descriptor =
-        (GeneratedMessageLite.ExtensionDescriptor) extension.getKey();
-    if (descriptor.isRepeated()) {
-      switch (descriptor.getLiteType()) {
-        case DOUBLE:
-          SchemaUtil.writeDoubleList(
-              descriptor.getNumber(),
-              (List<Double>) extension.getValue(),
-              writer,
-              descriptor.isPacked());
-          break;
-        case FLOAT:
-          SchemaUtil.writeFloatList(
-              descriptor.getNumber(),
-              (List<Float>) extension.getValue(),
-              writer,
-              descriptor.isPacked());
-          break;
-        case INT64:
-          SchemaUtil.writeInt64List(
-              descriptor.getNumber(),
-              (List<Long>) extension.getValue(),
-              writer,
-              descriptor.isPacked());
-          break;
-        case UINT64:
-          SchemaUtil.writeUInt64List(
-              descriptor.getNumber(),
-              (List<Long>) extension.getValue(),
-              writer,
-              descriptor.isPacked());
-          break;
-        case INT32:
-          SchemaUtil.writeInt32List(
-              descriptor.getNumber(),
-              (List<Integer>) extension.getValue(),
-              writer,
-              descriptor.isPacked());
-          break;
-        case FIXED64:
-          SchemaUtil.writeFixed64List(
-              descriptor.getNumber(),
-              (List<Long>) extension.getValue(),
-              writer,
-              descriptor.isPacked());
-          break;
-        case FIXED32:
-          SchemaUtil.writeFixed32List(
-              descriptor.getNumber(),
-              (List<Integer>) extension.getValue(),
-              writer,
-              descriptor.isPacked());
-          break;
-        case BOOL:
-          SchemaUtil.writeBoolList(
-              descriptor.getNumber(),
-              (List<Boolean>) extension.getValue(),
-              writer,
-              descriptor.isPacked());
-          break;
-        case BYTES:
-          SchemaUtil.writeBytesList(
-              descriptor.getNumber(), (List<ByteString>) extension.getValue(), writer);
-          break;
-        case UINT32:
-          SchemaUtil.writeUInt32List(
-              descriptor.getNumber(),
-              (List<Integer>) extension.getValue(),
-              writer,
-              descriptor.isPacked());
-          break;
-        case SFIXED32:
-          SchemaUtil.writeSFixed32List(
-              descriptor.getNumber(),
-              (List<Integer>) extension.getValue(),
-              writer,
-              descriptor.isPacked());
-          break;
-        case SFIXED64:
-          SchemaUtil.writeSFixed64List(
-              descriptor.getNumber(),
-              (List<Long>) extension.getValue(),
-              writer,
-              descriptor.isPacked());
-          break;
-        case SINT32:
-          SchemaUtil.writeSInt32List(
-              descriptor.getNumber(),
-              (List<Integer>) extension.getValue(),
-              writer,
-              descriptor.isPacked());
-          break;
-        case SINT64:
-          SchemaUtil.writeSInt64List(
-              descriptor.getNumber(),
-              (List<Long>) extension.getValue(),
-              writer,
-              descriptor.isPacked());
-          break;
-        case ENUM:
-          SchemaUtil.writeInt32List(
-              descriptor.getNumber(),
-              (List<Integer>) extension.getValue(),
-              writer,
-              descriptor.isPacked());
-          break;
-        case STRING:
-          SchemaUtil.writeStringList(
-              descriptor.getNumber(), (List<String>) extension.getValue(), writer);
-          break;
-        case GROUP:
-          {
-            List<?> data = (List<?>) extension.getValue();
-            if (data != null && !data.isEmpty()) {
-              SchemaUtil.writeGroupList(
-                  descriptor.getNumber(),
-                  (List<?>) extension.getValue(),
-                  writer,
-                  Protobuf.getInstance().schemaFor(data.get(0).getClass()));
-            }
-          }
-          break;
-        case MESSAGE:
-          {
-            List<?> data = (List<?>) extension.getValue();
-            if (data != null && !data.isEmpty()) {
-              SchemaUtil.writeMessageList(
-                  descriptor.getNumber(),
-                  (List<?>) extension.getValue(),
-                  writer,
-                  Protobuf.getInstance().schemaFor(data.get(0).getClass()));
-            }
-          }
-          break;
-      }
-    } else {
-      switch (descriptor.getLiteType()) {
-        case DOUBLE:
-          writer.writeDouble(descriptor.getNumber(), (Double) extension.getValue());
-          break;
-        case FLOAT:
-          writer.writeFloat(descriptor.getNumber(), (Float) extension.getValue());
-          break;
-        case INT64:
-          writer.writeInt64(descriptor.getNumber(), (Long) extension.getValue());
-          break;
-        case UINT64:
-          writer.writeUInt64(descriptor.getNumber(), (Long) extension.getValue());
-          break;
-        case INT32:
-          writer.writeInt32(descriptor.getNumber(), (Integer) extension.getValue());
-          break;
-        case FIXED64:
-          writer.writeFixed64(descriptor.getNumber(), (Long) extension.getValue());
-          break;
-        case FIXED32:
-          writer.writeFixed32(descriptor.getNumber(), (Integer) extension.getValue());
-          break;
-        case BOOL:
-          writer.writeBool(descriptor.getNumber(), (Boolean) extension.getValue());
-          break;
-        case BYTES:
-          writer.writeBytes(descriptor.getNumber(), (ByteString) extension.getValue());
-          break;
-        case UINT32:
-          writer.writeUInt32(descriptor.getNumber(), (Integer) extension.getValue());
-          break;
-        case SFIXED32:
-          writer.writeSFixed32(descriptor.getNumber(), (Integer) extension.getValue());
-          break;
-        case SFIXED64:
-          writer.writeSFixed64(descriptor.getNumber(), (Long) extension.getValue());
-          break;
-        case SINT32:
-          writer.writeSInt32(descriptor.getNumber(), (Integer) extension.getValue());
-          break;
-        case SINT64:
-          writer.writeSInt64(descriptor.getNumber(), (Long) extension.getValue());
-          break;
-        case ENUM:
-          writer.writeInt32(descriptor.getNumber(), (Integer) extension.getValue());
-          break;
-        case STRING:
-          writer.writeString(descriptor.getNumber(), (String) extension.getValue());
-          break;
-        case GROUP:
-          writer.writeGroup(
-              descriptor.getNumber(),
-              extension.getValue(),
-              Protobuf.getInstance().schemaFor(extension.getValue().getClass()));
-          break;
-        case MESSAGE:
-          writer.writeMessage(
-              descriptor.getNumber(),
-              extension.getValue(),
-              Protobuf.getInstance().schemaFor(extension.getValue().getClass()));
-          break;
-      }
-    }
-  }
-
-  @Override
-  Object findExtensionByNumber(
-      ExtensionRegistryLite extensionRegistry, MessageLite defaultInstance, int number) {
-    return extensionRegistry.findLiteExtensionByNumber(defaultInstance, number);
-  }
-
-  @Override
-  void parseLengthPrefixedMessageSetItem(
-      Reader reader,
-      Object extensionObject,
-      ExtensionRegistryLite extensionRegistry,
-      FieldSet<ExtensionDescriptor> extensions)
-      throws IOException {
-    GeneratedMessageLite.GeneratedExtension<?, ?> extension =
-        (GeneratedMessageLite.GeneratedExtension<?, ?>) extensionObject;
-    Object value =
-        reader.readMessage(extension.getMessageDefaultInstance().getClass(), extensionRegistry);
-    extensions.setField(extension.descriptor, value);
-  }
-
-  @Override
-  void parseMessageSetItem(
-      ByteString data,
-      Object extensionObject,
-      ExtensionRegistryLite extensionRegistry,
-      FieldSet<ExtensionDescriptor> extensions)
-      throws IOException {
-    GeneratedMessageLite.GeneratedExtension<?, ?> extension =
-        (GeneratedMessageLite.GeneratedExtension<?, ?>) extensionObject;
-    Object value = extension.getMessageDefaultInstance().newBuilderForType().buildPartial();
-
-    Reader reader = BinaryReader.newInstance(ByteBuffer.wrap(data.toByteArray()), true);
-
-    Protobuf.getInstance().mergeFrom(value, reader, extensionRegistry);
-    extensions.setField(extension.descriptor, value);
-
-    if (reader.getFieldNumber() != Reader.READ_DONE) {
-      throw InvalidProtocolBufferException.invalidEndTag();
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionSchemas.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionSchemas.java
deleted file mode 100644
index 46ce327..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ExtensionSchemas.java
+++ /dev/null
@@ -1,56 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-final class ExtensionSchemas {
-  private static final ExtensionSchema<?> LITE_SCHEMA = new ExtensionSchemaLite();
-  private static final ExtensionSchema<?> FULL_SCHEMA = loadSchemaForFullRuntime();
-
-  private static ExtensionSchema<?> loadSchemaForFullRuntime() {
-    try {
-      Class<?> clazz = Class.forName("com.google.protobuf.ExtensionSchemaFull");
-      return (ExtensionSchema) clazz.getDeclaredConstructor().newInstance();
-    } catch (Exception e) {
-      return null;
-    }
-  }
-
-  static ExtensionSchema<?> lite() {
-    return LITE_SCHEMA;
-  }
-
-  static ExtensionSchema<?> full() {
-    if (FULL_SCHEMA == null) {
-      throw new IllegalStateException("Protobuf runtime is not correctly loaded.");
-    }
-    return FULL_SCHEMA;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Field.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Field.java
deleted file mode 100644
index b0079c1..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Field.java
+++ /dev/null
@@ -1,2087 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/type.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * A single field of a message type.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.Field}
- */
-public  final class Field extends
-    com.google.protobuf.GeneratedMessageLite<
-        Field, Field.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.Field)
-    FieldOrBuilder {
-  private Field() {
-    name_ = "";
-    typeUrl_ = "";
-    options_ = emptyProtobufList();
-    jsonName_ = "";
-    defaultValue_ = "";
-  }
-  /**
-   * <pre>
-   * Basic field types.
-   * </pre>
-   *
-   * Protobuf enum {@code google.protobuf.Field.Kind}
-   */
-  public enum Kind
-      implements com.google.protobuf.Internal.EnumLite {
-    /**
-     * <pre>
-     * Field type unknown.
-     * </pre>
-     *
-     * <code>TYPE_UNKNOWN = 0;</code>
-     */
-    TYPE_UNKNOWN(0),
-    /**
-     * <pre>
-     * Field type double.
-     * </pre>
-     *
-     * <code>TYPE_DOUBLE = 1;</code>
-     */
-    TYPE_DOUBLE(1),
-    /**
-     * <pre>
-     * Field type float.
-     * </pre>
-     *
-     * <code>TYPE_FLOAT = 2;</code>
-     */
-    TYPE_FLOAT(2),
-    /**
-     * <pre>
-     * Field type int64.
-     * </pre>
-     *
-     * <code>TYPE_INT64 = 3;</code>
-     */
-    TYPE_INT64(3),
-    /**
-     * <pre>
-     * Field type uint64.
-     * </pre>
-     *
-     * <code>TYPE_UINT64 = 4;</code>
-     */
-    TYPE_UINT64(4),
-    /**
-     * <pre>
-     * Field type int32.
-     * </pre>
-     *
-     * <code>TYPE_INT32 = 5;</code>
-     */
-    TYPE_INT32(5),
-    /**
-     * <pre>
-     * Field type fixed64.
-     * </pre>
-     *
-     * <code>TYPE_FIXED64 = 6;</code>
-     */
-    TYPE_FIXED64(6),
-    /**
-     * <pre>
-     * Field type fixed32.
-     * </pre>
-     *
-     * <code>TYPE_FIXED32 = 7;</code>
-     */
-    TYPE_FIXED32(7),
-    /**
-     * <pre>
-     * Field type bool.
-     * </pre>
-     *
-     * <code>TYPE_BOOL = 8;</code>
-     */
-    TYPE_BOOL(8),
-    /**
-     * <pre>
-     * Field type string.
-     * </pre>
-     *
-     * <code>TYPE_STRING = 9;</code>
-     */
-    TYPE_STRING(9),
-    /**
-     * <pre>
-     * Field type group. Proto2 syntax only, and deprecated.
-     * </pre>
-     *
-     * <code>TYPE_GROUP = 10;</code>
-     */
-    TYPE_GROUP(10),
-    /**
-     * <pre>
-     * Field type message.
-     * </pre>
-     *
-     * <code>TYPE_MESSAGE = 11;</code>
-     */
-    TYPE_MESSAGE(11),
-    /**
-     * <pre>
-     * Field type bytes.
-     * </pre>
-     *
-     * <code>TYPE_BYTES = 12;</code>
-     */
-    TYPE_BYTES(12),
-    /**
-     * <pre>
-     * Field type uint32.
-     * </pre>
-     *
-     * <code>TYPE_UINT32 = 13;</code>
-     */
-    TYPE_UINT32(13),
-    /**
-     * <pre>
-     * Field type enum.
-     * </pre>
-     *
-     * <code>TYPE_ENUM = 14;</code>
-     */
-    TYPE_ENUM(14),
-    /**
-     * <pre>
-     * Field type sfixed32.
-     * </pre>
-     *
-     * <code>TYPE_SFIXED32 = 15;</code>
-     */
-    TYPE_SFIXED32(15),
-    /**
-     * <pre>
-     * Field type sfixed64.
-     * </pre>
-     *
-     * <code>TYPE_SFIXED64 = 16;</code>
-     */
-    TYPE_SFIXED64(16),
-    /**
-     * <pre>
-     * Field type sint32.
-     * </pre>
-     *
-     * <code>TYPE_SINT32 = 17;</code>
-     */
-    TYPE_SINT32(17),
-    /**
-     * <pre>
-     * Field type sint64.
-     * </pre>
-     *
-     * <code>TYPE_SINT64 = 18;</code>
-     */
-    TYPE_SINT64(18),
-    UNRECOGNIZED(-1),
-    ;
-
-    /**
-     * <pre>
-     * Field type unknown.
-     * </pre>
-     *
-     * <code>TYPE_UNKNOWN = 0;</code>
-     */
-    public static final int TYPE_UNKNOWN_VALUE = 0;
-    /**
-     * <pre>
-     * Field type double.
-     * </pre>
-     *
-     * <code>TYPE_DOUBLE = 1;</code>
-     */
-    public static final int TYPE_DOUBLE_VALUE = 1;
-    /**
-     * <pre>
-     * Field type float.
-     * </pre>
-     *
-     * <code>TYPE_FLOAT = 2;</code>
-     */
-    public static final int TYPE_FLOAT_VALUE = 2;
-    /**
-     * <pre>
-     * Field type int64.
-     * </pre>
-     *
-     * <code>TYPE_INT64 = 3;</code>
-     */
-    public static final int TYPE_INT64_VALUE = 3;
-    /**
-     * <pre>
-     * Field type uint64.
-     * </pre>
-     *
-     * <code>TYPE_UINT64 = 4;</code>
-     */
-    public static final int TYPE_UINT64_VALUE = 4;
-    /**
-     * <pre>
-     * Field type int32.
-     * </pre>
-     *
-     * <code>TYPE_INT32 = 5;</code>
-     */
-    public static final int TYPE_INT32_VALUE = 5;
-    /**
-     * <pre>
-     * Field type fixed64.
-     * </pre>
-     *
-     * <code>TYPE_FIXED64 = 6;</code>
-     */
-    public static final int TYPE_FIXED64_VALUE = 6;
-    /**
-     * <pre>
-     * Field type fixed32.
-     * </pre>
-     *
-     * <code>TYPE_FIXED32 = 7;</code>
-     */
-    public static final int TYPE_FIXED32_VALUE = 7;
-    /**
-     * <pre>
-     * Field type bool.
-     * </pre>
-     *
-     * <code>TYPE_BOOL = 8;</code>
-     */
-    public static final int TYPE_BOOL_VALUE = 8;
-    /**
-     * <pre>
-     * Field type string.
-     * </pre>
-     *
-     * <code>TYPE_STRING = 9;</code>
-     */
-    public static final int TYPE_STRING_VALUE = 9;
-    /**
-     * <pre>
-     * Field type group. Proto2 syntax only, and deprecated.
-     * </pre>
-     *
-     * <code>TYPE_GROUP = 10;</code>
-     */
-    public static final int TYPE_GROUP_VALUE = 10;
-    /**
-     * <pre>
-     * Field type message.
-     * </pre>
-     *
-     * <code>TYPE_MESSAGE = 11;</code>
-     */
-    public static final int TYPE_MESSAGE_VALUE = 11;
-    /**
-     * <pre>
-     * Field type bytes.
-     * </pre>
-     *
-     * <code>TYPE_BYTES = 12;</code>
-     */
-    public static final int TYPE_BYTES_VALUE = 12;
-    /**
-     * <pre>
-     * Field type uint32.
-     * </pre>
-     *
-     * <code>TYPE_UINT32 = 13;</code>
-     */
-    public static final int TYPE_UINT32_VALUE = 13;
-    /**
-     * <pre>
-     * Field type enum.
-     * </pre>
-     *
-     * <code>TYPE_ENUM = 14;</code>
-     */
-    public static final int TYPE_ENUM_VALUE = 14;
-    /**
-     * <pre>
-     * Field type sfixed32.
-     * </pre>
-     *
-     * <code>TYPE_SFIXED32 = 15;</code>
-     */
-    public static final int TYPE_SFIXED32_VALUE = 15;
-    /**
-     * <pre>
-     * Field type sfixed64.
-     * </pre>
-     *
-     * <code>TYPE_SFIXED64 = 16;</code>
-     */
-    public static final int TYPE_SFIXED64_VALUE = 16;
-    /**
-     * <pre>
-     * Field type sint32.
-     * </pre>
-     *
-     * <code>TYPE_SINT32 = 17;</code>
-     */
-    public static final int TYPE_SINT32_VALUE = 17;
-    /**
-     * <pre>
-     * Field type sint64.
-     * </pre>
-     *
-     * <code>TYPE_SINT64 = 18;</code>
-     */
-    public static final int TYPE_SINT64_VALUE = 18;
-
-
-    @java.lang.Override
-    public final int getNumber() {
-      if (this == UNRECOGNIZED) {
-        throw new java.lang.IllegalArgumentException(
-            "Can't get the number of an unknown enum value.");
-      }
-      return value;
-    }
-
-    /**
-     * @param value The number of the enum to look for.
-     * @return The enum associated with the given number.
-     * @deprecated Use {@link #forNumber(int)} instead.
-     */
-    @java.lang.Deprecated
-    public static Kind valueOf(int value) {
-      return forNumber(value);
-    }
-
-    public static Kind forNumber(int value) {
-      switch (value) {
-        case 0: return TYPE_UNKNOWN;
-        case 1: return TYPE_DOUBLE;
-        case 2: return TYPE_FLOAT;
-        case 3: return TYPE_INT64;
-        case 4: return TYPE_UINT64;
-        case 5: return TYPE_INT32;
-        case 6: return TYPE_FIXED64;
-        case 7: return TYPE_FIXED32;
-        case 8: return TYPE_BOOL;
-        case 9: return TYPE_STRING;
-        case 10: return TYPE_GROUP;
-        case 11: return TYPE_MESSAGE;
-        case 12: return TYPE_BYTES;
-        case 13: return TYPE_UINT32;
-        case 14: return TYPE_ENUM;
-        case 15: return TYPE_SFIXED32;
-        case 16: return TYPE_SFIXED64;
-        case 17: return TYPE_SINT32;
-        case 18: return TYPE_SINT64;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<Kind>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        Kind> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<Kind>() {
-            @java.lang.Override
-            public Kind findValueByNumber(int number) {
-              return Kind.forNumber(number);
-            }
-          };
-
-    public static com.google.protobuf.Internal.EnumVerifier 
-        internalGetVerifier() {
-      return KindVerifier.INSTANCE;
-    }
-
-    private static final class KindVerifier implements 
-         com.google.protobuf.Internal.EnumVerifier { 
-            static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new KindVerifier();
-            @java.lang.Override
-            public boolean isInRange(int number) {
-              return Kind.forNumber(number) != null;
-            }
-          };
-
-    private final int value;
-
-    private Kind(int value) {
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:google.protobuf.Field.Kind)
-  }
-
-  /**
-   * <pre>
-   * Whether a field is optional, required, or repeated.
-   * </pre>
-   *
-   * Protobuf enum {@code google.protobuf.Field.Cardinality}
-   */
-  public enum Cardinality
-      implements com.google.protobuf.Internal.EnumLite {
-    /**
-     * <pre>
-     * For fields with unknown cardinality.
-     * </pre>
-     *
-     * <code>CARDINALITY_UNKNOWN = 0;</code>
-     */
-    CARDINALITY_UNKNOWN(0),
-    /**
-     * <pre>
-     * For optional fields.
-     * </pre>
-     *
-     * <code>CARDINALITY_OPTIONAL = 1;</code>
-     */
-    CARDINALITY_OPTIONAL(1),
-    /**
-     * <pre>
-     * For required fields. Proto2 syntax only.
-     * </pre>
-     *
-     * <code>CARDINALITY_REQUIRED = 2;</code>
-     */
-    CARDINALITY_REQUIRED(2),
-    /**
-     * <pre>
-     * For repeated fields.
-     * </pre>
-     *
-     * <code>CARDINALITY_REPEATED = 3;</code>
-     */
-    CARDINALITY_REPEATED(3),
-    UNRECOGNIZED(-1),
-    ;
-
-    /**
-     * <pre>
-     * For fields with unknown cardinality.
-     * </pre>
-     *
-     * <code>CARDINALITY_UNKNOWN = 0;</code>
-     */
-    public static final int CARDINALITY_UNKNOWN_VALUE = 0;
-    /**
-     * <pre>
-     * For optional fields.
-     * </pre>
-     *
-     * <code>CARDINALITY_OPTIONAL = 1;</code>
-     */
-    public static final int CARDINALITY_OPTIONAL_VALUE = 1;
-    /**
-     * <pre>
-     * For required fields. Proto2 syntax only.
-     * </pre>
-     *
-     * <code>CARDINALITY_REQUIRED = 2;</code>
-     */
-    public static final int CARDINALITY_REQUIRED_VALUE = 2;
-    /**
-     * <pre>
-     * For repeated fields.
-     * </pre>
-     *
-     * <code>CARDINALITY_REPEATED = 3;</code>
-     */
-    public static final int CARDINALITY_REPEATED_VALUE = 3;
-
-
-    @java.lang.Override
-    public final int getNumber() {
-      if (this == UNRECOGNIZED) {
-        throw new java.lang.IllegalArgumentException(
-            "Can't get the number of an unknown enum value.");
-      }
-      return value;
-    }
-
-    /**
-     * @param value The number of the enum to look for.
-     * @return The enum associated with the given number.
-     * @deprecated Use {@link #forNumber(int)} instead.
-     */
-    @java.lang.Deprecated
-    public static Cardinality valueOf(int value) {
-      return forNumber(value);
-    }
-
-    public static Cardinality forNumber(int value) {
-      switch (value) {
-        case 0: return CARDINALITY_UNKNOWN;
-        case 1: return CARDINALITY_OPTIONAL;
-        case 2: return CARDINALITY_REQUIRED;
-        case 3: return CARDINALITY_REPEATED;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<Cardinality>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        Cardinality> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<Cardinality>() {
-            @java.lang.Override
-            public Cardinality findValueByNumber(int number) {
-              return Cardinality.forNumber(number);
-            }
-          };
-
-    public static com.google.protobuf.Internal.EnumVerifier 
-        internalGetVerifier() {
-      return CardinalityVerifier.INSTANCE;
-    }
-
-    private static final class CardinalityVerifier implements 
-         com.google.protobuf.Internal.EnumVerifier { 
-            static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new CardinalityVerifier();
-            @java.lang.Override
-            public boolean isInRange(int number) {
-              return Cardinality.forNumber(number) != null;
-            }
-          };
-
-    private final int value;
-
-    private Cardinality(int value) {
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:google.protobuf.Field.Cardinality)
-  }
-
-  public static final int KIND_FIELD_NUMBER = 1;
-  private int kind_;
-  /**
-   * <pre>
-   * The field type.
-   * </pre>
-   *
-   * <code>.google.protobuf.Field.Kind kind = 1;</code>
-   * @return The enum numeric value on the wire for kind.
-   */
-  @java.lang.Override
-  public int getKindValue() {
-    return kind_;
-  }
-  /**
-   * <pre>
-   * The field type.
-   * </pre>
-   *
-   * <code>.google.protobuf.Field.Kind kind = 1;</code>
-   * @return The kind.
-   */
-  @java.lang.Override
-  public com.google.protobuf.Field.Kind getKind() {
-    com.google.protobuf.Field.Kind result = com.google.protobuf.Field.Kind.forNumber(kind_);
-    return result == null ? com.google.protobuf.Field.Kind.UNRECOGNIZED : result;
-  }
-  /**
-   * <pre>
-   * The field type.
-   * </pre>
-   *
-   * <code>.google.protobuf.Field.Kind kind = 1;</code>
-   * @param value The enum numeric value on the wire for kind to set.
-   */
-  private void setKindValue(int value) {
-      kind_ = value;
-  }
-  /**
-   * <pre>
-   * The field type.
-   * </pre>
-   *
-   * <code>.google.protobuf.Field.Kind kind = 1;</code>
-   * @param value The kind to set.
-   */
-  private void setKind(com.google.protobuf.Field.Kind value) {
-    kind_ = value.getNumber();
-    
-  }
-  /**
-   * <pre>
-   * The field type.
-   * </pre>
-   *
-   * <code>.google.protobuf.Field.Kind kind = 1;</code>
-   */
-  private void clearKind() {
-    
-    kind_ = 0;
-  }
-
-  public static final int CARDINALITY_FIELD_NUMBER = 2;
-  private int cardinality_;
-  /**
-   * <pre>
-   * The field cardinality.
-   * </pre>
-   *
-   * <code>.google.protobuf.Field.Cardinality cardinality = 2;</code>
-   * @return The enum numeric value on the wire for cardinality.
-   */
-  @java.lang.Override
-  public int getCardinalityValue() {
-    return cardinality_;
-  }
-  /**
-   * <pre>
-   * The field cardinality.
-   * </pre>
-   *
-   * <code>.google.protobuf.Field.Cardinality cardinality = 2;</code>
-   * @return The cardinality.
-   */
-  @java.lang.Override
-  public com.google.protobuf.Field.Cardinality getCardinality() {
-    com.google.protobuf.Field.Cardinality result = com.google.protobuf.Field.Cardinality.forNumber(cardinality_);
-    return result == null ? com.google.protobuf.Field.Cardinality.UNRECOGNIZED : result;
-  }
-  /**
-   * <pre>
-   * The field cardinality.
-   * </pre>
-   *
-   * <code>.google.protobuf.Field.Cardinality cardinality = 2;</code>
-   * @param value The enum numeric value on the wire for cardinality to set.
-   */
-  private void setCardinalityValue(int value) {
-      cardinality_ = value;
-  }
-  /**
-   * <pre>
-   * The field cardinality.
-   * </pre>
-   *
-   * <code>.google.protobuf.Field.Cardinality cardinality = 2;</code>
-   * @param value The cardinality to set.
-   */
-  private void setCardinality(com.google.protobuf.Field.Cardinality value) {
-    cardinality_ = value.getNumber();
-    
-  }
-  /**
-   * <pre>
-   * The field cardinality.
-   * </pre>
-   *
-   * <code>.google.protobuf.Field.Cardinality cardinality = 2;</code>
-   */
-  private void clearCardinality() {
-    
-    cardinality_ = 0;
-  }
-
-  public static final int NUMBER_FIELD_NUMBER = 3;
-  private int number_;
-  /**
-   * <pre>
-   * The field number.
-   * </pre>
-   *
-   * <code>int32 number = 3;</code>
-   * @return The number.
-   */
-  @java.lang.Override
-  public int getNumber() {
-    return number_;
-  }
-  /**
-   * <pre>
-   * The field number.
-   * </pre>
-   *
-   * <code>int32 number = 3;</code>
-   * @param value The number to set.
-   */
-  private void setNumber(int value) {
-    
-    number_ = value;
-  }
-  /**
-   * <pre>
-   * The field number.
-   * </pre>
-   *
-   * <code>int32 number = 3;</code>
-   */
-  private void clearNumber() {
-    
-    number_ = 0;
-  }
-
-  public static final int NAME_FIELD_NUMBER = 4;
-  private java.lang.String name_;
-  /**
-   * <pre>
-   * The field name.
-   * </pre>
-   *
-   * <code>string name = 4;</code>
-   * @return The name.
-   */
-  @java.lang.Override
-  public java.lang.String getName() {
-    return name_;
-  }
-  /**
-   * <pre>
-   * The field name.
-   * </pre>
-   *
-   * <code>string name = 4;</code>
-   * @return The bytes for name.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getNameBytes() {
-    return com.google.protobuf.ByteString.copyFromUtf8(name_);
-  }
-  /**
-   * <pre>
-   * The field name.
-   * </pre>
-   *
-   * <code>string name = 4;</code>
-   * @param value The name to set.
-   */
-  private void setName(
-      java.lang.String value) {
-    value.getClass();
-  
-    name_ = value;
-  }
-  /**
-   * <pre>
-   * The field name.
-   * </pre>
-   *
-   * <code>string name = 4;</code>
-   */
-  private void clearName() {
-    
-    name_ = getDefaultInstance().getName();
-  }
-  /**
-   * <pre>
-   * The field name.
-   * </pre>
-   *
-   * <code>string name = 4;</code>
-   * @param value The bytes for name to set.
-   */
-  private void setNameBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    name_ = value.toStringUtf8();
-    
-  }
-
-  public static final int TYPE_URL_FIELD_NUMBER = 6;
-  private java.lang.String typeUrl_;
-  /**
-   * <pre>
-   * The field type URL, without the scheme, for message or enumeration
-   * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
-   * </pre>
-   *
-   * <code>string type_url = 6;</code>
-   * @return The typeUrl.
-   */
-  @java.lang.Override
-  public java.lang.String getTypeUrl() {
-    return typeUrl_;
-  }
-  /**
-   * <pre>
-   * The field type URL, without the scheme, for message or enumeration
-   * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
-   * </pre>
-   *
-   * <code>string type_url = 6;</code>
-   * @return The bytes for typeUrl.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getTypeUrlBytes() {
-    return com.google.protobuf.ByteString.copyFromUtf8(typeUrl_);
-  }
-  /**
-   * <pre>
-   * The field type URL, without the scheme, for message or enumeration
-   * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
-   * </pre>
-   *
-   * <code>string type_url = 6;</code>
-   * @param value The typeUrl to set.
-   */
-  private void setTypeUrl(
-      java.lang.String value) {
-    value.getClass();
-  
-    typeUrl_ = value;
-  }
-  /**
-   * <pre>
-   * The field type URL, without the scheme, for message or enumeration
-   * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
-   * </pre>
-   *
-   * <code>string type_url = 6;</code>
-   */
-  private void clearTypeUrl() {
-    
-    typeUrl_ = getDefaultInstance().getTypeUrl();
-  }
-  /**
-   * <pre>
-   * The field type URL, without the scheme, for message or enumeration
-   * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
-   * </pre>
-   *
-   * <code>string type_url = 6;</code>
-   * @param value The bytes for typeUrl to set.
-   */
-  private void setTypeUrlBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    typeUrl_ = value.toStringUtf8();
-    
-  }
-
-  public static final int ONEOF_INDEX_FIELD_NUMBER = 7;
-  private int oneofIndex_;
-  /**
-   * <pre>
-   * The index of the field type in `Type.oneofs`, for message or enumeration
-   * types. The first type has index 1; zero means the type is not in the list.
-   * </pre>
-   *
-   * <code>int32 oneof_index = 7;</code>
-   * @return The oneofIndex.
-   */
-  @java.lang.Override
-  public int getOneofIndex() {
-    return oneofIndex_;
-  }
-  /**
-   * <pre>
-   * The index of the field type in `Type.oneofs`, for message or enumeration
-   * types. The first type has index 1; zero means the type is not in the list.
-   * </pre>
-   *
-   * <code>int32 oneof_index = 7;</code>
-   * @param value The oneofIndex to set.
-   */
-  private void setOneofIndex(int value) {
-    
-    oneofIndex_ = value;
-  }
-  /**
-   * <pre>
-   * The index of the field type in `Type.oneofs`, for message or enumeration
-   * types. The first type has index 1; zero means the type is not in the list.
-   * </pre>
-   *
-   * <code>int32 oneof_index = 7;</code>
-   */
-  private void clearOneofIndex() {
-    
-    oneofIndex_ = 0;
-  }
-
-  public static final int PACKED_FIELD_NUMBER = 8;
-  private boolean packed_;
-  /**
-   * <pre>
-   * Whether to use alternative packed wire representation.
-   * </pre>
-   *
-   * <code>bool packed = 8;</code>
-   * @return The packed.
-   */
-  @java.lang.Override
-  public boolean getPacked() {
-    return packed_;
-  }
-  /**
-   * <pre>
-   * Whether to use alternative packed wire representation.
-   * </pre>
-   *
-   * <code>bool packed = 8;</code>
-   * @param value The packed to set.
-   */
-  private void setPacked(boolean value) {
-    
-    packed_ = value;
-  }
-  /**
-   * <pre>
-   * Whether to use alternative packed wire representation.
-   * </pre>
-   *
-   * <code>bool packed = 8;</code>
-   */
-  private void clearPacked() {
-    
-    packed_ = false;
-  }
-
-  public static final int OPTIONS_FIELD_NUMBER = 9;
-  private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Option> options_;
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 9;</code>
-   */
-  @java.lang.Override
-  public java.util.List<com.google.protobuf.Option> getOptionsList() {
-    return options_;
-  }
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 9;</code>
-   */
-  public java.util.List<? extends com.google.protobuf.OptionOrBuilder> 
-      getOptionsOrBuilderList() {
-    return options_;
-  }
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 9;</code>
-   */
-  @java.lang.Override
-  public int getOptionsCount() {
-    return options_.size();
-  }
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 9;</code>
-   */
-  @java.lang.Override
-  public com.google.protobuf.Option getOptions(int index) {
-    return options_.get(index);
-  }
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 9;</code>
-   */
-  public com.google.protobuf.OptionOrBuilder getOptionsOrBuilder(
-      int index) {
-    return options_.get(index);
-  }
-  private void ensureOptionsIsMutable() {
-    com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Option> tmp = options_;
-    if (!tmp.isModifiable()) {
-      options_ =
-          com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-     }
-  }
-
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 9;</code>
-   */
-  private void setOptions(
-      int index, com.google.protobuf.Option value) {
-    value.getClass();
-  ensureOptionsIsMutable();
-    options_.set(index, value);
-  }
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 9;</code>
-   */
-  private void addOptions(com.google.protobuf.Option value) {
-    value.getClass();
-  ensureOptionsIsMutable();
-    options_.add(value);
-  }
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 9;</code>
-   */
-  private void addOptions(
-      int index, com.google.protobuf.Option value) {
-    value.getClass();
-  ensureOptionsIsMutable();
-    options_.add(index, value);
-  }
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 9;</code>
-   */
-  private void addAllOptions(
-      java.lang.Iterable<? extends com.google.protobuf.Option> values) {
-    ensureOptionsIsMutable();
-    com.google.protobuf.AbstractMessageLite.addAll(
-        values, options_);
-  }
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 9;</code>
-   */
-  private void clearOptions() {
-    options_ = emptyProtobufList();
-  }
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 9;</code>
-   */
-  private void removeOptions(int index) {
-    ensureOptionsIsMutable();
-    options_.remove(index);
-  }
-
-  public static final int JSON_NAME_FIELD_NUMBER = 10;
-  private java.lang.String jsonName_;
-  /**
-   * <pre>
-   * The field JSON name.
-   * </pre>
-   *
-   * <code>string json_name = 10;</code>
-   * @return The jsonName.
-   */
-  @java.lang.Override
-  public java.lang.String getJsonName() {
-    return jsonName_;
-  }
-  /**
-   * <pre>
-   * The field JSON name.
-   * </pre>
-   *
-   * <code>string json_name = 10;</code>
-   * @return The bytes for jsonName.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getJsonNameBytes() {
-    return com.google.protobuf.ByteString.copyFromUtf8(jsonName_);
-  }
-  /**
-   * <pre>
-   * The field JSON name.
-   * </pre>
-   *
-   * <code>string json_name = 10;</code>
-   * @param value The jsonName to set.
-   */
-  private void setJsonName(
-      java.lang.String value) {
-    value.getClass();
-  
-    jsonName_ = value;
-  }
-  /**
-   * <pre>
-   * The field JSON name.
-   * </pre>
-   *
-   * <code>string json_name = 10;</code>
-   */
-  private void clearJsonName() {
-    
-    jsonName_ = getDefaultInstance().getJsonName();
-  }
-  /**
-   * <pre>
-   * The field JSON name.
-   * </pre>
-   *
-   * <code>string json_name = 10;</code>
-   * @param value The bytes for jsonName to set.
-   */
-  private void setJsonNameBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    jsonName_ = value.toStringUtf8();
-    
-  }
-
-  public static final int DEFAULT_VALUE_FIELD_NUMBER = 11;
-  private java.lang.String defaultValue_;
-  /**
-   * <pre>
-   * The string value of the default value of this field. Proto2 syntax only.
-   * </pre>
-   *
-   * <code>string default_value = 11;</code>
-   * @return The defaultValue.
-   */
-  @java.lang.Override
-  public java.lang.String getDefaultValue() {
-    return defaultValue_;
-  }
-  /**
-   * <pre>
-   * The string value of the default value of this field. Proto2 syntax only.
-   * </pre>
-   *
-   * <code>string default_value = 11;</code>
-   * @return The bytes for defaultValue.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getDefaultValueBytes() {
-    return com.google.protobuf.ByteString.copyFromUtf8(defaultValue_);
-  }
-  /**
-   * <pre>
-   * The string value of the default value of this field. Proto2 syntax only.
-   * </pre>
-   *
-   * <code>string default_value = 11;</code>
-   * @param value The defaultValue to set.
-   */
-  private void setDefaultValue(
-      java.lang.String value) {
-    value.getClass();
-  
-    defaultValue_ = value;
-  }
-  /**
-   * <pre>
-   * The string value of the default value of this field. Proto2 syntax only.
-   * </pre>
-   *
-   * <code>string default_value = 11;</code>
-   */
-  private void clearDefaultValue() {
-    
-    defaultValue_ = getDefaultInstance().getDefaultValue();
-  }
-  /**
-   * <pre>
-   * The string value of the default value of this field. Proto2 syntax only.
-   * </pre>
-   *
-   * <code>string default_value = 11;</code>
-   * @param value The bytes for defaultValue to set.
-   */
-  private void setDefaultValueBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    defaultValue_ = value.toStringUtf8();
-    
-  }
-
-  public static com.google.protobuf.Field parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Field parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Field parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Field parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Field parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Field parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Field parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Field parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Field parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Field parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Field parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Field parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.Field prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * A single field of a message type.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.Field}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.Field, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.Field)
-      com.google.protobuf.FieldOrBuilder {
-    // Construct using com.google.protobuf.Field.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * The field type.
-     * </pre>
-     *
-     * <code>.google.protobuf.Field.Kind kind = 1;</code>
-     * @return The enum numeric value on the wire for kind.
-     */
-    @java.lang.Override
-    public int getKindValue() {
-      return instance.getKindValue();
-    }
-    /**
-     * <pre>
-     * The field type.
-     * </pre>
-     *
-     * <code>.google.protobuf.Field.Kind kind = 1;</code>
-     * @param value The kind to set.
-     * @return This builder for chaining.
-     */
-    public Builder setKindValue(int value) {
-      copyOnWrite();
-      instance.setKindValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The field type.
-     * </pre>
-     *
-     * <code>.google.protobuf.Field.Kind kind = 1;</code>
-     * @return The kind.
-     */
-    @java.lang.Override
-    public com.google.protobuf.Field.Kind getKind() {
-      return instance.getKind();
-    }
-    /**
-     * <pre>
-     * The field type.
-     * </pre>
-     *
-     * <code>.google.protobuf.Field.Kind kind = 1;</code>
-     * @param value The enum numeric value on the wire for kind to set.
-     * @return This builder for chaining.
-     */
-    public Builder setKind(com.google.protobuf.Field.Kind value) {
-      copyOnWrite();
-      instance.setKind(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The field type.
-     * </pre>
-     *
-     * <code>.google.protobuf.Field.Kind kind = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearKind() {
-      copyOnWrite();
-      instance.clearKind();
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The field cardinality.
-     * </pre>
-     *
-     * <code>.google.protobuf.Field.Cardinality cardinality = 2;</code>
-     * @return The enum numeric value on the wire for cardinality.
-     */
-    @java.lang.Override
-    public int getCardinalityValue() {
-      return instance.getCardinalityValue();
-    }
-    /**
-     * <pre>
-     * The field cardinality.
-     * </pre>
-     *
-     * <code>.google.protobuf.Field.Cardinality cardinality = 2;</code>
-     * @param value The cardinality to set.
-     * @return This builder for chaining.
-     */
-    public Builder setCardinalityValue(int value) {
-      copyOnWrite();
-      instance.setCardinalityValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The field cardinality.
-     * </pre>
-     *
-     * <code>.google.protobuf.Field.Cardinality cardinality = 2;</code>
-     * @return The cardinality.
-     */
-    @java.lang.Override
-    public com.google.protobuf.Field.Cardinality getCardinality() {
-      return instance.getCardinality();
-    }
-    /**
-     * <pre>
-     * The field cardinality.
-     * </pre>
-     *
-     * <code>.google.protobuf.Field.Cardinality cardinality = 2;</code>
-     * @param value The enum numeric value on the wire for cardinality to set.
-     * @return This builder for chaining.
-     */
-    public Builder setCardinality(com.google.protobuf.Field.Cardinality value) {
-      copyOnWrite();
-      instance.setCardinality(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The field cardinality.
-     * </pre>
-     *
-     * <code>.google.protobuf.Field.Cardinality cardinality = 2;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearCardinality() {
-      copyOnWrite();
-      instance.clearCardinality();
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The field number.
-     * </pre>
-     *
-     * <code>int32 number = 3;</code>
-     * @return The number.
-     */
-    @java.lang.Override
-    public int getNumber() {
-      return instance.getNumber();
-    }
-    /**
-     * <pre>
-     * The field number.
-     * </pre>
-     *
-     * <code>int32 number = 3;</code>
-     * @param value The number to set.
-     * @return This builder for chaining.
-     */
-    public Builder setNumber(int value) {
-      copyOnWrite();
-      instance.setNumber(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The field number.
-     * </pre>
-     *
-     * <code>int32 number = 3;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearNumber() {
-      copyOnWrite();
-      instance.clearNumber();
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The field name.
-     * </pre>
-     *
-     * <code>string name = 4;</code>
-     * @return The name.
-     */
-    @java.lang.Override
-    public java.lang.String getName() {
-      return instance.getName();
-    }
-    /**
-     * <pre>
-     * The field name.
-     * </pre>
-     *
-     * <code>string name = 4;</code>
-     * @return The bytes for name.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getNameBytes() {
-      return instance.getNameBytes();
-    }
-    /**
-     * <pre>
-     * The field name.
-     * </pre>
-     *
-     * <code>string name = 4;</code>
-     * @param value The name to set.
-     * @return This builder for chaining.
-     */
-    public Builder setName(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.setName(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The field name.
-     * </pre>
-     *
-     * <code>string name = 4;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearName() {
-      copyOnWrite();
-      instance.clearName();
-      return this;
-    }
-    /**
-     * <pre>
-     * The field name.
-     * </pre>
-     *
-     * <code>string name = 4;</code>
-     * @param value The bytes for name to set.
-     * @return This builder for chaining.
-     */
-    public Builder setNameBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setNameBytes(value);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The field type URL, without the scheme, for message or enumeration
-     * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
-     * </pre>
-     *
-     * <code>string type_url = 6;</code>
-     * @return The typeUrl.
-     */
-    @java.lang.Override
-    public java.lang.String getTypeUrl() {
-      return instance.getTypeUrl();
-    }
-    /**
-     * <pre>
-     * The field type URL, without the scheme, for message or enumeration
-     * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
-     * </pre>
-     *
-     * <code>string type_url = 6;</code>
-     * @return The bytes for typeUrl.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getTypeUrlBytes() {
-      return instance.getTypeUrlBytes();
-    }
-    /**
-     * <pre>
-     * The field type URL, without the scheme, for message or enumeration
-     * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
-     * </pre>
-     *
-     * <code>string type_url = 6;</code>
-     * @param value The typeUrl to set.
-     * @return This builder for chaining.
-     */
-    public Builder setTypeUrl(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.setTypeUrl(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The field type URL, without the scheme, for message or enumeration
-     * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
-     * </pre>
-     *
-     * <code>string type_url = 6;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearTypeUrl() {
-      copyOnWrite();
-      instance.clearTypeUrl();
-      return this;
-    }
-    /**
-     * <pre>
-     * The field type URL, without the scheme, for message or enumeration
-     * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
-     * </pre>
-     *
-     * <code>string type_url = 6;</code>
-     * @param value The bytes for typeUrl to set.
-     * @return This builder for chaining.
-     */
-    public Builder setTypeUrlBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setTypeUrlBytes(value);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The index of the field type in `Type.oneofs`, for message or enumeration
-     * types. The first type has index 1; zero means the type is not in the list.
-     * </pre>
-     *
-     * <code>int32 oneof_index = 7;</code>
-     * @return The oneofIndex.
-     */
-    @java.lang.Override
-    public int getOneofIndex() {
-      return instance.getOneofIndex();
-    }
-    /**
-     * <pre>
-     * The index of the field type in `Type.oneofs`, for message or enumeration
-     * types. The first type has index 1; zero means the type is not in the list.
-     * </pre>
-     *
-     * <code>int32 oneof_index = 7;</code>
-     * @param value The oneofIndex to set.
-     * @return This builder for chaining.
-     */
-    public Builder setOneofIndex(int value) {
-      copyOnWrite();
-      instance.setOneofIndex(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The index of the field type in `Type.oneofs`, for message or enumeration
-     * types. The first type has index 1; zero means the type is not in the list.
-     * </pre>
-     *
-     * <code>int32 oneof_index = 7;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearOneofIndex() {
-      copyOnWrite();
-      instance.clearOneofIndex();
-      return this;
-    }
-
-    /**
-     * <pre>
-     * Whether to use alternative packed wire representation.
-     * </pre>
-     *
-     * <code>bool packed = 8;</code>
-     * @return The packed.
-     */
-    @java.lang.Override
-    public boolean getPacked() {
-      return instance.getPacked();
-    }
-    /**
-     * <pre>
-     * Whether to use alternative packed wire representation.
-     * </pre>
-     *
-     * <code>bool packed = 8;</code>
-     * @param value The packed to set.
-     * @return This builder for chaining.
-     */
-    public Builder setPacked(boolean value) {
-      copyOnWrite();
-      instance.setPacked(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Whether to use alternative packed wire representation.
-     * </pre>
-     *
-     * <code>bool packed = 8;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearPacked() {
-      copyOnWrite();
-      instance.clearPacked();
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 9;</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.Option> getOptionsList() {
-      return java.util.Collections.unmodifiableList(
-          instance.getOptionsList());
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 9;</code>
-     */
-    @java.lang.Override
-    public int getOptionsCount() {
-      return instance.getOptionsCount();
-    }/**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 9;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.Option getOptions(int index) {
-      return instance.getOptions(index);
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 9;</code>
-     */
-    public Builder setOptions(
-        int index, com.google.protobuf.Option value) {
-      copyOnWrite();
-      instance.setOptions(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 9;</code>
-     */
-    public Builder setOptions(
-        int index, com.google.protobuf.Option.Builder builderForValue) {
-      copyOnWrite();
-      instance.setOptions(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 9;</code>
-     */
-    public Builder addOptions(com.google.protobuf.Option value) {
-      copyOnWrite();
-      instance.addOptions(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 9;</code>
-     */
-    public Builder addOptions(
-        int index, com.google.protobuf.Option value) {
-      copyOnWrite();
-      instance.addOptions(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 9;</code>
-     */
-    public Builder addOptions(
-        com.google.protobuf.Option.Builder builderForValue) {
-      copyOnWrite();
-      instance.addOptions(builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 9;</code>
-     */
-    public Builder addOptions(
-        int index, com.google.protobuf.Option.Builder builderForValue) {
-      copyOnWrite();
-      instance.addOptions(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 9;</code>
-     */
-    public Builder addAllOptions(
-        java.lang.Iterable<? extends com.google.protobuf.Option> values) {
-      copyOnWrite();
-      instance.addAllOptions(values);
-      return this;
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 9;</code>
-     */
-    public Builder clearOptions() {
-      copyOnWrite();
-      instance.clearOptions();
-      return this;
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 9;</code>
-     */
-    public Builder removeOptions(int index) {
-      copyOnWrite();
-      instance.removeOptions(index);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The field JSON name.
-     * </pre>
-     *
-     * <code>string json_name = 10;</code>
-     * @return The jsonName.
-     */
-    @java.lang.Override
-    public java.lang.String getJsonName() {
-      return instance.getJsonName();
-    }
-    /**
-     * <pre>
-     * The field JSON name.
-     * </pre>
-     *
-     * <code>string json_name = 10;</code>
-     * @return The bytes for jsonName.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getJsonNameBytes() {
-      return instance.getJsonNameBytes();
-    }
-    /**
-     * <pre>
-     * The field JSON name.
-     * </pre>
-     *
-     * <code>string json_name = 10;</code>
-     * @param value The jsonName to set.
-     * @return This builder for chaining.
-     */
-    public Builder setJsonName(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.setJsonName(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The field JSON name.
-     * </pre>
-     *
-     * <code>string json_name = 10;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearJsonName() {
-      copyOnWrite();
-      instance.clearJsonName();
-      return this;
-    }
-    /**
-     * <pre>
-     * The field JSON name.
-     * </pre>
-     *
-     * <code>string json_name = 10;</code>
-     * @param value The bytes for jsonName to set.
-     * @return This builder for chaining.
-     */
-    public Builder setJsonNameBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setJsonNameBytes(value);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The string value of the default value of this field. Proto2 syntax only.
-     * </pre>
-     *
-     * <code>string default_value = 11;</code>
-     * @return The defaultValue.
-     */
-    @java.lang.Override
-    public java.lang.String getDefaultValue() {
-      return instance.getDefaultValue();
-    }
-    /**
-     * <pre>
-     * The string value of the default value of this field. Proto2 syntax only.
-     * </pre>
-     *
-     * <code>string default_value = 11;</code>
-     * @return The bytes for defaultValue.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getDefaultValueBytes() {
-      return instance.getDefaultValueBytes();
-    }
-    /**
-     * <pre>
-     * The string value of the default value of this field. Proto2 syntax only.
-     * </pre>
-     *
-     * <code>string default_value = 11;</code>
-     * @param value The defaultValue to set.
-     * @return This builder for chaining.
-     */
-    public Builder setDefaultValue(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.setDefaultValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The string value of the default value of this field. Proto2 syntax only.
-     * </pre>
-     *
-     * <code>string default_value = 11;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearDefaultValue() {
-      copyOnWrite();
-      instance.clearDefaultValue();
-      return this;
-    }
-    /**
-     * <pre>
-     * The string value of the default value of this field. Proto2 syntax only.
-     * </pre>
-     *
-     * <code>string default_value = 11;</code>
-     * @param value The bytes for defaultValue to set.
-     * @return This builder for chaining.
-     */
-    public Builder setDefaultValueBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setDefaultValueBytes(value);
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.Field)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.Field();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "kind_",
-            "cardinality_",
-            "number_",
-            "name_",
-            "typeUrl_",
-            "oneofIndex_",
-            "packed_",
-            "options_",
-            com.google.protobuf.Option.class,
-            "jsonName_",
-            "defaultValue_",
-          };
-          java.lang.String info =
-              "\u0000\n\u0000\u0000\u0001\u000b\n\u0000\u0001\u0000\u0001\f\u0002\f\u0003\u0004" +
-              "\u0004\u0208\u0006\u0208\u0007\u0004\b\u0007\t\u001b\n\u0208\u000b\u0208";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.Field> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.Field.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.Field>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.Field)
-  private static final com.google.protobuf.Field DEFAULT_INSTANCE;
-  static {
-    Field defaultInstance = new Field();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      Field.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.Field getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<Field> PARSER;
-
-  public static com.google.protobuf.Parser<Field> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldInfo.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldInfo.java
deleted file mode 100644
index 71a307a..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldInfo.java
+++ /dev/null
@@ -1,577 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.Internal.checkNotNull;
-
-import com.google.protobuf.Internal.EnumVerifier;
-import java.lang.reflect.Field;
-
-/** Information for a single field in a protobuf message class. */
-@ExperimentalApi
-final class FieldInfo implements Comparable<FieldInfo> {
-  private final Field field;
-  private final FieldType type;
-  private final Class<?> messageClass; // The message type for repeated message fields.
-  private final int fieldNumber;
-  private final Field presenceField;
-  private final int presenceMask;
-  private final boolean required;
-  private final boolean enforceUtf8;
-  private final OneofInfo oneof;
-  private final Field cachedSizeField;
-  /**
-   * The actual type stored in the oneof value for this field. Since the oneof value is an {@link
-   * Object}, primitives will store their boxed type. Only valid in conjunction with {@link #oneof}
-   * (both must be either null or non-null.
-   */
-  private final Class<?> oneofStoredType;
-
-  // TODO(liujisi): make map default entry lazy?
-  private final Object mapDefaultEntry;
-
-  private final EnumVerifier enumVerifier;
-
-  /** Constructs a new descriptor for a field. */
-  public static FieldInfo forField(
-      Field field, int fieldNumber, FieldType fieldType, boolean enforceUtf8) {
-    checkFieldNumber(fieldNumber);
-    checkNotNull(field, "field");
-    checkNotNull(fieldType, "fieldType");
-    if (fieldType == FieldType.MESSAGE_LIST || fieldType == FieldType.GROUP_LIST) {
-      throw new IllegalStateException("Shouldn't be called for repeated message fields.");
-    }
-    return new FieldInfo(
-        field,
-        fieldNumber,
-        fieldType,
-        /* messageClass= */ null,
-        /* presenceField= */ null,
-        /* presenceMask= */ 0,
-        /* required= */ false,
-        enforceUtf8,
-        /* oneof= */ null,
-        /* oneofStoredType= */ null,
-        /* mapDefaultEntry= */ null,
-        /* enumVerifier= */ null,
-        /* cachedSizeField= */ null);
-  }
-
-  /** Constructs a new descriptor for a packed field. */
-  public static FieldInfo forPackedField(
-      Field field, int fieldNumber, FieldType fieldType, Field cachedSizeField) {
-    checkFieldNumber(fieldNumber);
-    checkNotNull(field, "field");
-    checkNotNull(fieldType, "fieldType");
-    if (fieldType == FieldType.MESSAGE_LIST || fieldType == FieldType.GROUP_LIST) {
-      throw new IllegalStateException("Shouldn't be called for repeated message fields.");
-    }
-    return new FieldInfo(
-        field,
-        fieldNumber,
-        fieldType,
-        /* messageClass= */ null,
-        /* presenceField= */ null,
-        /* presenceMask= */ 0,
-        /* required= */ false,
-        /* enforceUtf8= */ false,
-        /* oneof= */ null,
-        /* oneofStoredType= */ null,
-        /* mapDefaultEntry= */ null,
-        /* enumVerifier= */ null,
-        cachedSizeField);
-  }
-
-  /** Constructs a new descriptor for a repeated message field. */
-  public static FieldInfo forRepeatedMessageField(
-      Field field, int fieldNumber, FieldType fieldType, Class<?> messageClass) {
-    checkFieldNumber(fieldNumber);
-    checkNotNull(field, "field");
-    checkNotNull(fieldType, "fieldType");
-    checkNotNull(messageClass, "messageClass");
-    return new FieldInfo(
-        field,
-        fieldNumber,
-        fieldType,
-        messageClass,
-        /* presenceField= */ null,
-        /* presenceMask= */ 0,
-        /* required= */ false,
-        /* enforceUtf8= */ false,
-        /* oneof= */ null,
-        /* oneofStoredType= */ null,
-        /* mapDefaultEntry= */ null,
-        /* enumVerifier= */ null,
-        /* cachedSizeField= */ null);
-  }
-
-  public static FieldInfo forFieldWithEnumVerifier(
-      Field field, int fieldNumber, FieldType fieldType, EnumVerifier enumVerifier) {
-    checkFieldNumber(fieldNumber);
-    checkNotNull(field, "field");
-    return new FieldInfo(
-        field,
-        fieldNumber,
-        fieldType,
-        /* messageClass= */ null,
-        /* presenceField= */ null,
-        /* presenceMask= */ 0,
-        /* required= */ false,
-        /* enforceUtf8= */ false,
-        /* oneof= */ null,
-        /* oneofStoredType= */ null,
-        /* mapDefaultEntry= */ null,
-        enumVerifier,
-        /* cachedSizeField= */ null);
-  }
-
-  public static FieldInfo forPackedFieldWithEnumVerifier(
-      Field field,
-      int fieldNumber,
-      FieldType fieldType,
-      EnumVerifier enumVerifier,
-      Field cachedSizeField) {
-    checkFieldNumber(fieldNumber);
-    checkNotNull(field, "field");
-    return new FieldInfo(
-        field,
-        fieldNumber,
-        fieldType,
-        /* messageClass= */ null,
-        /* presenceField= */ null,
-        /* presenceMask= */ 0,
-        /* required= */ false,
-        /* enforceUtf8= */ false,
-        /* oneof= */ null,
-        /* oneofStoredType= */ null,
-        /* mapDefaultEntry= */ null,
-        enumVerifier,
-        cachedSizeField);
-  }
-
-  /** Constructor for a proto2 optional field. */
-  public static FieldInfo forProto2OptionalField(
-      Field field,
-      int fieldNumber,
-      FieldType fieldType,
-      Field presenceField,
-      int presenceMask,
-      boolean enforceUtf8,
-      EnumVerifier enumVerifier) {
-    checkFieldNumber(fieldNumber);
-    checkNotNull(field, "field");
-    checkNotNull(fieldType, "fieldType");
-    checkNotNull(presenceField, "presenceField");
-    if (presenceField != null && !isExactlyOneBitSet(presenceMask)) {
-      throw new IllegalArgumentException(
-          "presenceMask must have exactly one bit set: " + presenceMask);
-    }
-    return new FieldInfo(
-        field,
-        fieldNumber,
-        fieldType,
-        /* messageClass= */ null,
-        presenceField,
-        presenceMask,
-        /* required= */ false,
-        enforceUtf8,
-        /* oneof= */ null,
-        /* oneofStoredType= */ null,
-        /* mapDefaultEntry= */ null,
-        enumVerifier,
-        /* cachedSizeField= */ null);
-  }
-
-  /**
-   * Constructor for a field that is part of a oneof.
-   *
-   * @param fieldNumber the unique field number for this field within the message.
-   * @param fieldType the type of the field (must be non-null).
-   * @param oneof the oneof for which this field is associated (must be non-null).
-   * @param oneofStoredType the actual type stored in the oneof value for this field. Since the
-   *     oneof value is an {@link Object}, primitives will store their boxed type. Must be non-null.
-   * @param enforceUtf8 Only used for string fields. If {@code true}, will enforce UTF-8 on a string
-   *     field.
-   * @return the {@link FieldInfo} describing this field.
-   */
-  public static FieldInfo forOneofMemberField(
-      int fieldNumber,
-      FieldType fieldType,
-      OneofInfo oneof,
-      Class<?> oneofStoredType,
-      boolean enforceUtf8,
-      EnumVerifier enumVerifier) {
-    checkFieldNumber(fieldNumber);
-    checkNotNull(fieldType, "fieldType");
-    checkNotNull(oneof, "oneof");
-    checkNotNull(oneofStoredType, "oneofStoredType");
-    if (!fieldType.isScalar()) {
-      throw new IllegalArgumentException(
-          "Oneof is only supported for scalar fields. Field "
-              + fieldNumber
-              + " is of type "
-              + fieldType);
-    }
-    return new FieldInfo(
-        /* field= */ null,
-        fieldNumber,
-        fieldType,
-        /* messageClass= */ null,
-        /* presenceField= */ null,
-        /* presenceMask= */ 0,
-        /* required= */ false,
-        enforceUtf8,
-        oneof,
-        oneofStoredType,
-        /* mapDefaultEntry= */ null,
-        enumVerifier,
-        /* cachedSizeField= */ null);
-  }
-
-  private static void checkFieldNumber(int fieldNumber) {
-    if (fieldNumber <= 0) {
-      throw new IllegalArgumentException("fieldNumber must be positive: " + fieldNumber);
-    }
-  }
-
-  /** Constructor for a proto2 required field. */
-  public static FieldInfo forProto2RequiredField(
-      Field field,
-      int fieldNumber,
-      FieldType fieldType,
-      Field presenceField,
-      int presenceMask,
-      boolean enforceUtf8,
-      EnumVerifier enumVerifier) {
-    checkFieldNumber(fieldNumber);
-    checkNotNull(field, "field");
-    checkNotNull(fieldType, "fieldType");
-    checkNotNull(presenceField, "presenceField");
-    if (presenceField != null && !isExactlyOneBitSet(presenceMask)) {
-      throw new IllegalArgumentException(
-          "presenceMask must have exactly one bit set: " + presenceMask);
-    }
-    return new FieldInfo(
-        field,
-        fieldNumber,
-        fieldType,
-        /* messageClass= */ null,
-        presenceField,
-        presenceMask,
-        /* required= */ true,
-        enforceUtf8,
-        /* oneof= */ null,
-        /* oneofStoredType= */ null,
-        /* mapDefaultEntry= */ null,
-        /* enumVerifier= */ enumVerifier,
-        /* cachedSizeField= */ null);
-  }
-
-  public static FieldInfo forMapField(
-      Field field, int fieldNumber, Object mapDefaultEntry, EnumVerifier enumVerifier) {
-    checkNotNull(mapDefaultEntry, "mapDefaultEntry");
-    checkFieldNumber(fieldNumber);
-    checkNotNull(field, "field");
-    return new FieldInfo(
-        field,
-        fieldNumber,
-        FieldType.MAP,
-        /* messageClass= */ null,
-        /* presenceField= */ null,
-        /* presenceMask= */ 0,
-        /* required= */ false,
-        /* enforceUtf8= */ true,
-        /* oneof= */ null,
-        /* oneofStoredType= */ null,
-        mapDefaultEntry,
-        enumVerifier,
-        /* cachedSizeField= */ null);
-  }
-
-  private FieldInfo(
-      Field field,
-      int fieldNumber,
-      FieldType type,
-      Class<?> messageClass,
-      Field presenceField,
-      int presenceMask,
-      boolean required,
-      boolean enforceUtf8,
-      OneofInfo oneof,
-      Class<?> oneofStoredType,
-      Object mapDefaultEntry,
-      EnumVerifier enumVerifier,
-      Field cachedSizeField) {
-    this.field = field;
-    this.type = type;
-    this.messageClass = messageClass;
-    this.fieldNumber = fieldNumber;
-    this.presenceField = presenceField;
-    this.presenceMask = presenceMask;
-    this.required = required;
-    this.enforceUtf8 = enforceUtf8;
-    this.oneof = oneof;
-    this.oneofStoredType = oneofStoredType;
-    this.mapDefaultEntry = mapDefaultEntry;
-    this.enumVerifier = enumVerifier;
-    this.cachedSizeField = cachedSizeField;
-  }
-
-  /** Gets the field number for the field. */
-  public int getFieldNumber() {
-    return fieldNumber;
-  }
-
-  /** Gets the subject {@link Field} of this descriptor. */
-  public Field getField() {
-    return field;
-  }
-
-  /** Gets the type information for the field. */
-  public FieldType getType() {
-    return type;
-  }
-
-  /** Gets the oneof for which this field is a member, or {@code null} if not part of a oneof. */
-  public OneofInfo getOneof() {
-    return oneof;
-  }
-
-  /**
-   * Gets the actual type stored in the oneof value by this field. Since the oneof value is an
-   * {@link Object}, primitives will store their boxed type. For non-oneof fields, this will always
-   * be {@code null}.
-   */
-  public Class<?> getOneofStoredType() {
-    return oneofStoredType;
-  }
-
-  /** Gets the {@code EnumVerifier} if the field is an enum field. */
-  public EnumVerifier getEnumVerifier() {
-    return enumVerifier;
-  }
-
-  @Override
-  public int compareTo(FieldInfo o) {
-    return fieldNumber - o.fieldNumber;
-  }
-
-  /**
-   * For repeated message fields, returns the message type of the field. For other fields, returns
-   * {@code null}.
-   */
-  public Class<?> getListElementType() {
-    return messageClass;
-  }
-
-  /** Gets the presence bit field. Only valid for unary fields. For lists, returns {@code null}. */
-  public Field getPresenceField() {
-    return presenceField;
-  }
-
-  public Object getMapDefaultEntry() {
-    return mapDefaultEntry;
-  }
-
-  /**
-   * If {@link #getPresenceField()} is non-{@code null}, returns the mask used to identify the
-   * presence bit for this field in the message.
-   */
-  public int getPresenceMask() {
-    return presenceMask;
-  }
-
-  /** Whether this is a required field. */
-  public boolean isRequired() {
-    return required;
-  }
-
-  /**
-   * Whether a UTF-8 should be enforced on string fields. Only applies to strings and string lists.
-   */
-  public boolean isEnforceUtf8() {
-    return enforceUtf8;
-  }
-
-  public Field getCachedSizeField() {
-    return cachedSizeField;
-  }
-
-  /**
-   * For singular or repeated message fields, returns the message type. For other fields, returns
-   * {@code null}.
-   */
-  public Class<?> getMessageFieldClass() {
-    switch (type) {
-      case MESSAGE:
-      case GROUP:
-        return field != null ? field.getType() : oneofStoredType;
-      case MESSAGE_LIST:
-      case GROUP_LIST:
-        return messageClass;
-      default:
-        return null;
-    }
-  }
-
-  public static Builder newBuilder() {
-    return new Builder();
-  }
-
-  /** A builder for {@link FieldInfo} instances. */
-  public static final class Builder {
-    private Field field;
-    private FieldType type;
-    private int fieldNumber;
-    private Field presenceField;
-    private int presenceMask;
-    private boolean required;
-    private boolean enforceUtf8;
-    private OneofInfo oneof;
-    private Class<?> oneofStoredType;
-    private Object mapDefaultEntry;
-    private EnumVerifier enumVerifier;
-    private Field cachedSizeField;
-
-    private Builder() {}
-
-    /**
-     * Specifies the actual field on the message represented by this field. This should not be
-     * called for oneof member fields.
-     */
-    public Builder withField(Field field) {
-      if (oneof != null) {
-        throw new IllegalStateException("Cannot set field when building a oneof.");
-      }
-      this.field = field;
-      return this;
-    }
-
-    /** Specifies the type of this field. */
-    public Builder withType(FieldType type) {
-      this.type = type;
-      return this;
-    }
-
-    /** Specifies the unique field number for this field within the message. */
-    public Builder withFieldNumber(int fieldNumber) {
-      this.fieldNumber = fieldNumber;
-      return this;
-    }
-
-    /** Specifies proto2 presence information. This should not be called for oneof fields. */
-    public Builder withPresence(Field presenceField, int presenceMask) {
-      this.presenceField = checkNotNull(presenceField, "presenceField");
-      this.presenceMask = presenceMask;
-      return this;
-    }
-
-    /**
-     * Sets the information for building a oneof member field. This is incompatible with {@link
-     * #withField(Field)} and {@link #withPresence(Field, int)}.
-     *
-     * @param oneof the oneof for which this field is associated.
-     * @param oneofStoredType the actual type stored in the oneof value for this field. Since the
-     *     oneof value is an {@link Object}, primitives will store their boxed type.
-     */
-    public Builder withOneof(OneofInfo oneof, Class<?> oneofStoredType) {
-      if (field != null || presenceField != null) {
-        throw new IllegalStateException(
-            "Cannot set oneof when field or presenceField have been provided");
-      }
-      this.oneof = oneof;
-      this.oneofStoredType = oneofStoredType;
-      return this;
-    }
-
-    public Builder withRequired(boolean required) {
-      this.required = required;
-      return this;
-    }
-
-    public Builder withMapDefaultEntry(Object mapDefaultEntry) {
-      this.mapDefaultEntry = mapDefaultEntry;
-      return this;
-    }
-
-    public Builder withEnforceUtf8(boolean enforceUtf8) {
-      this.enforceUtf8 = enforceUtf8;
-      return this;
-    }
-
-    public Builder withEnumVerifier(EnumVerifier enumVerifier) {
-      this.enumVerifier = enumVerifier;
-      return this;
-    }
-
-    public Builder withCachedSizeField(Field cachedSizeField) {
-      this.cachedSizeField = cachedSizeField;
-      return this;
-    }
-
-    public FieldInfo build() {
-      if (oneof != null) {
-        return forOneofMemberField(
-            fieldNumber, type, oneof, oneofStoredType, enforceUtf8, enumVerifier);
-      }
-      if (mapDefaultEntry != null) {
-        return forMapField(field, fieldNumber, mapDefaultEntry, enumVerifier);
-      }
-      if (presenceField != null) {
-        if (required) {
-          return forProto2RequiredField(
-              field, fieldNumber, type, presenceField, presenceMask, enforceUtf8, enumVerifier);
-        } else {
-          return forProto2OptionalField(
-              field, fieldNumber, type, presenceField, presenceMask, enforceUtf8, enumVerifier);
-        }
-      }
-      if (enumVerifier != null) {
-        if (cachedSizeField == null) {
-          return forFieldWithEnumVerifier(field, fieldNumber, type, enumVerifier);
-        } else {
-          return forPackedFieldWithEnumVerifier(
-              field, fieldNumber, type, enumVerifier, cachedSizeField);
-        }
-      } else {
-        if (cachedSizeField == null) {
-          return forField(field, fieldNumber, type, enforceUtf8);
-        } else {
-          return forPackedField(field, fieldNumber, type, cachedSizeField);
-        }
-      }
-    }
-  }
-
-  private static boolean isExactlyOneBitSet(int value) {
-    return value != 0 && (value & (value - 1)) == 0;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldMask.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldMask.java
deleted file mode 100644
index 1e02662..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldMask.java
+++ /dev/null
@@ -1,750 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/field_mask.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * `FieldMask` represents a set of symbolic field paths, for example:
- *     paths: "f.a"
- *     paths: "f.b.d"
- * Here `f` represents a field in some root message, `a` and `b`
- * fields in the message found in `f`, and `d` a field found in the
- * message in `f.b`.
- * Field masks are used to specify a subset of fields that should be
- * returned by a get operation or modified by an update operation.
- * Field masks also have a custom JSON encoding (see below).
- * # Field Masks in Projections
- * When used in the context of a projection, a response message or
- * sub-message is filtered by the API to only contain those fields as
- * specified in the mask. For example, if the mask in the previous
- * example is applied to a response message as follows:
- *     f {
- *       a : 22
- *       b {
- *         d : 1
- *         x : 2
- *       }
- *       y : 13
- *     }
- *     z: 8
- * The result will not contain specific values for fields x,y and z
- * (their value will be set to the default, and omitted in proto text
- * output):
- *     f {
- *       a : 22
- *       b {
- *         d : 1
- *       }
- *     }
- * A repeated field is not allowed except at the last position of a
- * paths string.
- * If a FieldMask object is not present in a get operation, the
- * operation applies to all fields (as if a FieldMask of all fields
- * had been specified).
- * Note that a field mask does not necessarily apply to the
- * top-level response message. In case of a REST get operation, the
- * field mask applies directly to the response, but in case of a REST
- * list operation, the mask instead applies to each individual message
- * in the returned resource list. In case of a REST custom method,
- * other definitions may be used. Where the mask applies will be
- * clearly documented together with its declaration in the API.  In
- * any case, the effect on the returned resource/resources is required
- * behavior for APIs.
- * # Field Masks in Update Operations
- * A field mask in update operations specifies which fields of the
- * targeted resource are going to be updated. The API is required
- * to only change the values of the fields as specified in the mask
- * and leave the others untouched. If a resource is passed in to
- * describe the updated values, the API ignores the values of all
- * fields not covered by the mask.
- * If a repeated field is specified for an update operation, new values will
- * be appended to the existing repeated field in the target resource. Note that
- * a repeated field is only allowed in the last position of a `paths` string.
- * If a sub-message is specified in the last position of the field mask for an
- * update operation, then new value will be merged into the existing sub-message
- * in the target resource.
- * For example, given the target message:
- *     f {
- *       b {
- *         d: 1
- *         x: 2
- *       }
- *       c: [1]
- *     }
- * And an update message:
- *     f {
- *       b {
- *         d: 10
- *       }
- *       c: [2]
- *     }
- * then if the field mask is:
- *  paths: ["f.b", "f.c"]
- * then the result will be:
- *     f {
- *       b {
- *         d: 10
- *         x: 2
- *       }
- *       c: [1, 2]
- *     }
- * An implementation may provide options to override this default behavior for
- * repeated and message fields.
- * In order to reset a field's value to the default, the field must
- * be in the mask and set to the default value in the provided resource.
- * Hence, in order to reset all fields of a resource, provide a default
- * instance of the resource and set all fields in the mask, or do
- * not provide a mask as described below.
- * If a field mask is not present on update, the operation applies to
- * all fields (as if a field mask of all fields has been specified).
- * Note that in the presence of schema evolution, this may mean that
- * fields the client does not know and has therefore not filled into
- * the request will be reset to their default. If this is unwanted
- * behavior, a specific service may require a client to always specify
- * a field mask, producing an error if not.
- * As with get operations, the location of the resource which
- * describes the updated values in the request message depends on the
- * operation kind. In any case, the effect of the field mask is
- * required to be honored by the API.
- * ## Considerations for HTTP REST
- * The HTTP kind of an update operation which uses a field mask must
- * be set to PATCH instead of PUT in order to satisfy HTTP semantics
- * (PUT must only be used for full updates).
- * # JSON Encoding of Field Masks
- * In JSON, a field mask is encoded as a single string where paths are
- * separated by a comma. Fields name in each path are converted
- * to/from lower-camel naming conventions.
- * As an example, consider the following message declarations:
- *     message Profile {
- *       User user = 1;
- *       Photo photo = 2;
- *     }
- *     message User {
- *       string display_name = 1;
- *       string address = 2;
- *     }
- * In proto a field mask for `Profile` may look as such:
- *     mask {
- *       paths: "user.display_name"
- *       paths: "photo"
- *     }
- * In JSON, the same mask is represented as below:
- *     {
- *       mask: "user.displayName,photo"
- *     }
- * # Field Masks and Oneof Fields
- * Field masks treat fields in oneofs just as regular fields. Consider the
- * following message:
- *     message SampleMessage {
- *       oneof test_oneof {
- *         string name = 4;
- *         SubMessage sub_message = 9;
- *       }
- *     }
- * The field mask can be:
- *     mask {
- *       paths: "name"
- *     }
- * Or:
- *     mask {
- *       paths: "sub_message"
- *     }
- * Note that oneof type names ("test_oneof" in this case) cannot be used in
- * paths.
- * ## Field Mask Verification
- * The implementation of any API method which has a FieldMask type field in the
- * request should verify the included field paths, and return an
- * `INVALID_ARGUMENT` error if any path is unmappable.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.FieldMask}
- */
-public  final class FieldMask extends
-    com.google.protobuf.GeneratedMessageLite<
-        FieldMask, FieldMask.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.FieldMask)
-    FieldMaskOrBuilder {
-  private FieldMask() {
-    paths_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-  }
-  public static final int PATHS_FIELD_NUMBER = 1;
-  private com.google.protobuf.Internal.ProtobufList<java.lang.String> paths_;
-  /**
-   * <pre>
-   * The set of field mask paths.
-   * </pre>
-   *
-   * <code>repeated string paths = 1;</code>
-   * @return A list containing the paths.
-   */
-  @java.lang.Override
-  public java.util.List<java.lang.String> getPathsList() {
-    return paths_;
-  }
-  /**
-   * <pre>
-   * The set of field mask paths.
-   * </pre>
-   *
-   * <code>repeated string paths = 1;</code>
-   * @return The count of paths.
-   */
-  @java.lang.Override
-  public int getPathsCount() {
-    return paths_.size();
-  }
-  /**
-   * <pre>
-   * The set of field mask paths.
-   * </pre>
-   *
-   * <code>repeated string paths = 1;</code>
-   * @param index The index of the element to return.
-   * @return The paths at the given index.
-   */
-  @java.lang.Override
-  public java.lang.String getPaths(int index) {
-    return paths_.get(index);
-  }
-  /**
-   * <pre>
-   * The set of field mask paths.
-   * </pre>
-   *
-   * <code>repeated string paths = 1;</code>
-   * @param index The index of the value to return.
-   * @return The bytes of the paths at the given index.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getPathsBytes(int index) {
-    return com.google.protobuf.ByteString.copyFromUtf8(
-        paths_.get(index));
-  }
-  private void ensurePathsIsMutable() {
-    com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-        paths_;  if (!tmp.isModifiable()) {
-      paths_ =
-          com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-     }
-  }
-  /**
-   * <pre>
-   * The set of field mask paths.
-   * </pre>
-   *
-   * <code>repeated string paths = 1;</code>
-   * @param index The index to set the value at.
-   * @param value The paths to set.
-   */
-  private void setPaths(
-      int index, java.lang.String value) {
-    value.getClass();
-  ensurePathsIsMutable();
-    paths_.set(index, value);
-  }
-  /**
-   * <pre>
-   * The set of field mask paths.
-   * </pre>
-   *
-   * <code>repeated string paths = 1;</code>
-   * @param value The paths to add.
-   */
-  private void addPaths(
-      java.lang.String value) {
-    value.getClass();
-  ensurePathsIsMutable();
-    paths_.add(value);
-  }
-  /**
-   * <pre>
-   * The set of field mask paths.
-   * </pre>
-   *
-   * <code>repeated string paths = 1;</code>
-   * @param values The paths to add.
-   */
-  private void addAllPaths(
-      java.lang.Iterable<java.lang.String> values) {
-    ensurePathsIsMutable();
-    com.google.protobuf.AbstractMessageLite.addAll(
-        values, paths_);
-  }
-  /**
-   * <pre>
-   * The set of field mask paths.
-   * </pre>
-   *
-   * <code>repeated string paths = 1;</code>
-   */
-  private void clearPaths() {
-    paths_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-  }
-  /**
-   * <pre>
-   * The set of field mask paths.
-   * </pre>
-   *
-   * <code>repeated string paths = 1;</code>
-   * @param value The bytes of the paths to add.
-   */
-  private void addPathsBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    ensurePathsIsMutable();
-    paths_.add(value.toStringUtf8());
-  }
-
-  public static com.google.protobuf.FieldMask parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.FieldMask parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.FieldMask parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.FieldMask parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.FieldMask parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.FieldMask parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.FieldMask parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.FieldMask parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.FieldMask parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.FieldMask parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.FieldMask parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.FieldMask parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.FieldMask prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * `FieldMask` represents a set of symbolic field paths, for example:
-   *     paths: "f.a"
-   *     paths: "f.b.d"
-   * Here `f` represents a field in some root message, `a` and `b`
-   * fields in the message found in `f`, and `d` a field found in the
-   * message in `f.b`.
-   * Field masks are used to specify a subset of fields that should be
-   * returned by a get operation or modified by an update operation.
-   * Field masks also have a custom JSON encoding (see below).
-   * # Field Masks in Projections
-   * When used in the context of a projection, a response message or
-   * sub-message is filtered by the API to only contain those fields as
-   * specified in the mask. For example, if the mask in the previous
-   * example is applied to a response message as follows:
-   *     f {
-   *       a : 22
-   *       b {
-   *         d : 1
-   *         x : 2
-   *       }
-   *       y : 13
-   *     }
-   *     z: 8
-   * The result will not contain specific values for fields x,y and z
-   * (their value will be set to the default, and omitted in proto text
-   * output):
-   *     f {
-   *       a : 22
-   *       b {
-   *         d : 1
-   *       }
-   *     }
-   * A repeated field is not allowed except at the last position of a
-   * paths string.
-   * If a FieldMask object is not present in a get operation, the
-   * operation applies to all fields (as if a FieldMask of all fields
-   * had been specified).
-   * Note that a field mask does not necessarily apply to the
-   * top-level response message. In case of a REST get operation, the
-   * field mask applies directly to the response, but in case of a REST
-   * list operation, the mask instead applies to each individual message
-   * in the returned resource list. In case of a REST custom method,
-   * other definitions may be used. Where the mask applies will be
-   * clearly documented together with its declaration in the API.  In
-   * any case, the effect on the returned resource/resources is required
-   * behavior for APIs.
-   * # Field Masks in Update Operations
-   * A field mask in update operations specifies which fields of the
-   * targeted resource are going to be updated. The API is required
-   * to only change the values of the fields as specified in the mask
-   * and leave the others untouched. If a resource is passed in to
-   * describe the updated values, the API ignores the values of all
-   * fields not covered by the mask.
-   * If a repeated field is specified for an update operation, new values will
-   * be appended to the existing repeated field in the target resource. Note that
-   * a repeated field is only allowed in the last position of a `paths` string.
-   * If a sub-message is specified in the last position of the field mask for an
-   * update operation, then new value will be merged into the existing sub-message
-   * in the target resource.
-   * For example, given the target message:
-   *     f {
-   *       b {
-   *         d: 1
-   *         x: 2
-   *       }
-   *       c: [1]
-   *     }
-   * And an update message:
-   *     f {
-   *       b {
-   *         d: 10
-   *       }
-   *       c: [2]
-   *     }
-   * then if the field mask is:
-   *  paths: ["f.b", "f.c"]
-   * then the result will be:
-   *     f {
-   *       b {
-   *         d: 10
-   *         x: 2
-   *       }
-   *       c: [1, 2]
-   *     }
-   * An implementation may provide options to override this default behavior for
-   * repeated and message fields.
-   * In order to reset a field's value to the default, the field must
-   * be in the mask and set to the default value in the provided resource.
-   * Hence, in order to reset all fields of a resource, provide a default
-   * instance of the resource and set all fields in the mask, or do
-   * not provide a mask as described below.
-   * If a field mask is not present on update, the operation applies to
-   * all fields (as if a field mask of all fields has been specified).
-   * Note that in the presence of schema evolution, this may mean that
-   * fields the client does not know and has therefore not filled into
-   * the request will be reset to their default. If this is unwanted
-   * behavior, a specific service may require a client to always specify
-   * a field mask, producing an error if not.
-   * As with get operations, the location of the resource which
-   * describes the updated values in the request message depends on the
-   * operation kind. In any case, the effect of the field mask is
-   * required to be honored by the API.
-   * ## Considerations for HTTP REST
-   * The HTTP kind of an update operation which uses a field mask must
-   * be set to PATCH instead of PUT in order to satisfy HTTP semantics
-   * (PUT must only be used for full updates).
-   * # JSON Encoding of Field Masks
-   * In JSON, a field mask is encoded as a single string where paths are
-   * separated by a comma. Fields name in each path are converted
-   * to/from lower-camel naming conventions.
-   * As an example, consider the following message declarations:
-   *     message Profile {
-   *       User user = 1;
-   *       Photo photo = 2;
-   *     }
-   *     message User {
-   *       string display_name = 1;
-   *       string address = 2;
-   *     }
-   * In proto a field mask for `Profile` may look as such:
-   *     mask {
-   *       paths: "user.display_name"
-   *       paths: "photo"
-   *     }
-   * In JSON, the same mask is represented as below:
-   *     {
-   *       mask: "user.displayName,photo"
-   *     }
-   * # Field Masks and Oneof Fields
-   * Field masks treat fields in oneofs just as regular fields. Consider the
-   * following message:
-   *     message SampleMessage {
-   *       oneof test_oneof {
-   *         string name = 4;
-   *         SubMessage sub_message = 9;
-   *       }
-   *     }
-   * The field mask can be:
-   *     mask {
-   *       paths: "name"
-   *     }
-   * Or:
-   *     mask {
-   *       paths: "sub_message"
-   *     }
-   * Note that oneof type names ("test_oneof" in this case) cannot be used in
-   * paths.
-   * ## Field Mask Verification
-   * The implementation of any API method which has a FieldMask type field in the
-   * request should verify the included field paths, and return an
-   * `INVALID_ARGUMENT` error if any path is unmappable.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.FieldMask}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.FieldMask, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.FieldMask)
-      com.google.protobuf.FieldMaskOrBuilder {
-    // Construct using com.google.protobuf.FieldMask.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * The set of field mask paths.
-     * </pre>
-     *
-     * <code>repeated string paths = 1;</code>
-     * @return A list containing the paths.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String>
-        getPathsList() {
-      return java.util.Collections.unmodifiableList(
-          instance.getPathsList());
-    }
-    /**
-     * <pre>
-     * The set of field mask paths.
-     * </pre>
-     *
-     * <code>repeated string paths = 1;</code>
-     * @return The count of paths.
-     */
-    @java.lang.Override
-    public int getPathsCount() {
-      return instance.getPathsCount();
-    }
-    /**
-     * <pre>
-     * The set of field mask paths.
-     * </pre>
-     *
-     * <code>repeated string paths = 1;</code>
-     * @param index The index of the element to return.
-     * @return The paths at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getPaths(int index) {
-      return instance.getPaths(index);
-    }
-    /**
-     * <pre>
-     * The set of field mask paths.
-     * </pre>
-     *
-     * <code>repeated string paths = 1;</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the paths at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getPathsBytes(int index) {
-      return instance.getPathsBytes(index);
-    }
-    /**
-     * <pre>
-     * The set of field mask paths.
-     * </pre>
-     *
-     * <code>repeated string paths = 1;</code>
-     * @param index The index to set the value at.
-     * @param value The paths to set.
-     * @return This builder for chaining.
-     */
-    public Builder setPaths(
-        int index, java.lang.String value) {
-      copyOnWrite();
-      instance.setPaths(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The set of field mask paths.
-     * </pre>
-     *
-     * <code>repeated string paths = 1;</code>
-     * @param value The paths to add.
-     * @return This builder for chaining.
-     */
-    public Builder addPaths(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.addPaths(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The set of field mask paths.
-     * </pre>
-     *
-     * <code>repeated string paths = 1;</code>
-     * @param values The paths to add.
-     * @return This builder for chaining.
-     */
-    public Builder addAllPaths(
-        java.lang.Iterable<java.lang.String> values) {
-      copyOnWrite();
-      instance.addAllPaths(values);
-      return this;
-    }
-    /**
-     * <pre>
-     * The set of field mask paths.
-     * </pre>
-     *
-     * <code>repeated string paths = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearPaths() {
-      copyOnWrite();
-      instance.clearPaths();
-      return this;
-    }
-    /**
-     * <pre>
-     * The set of field mask paths.
-     * </pre>
-     *
-     * <code>repeated string paths = 1;</code>
-     * @param value The bytes of the paths to add.
-     * @return This builder for chaining.
-     */
-    public Builder addPathsBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.addPathsBytes(value);
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.FieldMask)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.FieldMask();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "paths_",
-          };
-          java.lang.String info =
-              "\u0000\u0001\u0000\u0000\u0001\u0001\u0001\u0000\u0001\u0000\u0001\u021a";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.FieldMask> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.FieldMask.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.FieldMask>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.FieldMask)
-  private static final com.google.protobuf.FieldMask DEFAULT_INSTANCE;
-  static {
-    FieldMask defaultInstance = new FieldMask();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      FieldMask.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.FieldMask getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<FieldMask> PARSER;
-
-  public static com.google.protobuf.Parser<FieldMask> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldMaskOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldMaskOrBuilder.java
deleted file mode 100644
index 198f81f..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldMaskOrBuilder.java
+++ /dev/null
@@ -1,50 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/field_mask.proto
-
-package com.google.protobuf;
-
-public interface FieldMaskOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.FieldMask)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * The set of field mask paths.
-   * </pre>
-   *
-   * <code>repeated string paths = 1;</code>
-   * @return A list containing the paths.
-   */
-  java.util.List<java.lang.String>
-      getPathsList();
-  /**
-   * <pre>
-   * The set of field mask paths.
-   * </pre>
-   *
-   * <code>repeated string paths = 1;</code>
-   * @return The count of paths.
-   */
-  int getPathsCount();
-  /**
-   * <pre>
-   * The set of field mask paths.
-   * </pre>
-   *
-   * <code>repeated string paths = 1;</code>
-   * @param index The index of the element to return.
-   * @return The paths at the given index.
-   */
-  java.lang.String getPaths(int index);
-  /**
-   * <pre>
-   * The set of field mask paths.
-   * </pre>
-   *
-   * <code>repeated string paths = 1;</code>
-   * @param index The index of the element to return.
-   * @return The paths at the given index.
-   */
-  com.google.protobuf.ByteString
-      getPathsBytes(int index);
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldMaskProto.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldMaskProto.java
deleted file mode 100644
index 2970c16..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldMaskProto.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/field_mask.proto
-
-package com.google.protobuf;
-
-public final class FieldMaskProto {
-  private FieldMaskProto() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldOrBuilder.java
deleted file mode 100644
index d62250c..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldOrBuilder.java
+++ /dev/null
@@ -1,186 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/type.proto
-
-package com.google.protobuf;
-
-public interface FieldOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.Field)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * The field type.
-   * </pre>
-   *
-   * <code>.google.protobuf.Field.Kind kind = 1;</code>
-   * @return The enum numeric value on the wire for kind.
-   */
-  int getKindValue();
-  /**
-   * <pre>
-   * The field type.
-   * </pre>
-   *
-   * <code>.google.protobuf.Field.Kind kind = 1;</code>
-   * @return The kind.
-   */
-  com.google.protobuf.Field.Kind getKind();
-
-  /**
-   * <pre>
-   * The field cardinality.
-   * </pre>
-   *
-   * <code>.google.protobuf.Field.Cardinality cardinality = 2;</code>
-   * @return The enum numeric value on the wire for cardinality.
-   */
-  int getCardinalityValue();
-  /**
-   * <pre>
-   * The field cardinality.
-   * </pre>
-   *
-   * <code>.google.protobuf.Field.Cardinality cardinality = 2;</code>
-   * @return The cardinality.
-   */
-  com.google.protobuf.Field.Cardinality getCardinality();
-
-  /**
-   * <pre>
-   * The field number.
-   * </pre>
-   *
-   * <code>int32 number = 3;</code>
-   * @return The number.
-   */
-  int getNumber();
-
-  /**
-   * <pre>
-   * The field name.
-   * </pre>
-   *
-   * <code>string name = 4;</code>
-   * @return The name.
-   */
-  java.lang.String getName();
-  /**
-   * <pre>
-   * The field name.
-   * </pre>
-   *
-   * <code>string name = 4;</code>
-   * @return The bytes for name.
-   */
-  com.google.protobuf.ByteString
-      getNameBytes();
-
-  /**
-   * <pre>
-   * The field type URL, without the scheme, for message or enumeration
-   * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
-   * </pre>
-   *
-   * <code>string type_url = 6;</code>
-   * @return The typeUrl.
-   */
-  java.lang.String getTypeUrl();
-  /**
-   * <pre>
-   * The field type URL, without the scheme, for message or enumeration
-   * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
-   * </pre>
-   *
-   * <code>string type_url = 6;</code>
-   * @return The bytes for typeUrl.
-   */
-  com.google.protobuf.ByteString
-      getTypeUrlBytes();
-
-  /**
-   * <pre>
-   * The index of the field type in `Type.oneofs`, for message or enumeration
-   * types. The first type has index 1; zero means the type is not in the list.
-   * </pre>
-   *
-   * <code>int32 oneof_index = 7;</code>
-   * @return The oneofIndex.
-   */
-  int getOneofIndex();
-
-  /**
-   * <pre>
-   * Whether to use alternative packed wire representation.
-   * </pre>
-   *
-   * <code>bool packed = 8;</code>
-   * @return The packed.
-   */
-  boolean getPacked();
-
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 9;</code>
-   */
-  java.util.List<com.google.protobuf.Option> 
-      getOptionsList();
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 9;</code>
-   */
-  com.google.protobuf.Option getOptions(int index);
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 9;</code>
-   */
-  int getOptionsCount();
-
-  /**
-   * <pre>
-   * The field JSON name.
-   * </pre>
-   *
-   * <code>string json_name = 10;</code>
-   * @return The jsonName.
-   */
-  java.lang.String getJsonName();
-  /**
-   * <pre>
-   * The field JSON name.
-   * </pre>
-   *
-   * <code>string json_name = 10;</code>
-   * @return The bytes for jsonName.
-   */
-  com.google.protobuf.ByteString
-      getJsonNameBytes();
-
-  /**
-   * <pre>
-   * The string value of the default value of this field. Proto2 syntax only.
-   * </pre>
-   *
-   * <code>string default_value = 11;</code>
-   * @return The defaultValue.
-   */
-  java.lang.String getDefaultValue();
-  /**
-   * <pre>
-   * The string value of the default value of this field. Proto2 syntax only.
-   * </pre>
-   *
-   * <code>string default_value = 11;</code>
-   * @return The bytes for defaultValue.
-   */
-  com.google.protobuf.ByteString
-      getDefaultValueBytes();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldSet.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldSet.java
deleted file mode 100644
index f64b50a..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldSet.java
+++ /dev/null
@@ -1,1306 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.Internal.checkNotNull;
-
-import com.google.protobuf.LazyField.LazyIterator;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A class which represents an arbitrary set of fields of some message type. This is used to
- * implement {@link DynamicMessage}, and also to represent extensions in {@link GeneratedMessage}.
- * This class is package-private, since outside users should probably be using {@link
- * DynamicMessage}.
- *
- * @author kenton@google.com Kenton Varda
- */
-final class FieldSet<T extends FieldSet.FieldDescriptorLite<T>> {
-  /**
-   * Interface for a FieldDescriptor or lite extension descriptor. This prevents FieldSet from
-   * depending on {@link Descriptors.FieldDescriptor}.
-   */
-  public interface FieldDescriptorLite<T extends FieldDescriptorLite<T>> extends Comparable<T> {
-    int getNumber();
-
-    WireFormat.FieldType getLiteType();
-
-    WireFormat.JavaType getLiteJavaType();
-
-    boolean isRepeated();
-
-    boolean isPacked();
-
-    Internal.EnumLiteMap<?> getEnumType();
-
-    // If getLiteJavaType() == MESSAGE, this merges a message object of the
-    // type into a builder of the type.  Returns {@code to}.
-    MessageLite.Builder internalMergeFrom(MessageLite.Builder to, MessageLite from);
-  }
-
-  private static final int DEFAULT_FIELD_MAP_ARRAY_SIZE = 16;
-
-  private final SmallSortedMap<T, Object> fields;
-  private boolean isImmutable;
-  private boolean hasLazyField;
-
-  /** Construct a new FieldSet. */
-  private FieldSet() {
-    this.fields = SmallSortedMap.newFieldMap(DEFAULT_FIELD_MAP_ARRAY_SIZE);
-  }
-
-  /** Construct an empty FieldSet. This is only used to initialize DEFAULT_INSTANCE. */
-  @SuppressWarnings("unused")
-  private FieldSet(final boolean dummy) {
-    this(SmallSortedMap.<T>newFieldMap(0));
-    makeImmutable();
-  }
-
-  private FieldSet(SmallSortedMap<T, Object> fields) {
-    this.fields = fields;
-    makeImmutable();
-  }
-
-  /** Construct a new FieldSet. */
-  public static <T extends FieldSet.FieldDescriptorLite<T>> FieldSet<T> newFieldSet() {
-    return new FieldSet<T>();
-  }
-
-  /** Get an immutable empty FieldSet. */
-  @SuppressWarnings("unchecked")
-  public static <T extends FieldSet.FieldDescriptorLite<T>> FieldSet<T> emptySet() {
-    return DEFAULT_INSTANCE;
-  }
-
-  /** Construct a new Builder. */
-  public static <T extends FieldDescriptorLite<T>> Builder<T> newBuilder() {
-    return new Builder<T>();
-  }
-
-  @SuppressWarnings("rawtypes")
-  private static final FieldSet DEFAULT_INSTANCE = new FieldSet(true);
-
-  /** Returns {@code true} if empty, {@code false} otherwise. */
-  boolean isEmpty() {
-    return fields.isEmpty();
-  }
-
-  /** Make this FieldSet immutable from this point forward. */
-  public void makeImmutable() {
-    if (isImmutable) {
-      return;
-    }
-    fields.makeImmutable();
-    isImmutable = true;
-  }
-
-  /**
-   * Returns whether the FieldSet is immutable. This is true if it is the {@link #emptySet} or if
-   * {@link #makeImmutable} were called.
-   *
-   * @return whether the FieldSet is immutable.
-   */
-  public boolean isImmutable() {
-    return isImmutable;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-
-    if (!(o instanceof FieldSet)) {
-      return false;
-    }
-
-    FieldSet<?> other = (FieldSet<?>) o;
-    return fields.equals(other.fields);
-  }
-
-  @Override
-  public int hashCode() {
-    return fields.hashCode();
-  }
-
-  /**
-   * Clones the FieldSet. The returned FieldSet will be mutable even if the original FieldSet was
-   * immutable.
-   *
-   * @return the newly cloned FieldSet
-   */
-  @Override
-  public FieldSet<T> clone() {
-    // We can't just call fields.clone because List objects in the map
-    // should not be shared.
-    FieldSet<T> clone = FieldSet.newFieldSet();
-    for (int i = 0; i < fields.getNumArrayEntries(); i++) {
-      Map.Entry<T, Object> entry = fields.getArrayEntryAt(i);
-      clone.setField(entry.getKey(), entry.getValue());
-    }
-    for (Map.Entry<T, Object> entry : fields.getOverflowEntries()) {
-      clone.setField(entry.getKey(), entry.getValue());
-    }
-    clone.hasLazyField = hasLazyField;
-    return clone;
-  }
-
-
-  // =================================================================
-
-  /** See {@link Message.Builder#clear()}. */
-  public void clear() {
-    fields.clear();
-    hasLazyField = false;
-  }
-
-  /** Get a simple map containing all the fields. */
-  public Map<T, Object> getAllFields() {
-    if (hasLazyField) {
-      SmallSortedMap<T, Object> result = cloneAllFieldsMap(fields, /* copyList */ false);
-      if (fields.isImmutable()) {
-        result.makeImmutable();
-      }
-      return result;
-    }
-    return fields.isImmutable() ? fields : Collections.unmodifiableMap(fields);
-  }
-
-  private static <T extends FieldDescriptorLite<T>> SmallSortedMap<T, Object> cloneAllFieldsMap(
-      SmallSortedMap<T, Object> fields, boolean copyList) {
-    SmallSortedMap<T, Object> result = SmallSortedMap.newFieldMap(DEFAULT_FIELD_MAP_ARRAY_SIZE);
-    for (int i = 0; i < fields.getNumArrayEntries(); i++) {
-      cloneFieldEntry(result, fields.getArrayEntryAt(i), copyList);
-    }
-    for (Map.Entry<T, Object> entry : fields.getOverflowEntries()) {
-      cloneFieldEntry(result, entry, copyList);
-    }
-    return result;
-  }
-
-  private static <T extends FieldDescriptorLite<T>> void cloneFieldEntry(
-      Map<T, Object> map, Map.Entry<T, Object> entry, boolean copyList) {
-    T key = entry.getKey();
-    Object value = entry.getValue();
-    if (value instanceof LazyField) {
-      map.put(key, ((LazyField) value).getValue());
-    } else if (copyList && value instanceof List) {
-      map.put(key, new ArrayList<>((List<?>) value));
-    } else {
-      map.put(key, value);
-    }
-  }
-
-  /**
-   * Get an iterator to the field map. This iterator should not be leaked out of the protobuf
-   * library as it is not protected from mutation when fields is not immutable.
-   */
-  public Iterator<Map.Entry<T, Object>> iterator() {
-    if (hasLazyField) {
-      return new LazyIterator<T>(fields.entrySet().iterator());
-    }
-    return fields.entrySet().iterator();
-  }
-
-  /**
-   * Get an iterator over the fields in the map in descending (i.e. reverse) order. This iterator
-   * should not be leaked out of the protobuf library as it is not protected from mutation when
-   * fields is not immutable.
-   */
-  Iterator<Map.Entry<T, Object>> descendingIterator() {
-    if (hasLazyField) {
-      return new LazyIterator<T>(fields.descendingEntrySet().iterator());
-    }
-    return fields.descendingEntrySet().iterator();
-  }
-
-  /** Useful for implementing {@link Message#hasField(Descriptors.FieldDescriptor)}. */
-  public boolean hasField(final T descriptor) {
-    if (descriptor.isRepeated()) {
-      throw new IllegalArgumentException("hasField() can only be called on non-repeated fields.");
-    }
-
-    return fields.get(descriptor) != null;
-  }
-
-  /**
-   * Useful for implementing {@link Message#getField(Descriptors.FieldDescriptor)}. This method
-   * returns {@code null} if the field is not set; in this case it is up to the caller to fetch the
-   * field's default value.
-   */
-  public Object getField(final T descriptor) {
-    Object o = fields.get(descriptor);
-    if (o instanceof LazyField) {
-      return ((LazyField) o).getValue();
-    }
-    return o;
-  }
-
-  /**
-   * Useful for implementing {@link Message.Builder#setField(Descriptors.FieldDescriptor,Object)}.
-   */
-  @SuppressWarnings({"unchecked", "rawtypes"})
-  public void setField(final T descriptor, Object value) {
-    if (descriptor.isRepeated()) {
-      if (!(value instanceof List)) {
-        throw new IllegalArgumentException(
-            "Wrong object type used with protocol message reflection.");
-      }
-
-      // Wrap the contents in a new list so that the caller cannot change
-      // the list's contents after setting it.
-      final List newList = new ArrayList<>();
-      newList.addAll((List) value);
-      for (final Object element : newList) {
-        verifyType(descriptor, element);
-      }
-      value = newList;
-    } else {
-      verifyType(descriptor, value);
-    }
-
-    if (value instanceof LazyField) {
-      hasLazyField = true;
-    }
-    fields.put(descriptor, value);
-  }
-
-  /** Useful for implementing {@link Message.Builder#clearField(Descriptors.FieldDescriptor)}. */
-  public void clearField(final T descriptor) {
-    fields.remove(descriptor);
-    if (fields.isEmpty()) {
-      hasLazyField = false;
-    }
-  }
-
-  /** Useful for implementing {@link Message#getRepeatedFieldCount(Descriptors.FieldDescriptor)}. */
-  public int getRepeatedFieldCount(final T descriptor) {
-    if (!descriptor.isRepeated()) {
-      throw new IllegalArgumentException(
-          "getRepeatedField() can only be called on repeated fields.");
-    }
-
-    final Object value = getField(descriptor);
-    if (value == null) {
-      return 0;
-    } else {
-      return ((List<?>) value).size();
-    }
-  }
-
-  /** Useful for implementing {@link Message#getRepeatedField(Descriptors.FieldDescriptor,int)}. */
-  public Object getRepeatedField(final T descriptor, final int index) {
-    if (!descriptor.isRepeated()) {
-      throw new IllegalArgumentException(
-          "getRepeatedField() can only be called on repeated fields.");
-    }
-
-    final Object value = getField(descriptor);
-
-    if (value == null) {
-      throw new IndexOutOfBoundsException();
-    } else {
-      return ((List<?>) value).get(index);
-    }
-  }
-
-  /**
-   * Useful for implementing {@link
-   * Message.Builder#setRepeatedField(Descriptors.FieldDescriptor,int,Object)}.
-   */
-  @SuppressWarnings("unchecked")
-  public void setRepeatedField(final T descriptor, final int index, final Object value) {
-    if (!descriptor.isRepeated()) {
-      throw new IllegalArgumentException(
-          "getRepeatedField() can only be called on repeated fields.");
-    }
-
-    final Object list = getField(descriptor);
-    if (list == null) {
-      throw new IndexOutOfBoundsException();
-    }
-
-    verifyType(descriptor, value);
-    ((List<Object>) list).set(index, value);
-  }
-
-  /**
-   * Useful for implementing {@link
-   * Message.Builder#addRepeatedField(Descriptors.FieldDescriptor,Object)}.
-   */
-  @SuppressWarnings("unchecked")
-  public void addRepeatedField(final T descriptor, final Object value) {
-    if (!descriptor.isRepeated()) {
-      throw new IllegalArgumentException(
-          "addRepeatedField() can only be called on repeated fields.");
-    }
-
-    verifyType(descriptor, value);
-
-    final Object existingValue = getField(descriptor);
-    List<Object> list;
-    if (existingValue == null) {
-      list = new ArrayList<Object>();
-      fields.put(descriptor, list);
-    } else {
-      list = (List<Object>) existingValue;
-    }
-
-    list.add(value);
-  }
-
-  /**
-   * Verifies that the given object is of the correct type to be a valid value for the given field.
-   * (For repeated fields, this checks if the object is the right type to be one element of the
-   * field.)
-   *
-   * @throws IllegalArgumentException The value is not of the right type.
-   */
-  private void verifyType(final T descriptor, final Object value) {
-    if (!isValidType(descriptor.getLiteType(), value)) {
-      // TODO(kenton):  When chaining calls to setField(), it can be hard to
-      //   tell from the stack trace which exact call failed, since the whole
-      //   chain is considered one line of code.  It would be nice to print
-      //   more information here, e.g. naming the field.  We used to do that.
-      //   But we can't now that FieldSet doesn't use descriptors.  Maybe this
-      //   isn't a big deal, though, since it would only really apply when using
-      //   reflection and generally people don't chain reflection setters.
-      throw new IllegalArgumentException(
-          String.format(
-              "Wrong object type used with protocol message reflection.\n"
-              + "Field number: %d, field java type: %s, value type: %s\n",
-              descriptor.getNumber(),
-              descriptor.getLiteType().getJavaType(),
-              value.getClass().getName()));
-    }
-  }
-
-
-  private static boolean isValidType(final WireFormat.FieldType type, final Object value) {
-    checkNotNull(value);
-    switch (type.getJavaType()) {
-      case INT:
-        return value instanceof Integer;
-      case LONG:
-        return value instanceof Long;
-      case FLOAT:
-        return value instanceof Float;
-      case DOUBLE:
-        return value instanceof Double;
-      case BOOLEAN:
-        return value instanceof Boolean;
-      case STRING:
-        return value instanceof String;
-      case BYTE_STRING:
-        return value instanceof ByteString || value instanceof byte[];
-      case ENUM:
-        // TODO(kenton):  Caller must do type checking here, I guess.
-        return (value instanceof Integer || value instanceof Internal.EnumLite);
-      case MESSAGE:
-        // TODO(kenton):  Caller must do type checking here, I guess.
-        return (value instanceof MessageLite) || (value instanceof LazyField);
-    }
-    return false;
-  }
-
-  // =================================================================
-  // Parsing and serialization
-
-  /**
-   * See {@link Message#isInitialized()}. Note: Since {@code FieldSet} itself does not have any way
-   * of knowing about required fields that aren't actually present in the set, it is up to the
-   * caller to check that all required fields are present.
-   */
-  public boolean isInitialized() {
-    for (int i = 0; i < fields.getNumArrayEntries(); i++) {
-      if (!isInitialized(fields.getArrayEntryAt(i))) {
-        return false;
-      }
-    }
-    for (final Map.Entry<T, Object> entry : fields.getOverflowEntries()) {
-      if (!isInitialized(entry)) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  @SuppressWarnings("unchecked")
-  private static <T extends FieldDescriptorLite<T>> boolean isInitialized(
-      final Map.Entry<T, Object> entry) {
-    final T descriptor = entry.getKey();
-    if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) {
-      if (descriptor.isRepeated()) {
-        for (final MessageLite element : (List<MessageLite>) entry.getValue()) {
-          if (!element.isInitialized()) {
-            return false;
-          }
-        }
-      } else {
-        Object value = entry.getValue();
-        if (value instanceof MessageLite) {
-          if (!((MessageLite) value).isInitialized()) {
-            return false;
-          }
-        } else if (value instanceof LazyField) {
-          return true;
-        } else {
-          throw new IllegalArgumentException(
-              "Wrong object type used with protocol message reflection.");
-        }
-      }
-    }
-    return true;
-  }
-
-  /**
-   * Given a field type, return the wire type.
-   *
-   * @return One of the {@code WIRETYPE_} constants defined in {@link WireFormat}.
-   */
-  static int getWireFormatForFieldType(final WireFormat.FieldType type, boolean isPacked) {
-    if (isPacked) {
-      return WireFormat.WIRETYPE_LENGTH_DELIMITED;
-    } else {
-      return type.getWireType();
-    }
-  }
-
-  /** Like {@link Message.Builder#mergeFrom(Message)}, but merges from another {@link FieldSet}. */
-  public void mergeFrom(final FieldSet<T> other) {
-    for (int i = 0; i < other.fields.getNumArrayEntries(); i++) {
-      mergeFromField(other.fields.getArrayEntryAt(i));
-    }
-    for (final Map.Entry<T, Object> entry : other.fields.getOverflowEntries()) {
-      mergeFromField(entry);
-    }
-  }
-
-  private static Object cloneIfMutable(Object value) {
-    if (value instanceof byte[]) {
-      byte[] bytes = (byte[]) value;
-      byte[] copy = new byte[bytes.length];
-      System.arraycopy(bytes, 0, copy, 0, bytes.length);
-      return copy;
-    } else {
-      return value;
-    }
-  }
-
-  @SuppressWarnings({"unchecked", "rawtypes"})
-  private void mergeFromField(final Map.Entry<T, Object> entry) {
-    final T descriptor = entry.getKey();
-    Object otherValue = entry.getValue();
-    if (otherValue instanceof LazyField) {
-      otherValue = ((LazyField) otherValue).getValue();
-    }
-
-    if (descriptor.isRepeated()) {
-      Object value = getField(descriptor);
-      if (value == null) {
-        value = new ArrayList<>();
-      }
-      for (Object element : (List) otherValue) {
-        ((List) value).add(cloneIfMutable(element));
-      }
-      fields.put(descriptor, value);
-    } else if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) {
-      Object value = getField(descriptor);
-      if (value == null) {
-        fields.put(descriptor, cloneIfMutable(otherValue));
-      } else {
-        // Merge the messages.
-          value =
-              descriptor
-                  .internalMergeFrom(((MessageLite) value).toBuilder(), (MessageLite) otherValue)
-                  .build();
-        fields.put(descriptor, value);
-      }
-    } else {
-      fields.put(descriptor, cloneIfMutable(otherValue));
-    }
-  }
-
-  // TODO(kenton):  Move static parsing and serialization methods into some
-  //   other class.  Probably WireFormat.
-
-  /**
-   * Read a field of any primitive type for immutable messages from a CodedInputStream. Enums,
-   * groups, and embedded messages are not handled by this method.
-   *
-   * @param input The stream from which to read.
-   * @param type Declared type of the field.
-   * @param checkUtf8 When true, check that the input is valid utf8.
-   * @return An object representing the field's value, of the exact type which would be returned by
-   *     {@link Message#getField(Descriptors.FieldDescriptor)} for this field.
-   */
-  public static Object readPrimitiveField(
-      CodedInputStream input, final WireFormat.FieldType type, boolean checkUtf8)
-      throws IOException {
-    if (checkUtf8) {
-      return WireFormat.readPrimitiveField(input, type, WireFormat.Utf8Validation.STRICT);
-    } else {
-      return WireFormat.readPrimitiveField(input, type, WireFormat.Utf8Validation.LOOSE);
-    }
-  }
-
-
-  /** See {@link Message#writeTo(CodedOutputStream)}. */
-  public void writeTo(final CodedOutputStream output) throws IOException {
-    for (int i = 0; i < fields.getNumArrayEntries(); i++) {
-      final Map.Entry<T, Object> entry = fields.getArrayEntryAt(i);
-      writeField(entry.getKey(), entry.getValue(), output);
-    }
-    for (final Map.Entry<T, Object> entry : fields.getOverflowEntries()) {
-      writeField(entry.getKey(), entry.getValue(), output);
-    }
-  }
-
-  /** Like {@link #writeTo} but uses MessageSet wire format. */
-  public void writeMessageSetTo(final CodedOutputStream output) throws IOException {
-    for (int i = 0; i < fields.getNumArrayEntries(); i++) {
-      writeMessageSetTo(fields.getArrayEntryAt(i), output);
-    }
-    for (final Map.Entry<T, Object> entry : fields.getOverflowEntries()) {
-      writeMessageSetTo(entry, output);
-    }
-  }
-
-  private void writeMessageSetTo(final Map.Entry<T, Object> entry, final CodedOutputStream output)
-      throws IOException {
-    final T descriptor = entry.getKey();
-    if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE
-        && !descriptor.isRepeated()
-        && !descriptor.isPacked()) {
-      Object value = entry.getValue();
-      if (value instanceof LazyField) {
-        value = ((LazyField) value).getValue();
-      }
-      output.writeMessageSetExtension(entry.getKey().getNumber(), (MessageLite) value);
-    } else {
-      writeField(descriptor, entry.getValue(), output);
-    }
-  }
-
-  /**
-   * Write a single tag-value pair to the stream.
-   *
-   * @param output The output stream.
-   * @param type The field's type.
-   * @param number The field's number.
-   * @param value Object representing the field's value. Must be of the exact type which would be
-   *     returned by {@link Message#getField(Descriptors.FieldDescriptor)} for this field.
-   */
-  static void writeElement(
-      final CodedOutputStream output,
-      final WireFormat.FieldType type,
-      final int number,
-      final Object value)
-      throws IOException {
-    // Special case for groups, which need a start and end tag; other fields
-    // can just use writeTag() and writeFieldNoTag().
-    if (type == WireFormat.FieldType.GROUP) {
-        output.writeGroup(number, (MessageLite) value);
-    } else {
-      output.writeTag(number, getWireFormatForFieldType(type, false));
-      writeElementNoTag(output, type, value);
-    }
-  }
-
-  /**
-   * Write a field of arbitrary type, without its tag, to the stream.
-   *
-   * @param output The output stream.
-   * @param type The field's type.
-   * @param value Object representing the field's value. Must be of the exact type which would be
-   *     returned by {@link Message#getField(Descriptors.FieldDescriptor)} for this field.
-   */
-  static void writeElementNoTag(
-      final CodedOutputStream output, final WireFormat.FieldType type, final Object value)
-      throws IOException {
-    switch (type) {
-      case DOUBLE:
-        output.writeDoubleNoTag((Double) value);
-        break;
-      case FLOAT:
-        output.writeFloatNoTag((Float) value);
-        break;
-      case INT64:
-        output.writeInt64NoTag((Long) value);
-        break;
-      case UINT64:
-        output.writeUInt64NoTag((Long) value);
-        break;
-      case INT32:
-        output.writeInt32NoTag((Integer) value);
-        break;
-      case FIXED64:
-        output.writeFixed64NoTag((Long) value);
-        break;
-      case FIXED32:
-        output.writeFixed32NoTag((Integer) value);
-        break;
-      case BOOL:
-        output.writeBoolNoTag((Boolean) value);
-        break;
-      case GROUP:
-        output.writeGroupNoTag((MessageLite) value);
-        break;
-      case MESSAGE:
-        output.writeMessageNoTag((MessageLite) value);
-        break;
-      case STRING:
-        if (value instanceof ByteString) {
-          output.writeBytesNoTag((ByteString) value);
-        } else {
-          output.writeStringNoTag((String) value);
-        }
-        break;
-      case BYTES:
-        if (value instanceof ByteString) {
-          output.writeBytesNoTag((ByteString) value);
-        } else {
-          output.writeByteArrayNoTag((byte[]) value);
-        }
-        break;
-      case UINT32:
-        output.writeUInt32NoTag((Integer) value);
-        break;
-      case SFIXED32:
-        output.writeSFixed32NoTag((Integer) value);
-        break;
-      case SFIXED64:
-        output.writeSFixed64NoTag((Long) value);
-        break;
-      case SINT32:
-        output.writeSInt32NoTag((Integer) value);
-        break;
-      case SINT64:
-        output.writeSInt64NoTag((Long) value);
-        break;
-
-      case ENUM:
-        if (value instanceof Internal.EnumLite) {
-          output.writeEnumNoTag(((Internal.EnumLite) value).getNumber());
-        } else {
-          output.writeEnumNoTag(((Integer) value).intValue());
-        }
-        break;
-    }
-  }
-
-  /** Write a single field. */
-  public static void writeField(
-      final FieldDescriptorLite<?> descriptor, final Object value, final CodedOutputStream output)
-      throws IOException {
-    WireFormat.FieldType type = descriptor.getLiteType();
-    int number = descriptor.getNumber();
-    if (descriptor.isRepeated()) {
-      final List<?> valueList = (List<?>) value;
-      if (descriptor.isPacked()) {
-        output.writeTag(number, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-        // Compute the total data size so the length can be written.
-        int dataSize = 0;
-        for (final Object element : valueList) {
-          dataSize += computeElementSizeNoTag(type, element);
-        }
-        output.writeRawVarint32(dataSize);
-        // Write the data itself, without any tags.
-        for (final Object element : valueList) {
-          writeElementNoTag(output, type, element);
-        }
-      } else {
-        for (final Object element : valueList) {
-          writeElement(output, type, number, element);
-        }
-      }
-    } else {
-      if (value instanceof LazyField) {
-        writeElement(output, type, number, ((LazyField) value).getValue());
-      } else {
-        writeElement(output, type, number, value);
-      }
-    }
-  }
-
-  /**
-   * See {@link Message#getSerializedSize()}. It's up to the caller to cache the resulting size if
-   * desired.
-   */
-  public int getSerializedSize() {
-    int size = 0;
-    for (int i = 0; i < fields.getNumArrayEntries(); i++) {
-      final Map.Entry<T, Object> entry = fields.getArrayEntryAt(i);
-      size += computeFieldSize(entry.getKey(), entry.getValue());
-    }
-    for (final Map.Entry<T, Object> entry : fields.getOverflowEntries()) {
-      size += computeFieldSize(entry.getKey(), entry.getValue());
-    }
-    return size;
-  }
-
-  /** Like {@link #getSerializedSize} but uses MessageSet wire format. */
-  public int getMessageSetSerializedSize() {
-    int size = 0;
-    for (int i = 0; i < fields.getNumArrayEntries(); i++) {
-      size += getMessageSetSerializedSize(fields.getArrayEntryAt(i));
-    }
-    for (final Map.Entry<T, Object> entry : fields.getOverflowEntries()) {
-      size += getMessageSetSerializedSize(entry);
-    }
-    return size;
-  }
-
-  private int getMessageSetSerializedSize(final Map.Entry<T, Object> entry) {
-    final T descriptor = entry.getKey();
-    Object value = entry.getValue();
-    if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE
-        && !descriptor.isRepeated()
-        && !descriptor.isPacked()) {
-      if (value instanceof LazyField) {
-        return CodedOutputStream.computeLazyFieldMessageSetExtensionSize(
-            entry.getKey().getNumber(), (LazyField) value);
-      } else {
-        return CodedOutputStream.computeMessageSetExtensionSize(
-            entry.getKey().getNumber(), (MessageLite) value);
-      }
-    } else {
-      return computeFieldSize(descriptor, value);
-    }
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a single tag/value pair of arbitrary
-   * type.
-   *
-   * @param type The field's type.
-   * @param number The field's number.
-   * @param value Object representing the field's value. Must be of the exact type which would be
-   *     returned by {@link Message#getField(Descriptors.FieldDescriptor)} for this field.
-   */
-  static int computeElementSize(
-      final WireFormat.FieldType type, final int number, final Object value) {
-    int tagSize = CodedOutputStream.computeTagSize(number);
-    if (type == WireFormat.FieldType.GROUP) {
-      // Only count the end group tag for proto2 messages as for proto1 the end
-      // group tag will be counted as a part of getSerializedSize().
-        tagSize *= 2;
-    }
-    return tagSize + computeElementSizeNoTag(type, value);
-  }
-
-  /**
-   * Compute the number of bytes that would be needed to encode a particular value of arbitrary
-   * type, excluding tag.
-   *
-   * @param type The field's type.
-   * @param value Object representing the field's value. Must be of the exact type which would be
-   *     returned by {@link Message#getField(Descriptors.FieldDescriptor)} for this field.
-   */
-  static int computeElementSizeNoTag(final WireFormat.FieldType type, final Object value) {
-    switch (type) {
-        // Note:  Minor violation of 80-char limit rule here because this would
-        //   actually be harder to read if we wrapped the lines.
-      case DOUBLE:
-        return CodedOutputStream.computeDoubleSizeNoTag((Double) value);
-      case FLOAT:
-        return CodedOutputStream.computeFloatSizeNoTag((Float) value);
-      case INT64:
-        return CodedOutputStream.computeInt64SizeNoTag((Long) value);
-      case UINT64:
-        return CodedOutputStream.computeUInt64SizeNoTag((Long) value);
-      case INT32:
-        return CodedOutputStream.computeInt32SizeNoTag((Integer) value);
-      case FIXED64:
-        return CodedOutputStream.computeFixed64SizeNoTag((Long) value);
-      case FIXED32:
-        return CodedOutputStream.computeFixed32SizeNoTag((Integer) value);
-      case BOOL:
-        return CodedOutputStream.computeBoolSizeNoTag((Boolean) value);
-      case GROUP:
-        return CodedOutputStream.computeGroupSizeNoTag((MessageLite) value);
-      case BYTES:
-        if (value instanceof ByteString) {
-          return CodedOutputStream.computeBytesSizeNoTag((ByteString) value);
-        } else {
-          return CodedOutputStream.computeByteArraySizeNoTag((byte[]) value);
-        }
-      case STRING:
-        if (value instanceof ByteString) {
-          return CodedOutputStream.computeBytesSizeNoTag((ByteString) value);
-        } else {
-          return CodedOutputStream.computeStringSizeNoTag((String) value);
-        }
-      case UINT32:
-        return CodedOutputStream.computeUInt32SizeNoTag((Integer) value);
-      case SFIXED32:
-        return CodedOutputStream.computeSFixed32SizeNoTag((Integer) value);
-      case SFIXED64:
-        return CodedOutputStream.computeSFixed64SizeNoTag((Long) value);
-      case SINT32:
-        return CodedOutputStream.computeSInt32SizeNoTag((Integer) value);
-      case SINT64:
-        return CodedOutputStream.computeSInt64SizeNoTag((Long) value);
-
-      case MESSAGE:
-        if (value instanceof LazyField) {
-          return CodedOutputStream.computeLazyFieldSizeNoTag((LazyField) value);
-        } else {
-          return CodedOutputStream.computeMessageSizeNoTag((MessageLite) value);
-        }
-
-      case ENUM:
-        if (value instanceof Internal.EnumLite) {
-          return CodedOutputStream.computeEnumSizeNoTag(((Internal.EnumLite) value).getNumber());
-        } else {
-          return CodedOutputStream.computeEnumSizeNoTag((Integer) value);
-        }
-    }
-
-    throw new RuntimeException("There is no way to get here, but the compiler thinks otherwise.");
-  }
-
-  /** Compute the number of bytes needed to encode a particular field. */
-  public static int computeFieldSize(final FieldDescriptorLite<?> descriptor, final Object value) {
-    WireFormat.FieldType type = descriptor.getLiteType();
-    int number = descriptor.getNumber();
-    if (descriptor.isRepeated()) {
-      if (descriptor.isPacked()) {
-        int dataSize = 0;
-        for (final Object element : (List<?>) value) {
-          dataSize += computeElementSizeNoTag(type, element);
-        }
-        return dataSize
-            + CodedOutputStream.computeTagSize(number)
-            + CodedOutputStream.computeRawVarint32Size(dataSize);
-      } else {
-        int size = 0;
-        for (final Object element : (List<?>) value) {
-          size += computeElementSize(type, number, element);
-        }
-        return size;
-      }
-    } else {
-      return computeElementSize(type, number, value);
-    }
-  }
-
-  /**
-   * A FieldSet Builder that accept a {@link MessageLite.Builder} as a field value. This is useful
-   * for implementing methods in {@link MessageLite.Builder}.
-   */
-  static final class Builder<T extends FieldDescriptorLite<T>> {
-
-    private SmallSortedMap<T, Object> fields;
-    private boolean hasLazyField;
-    private boolean isMutable;
-    private boolean hasNestedBuilders;
-
-    private Builder() {
-      this(SmallSortedMap.<T>newFieldMap(DEFAULT_FIELD_MAP_ARRAY_SIZE));
-    }
-
-    private Builder(SmallSortedMap<T, Object> fields) {
-      this.fields = fields;
-      this.isMutable = true;
-    }
-
-    /** Creates the FieldSet */
-    public FieldSet<T> build() {
-      if (fields.isEmpty()) {
-        return FieldSet.emptySet();
-      }
-      isMutable = false;
-      SmallSortedMap<T, Object> fieldsForBuild = fields;
-      if (hasNestedBuilders) {
-        // Make a copy of the fields map with all Builders replaced by Message.
-        fieldsForBuild = cloneAllFieldsMap(fields, /* copyList */ false);
-        replaceBuilders(fieldsForBuild);
-      }
-      FieldSet<T> fieldSet = new FieldSet<>(fieldsForBuild);
-      fieldSet.hasLazyField = hasLazyField;
-      return fieldSet;
-    }
-
-    private static <T extends FieldDescriptorLite<T>> void replaceBuilders(
-        SmallSortedMap<T, Object> fieldMap) {
-      for (int i = 0; i < fieldMap.getNumArrayEntries(); i++) {
-        replaceBuilders(fieldMap.getArrayEntryAt(i));
-      }
-      for (Map.Entry<T, Object> entry : fieldMap.getOverflowEntries()) {
-        replaceBuilders(entry);
-      }
-    }
-
-    private static <T extends FieldDescriptorLite<T>> void replaceBuilders(
-        Map.Entry<T, Object> entry) {
-      entry.setValue(replaceBuilders(entry.getKey(), entry.getValue()));
-    }
-
-    private static <T extends FieldDescriptorLite<T>> Object replaceBuilders(
-        T descriptor, Object value) {
-      if (value == null) {
-        return value;
-      }
-      if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) {
-        if (descriptor.isRepeated()) {
-          if (!(value instanceof List)) {
-            throw new IllegalStateException(
-                "Repeated field should contains a List but actually contains type: "
-                    + value.getClass());
-          }
-          @SuppressWarnings("unchecked")  // We just check that value is an instance of List above.
-          List<Object> list = (List<Object>) value;
-          for (int i = 0; i < list.size(); i++) {
-            Object oldElement = list.get(i);
-            Object newElement = replaceBuilder(oldElement);
-            if (newElement != oldElement) {
-              // If the list contains a Message.Builder, then make a copy of that list and then
-              // modify the Message.Builder into a Message and return the new list. This way, the
-              // existing Message.Builder will still be able to modify the inner fields of the
-              // original FieldSet.Builder.
-              if (list == value) {
-                list = new ArrayList<>(list);
-              }
-              list.set(i, newElement);
-            }
-          }
-          return list;
-        } else {
-          return replaceBuilder(value);
-        }
-      }
-      return value;
-    }
-
-    private static Object replaceBuilder(Object value) {
-      return (value instanceof MessageLite.Builder) ? ((MessageLite.Builder) value).build() : value;
-    }
-
-    /** Returns a new Builder using the fields from {@code fieldSet}. */
-    public static <T extends FieldDescriptorLite<T>> Builder<T> fromFieldSet(FieldSet<T> fieldSet) {
-      Builder<T> builder = new Builder<T>(cloneAllFieldsMap(fieldSet.fields, /* copyList */ true));
-      builder.hasLazyField = fieldSet.hasLazyField;
-      return builder;
-    }
-
-    // =================================================================
-
-    /** Get a simple map containing all the fields. */
-    public Map<T, Object> getAllFields() {
-      if (hasLazyField) {
-        SmallSortedMap<T, Object> result = cloneAllFieldsMap(fields, /* copyList */ false);
-        if (fields.isImmutable()) {
-          result.makeImmutable();
-        } else {
-          replaceBuilders(result);
-        }
-        return result;
-      }
-      return fields.isImmutable() ? fields : Collections.unmodifiableMap(fields);
-    }
-
-    /** Useful for implementing {@link Message#hasField(Descriptors.FieldDescriptor)}. */
-    public boolean hasField(final T descriptor) {
-      if (descriptor.isRepeated()) {
-        throw new IllegalArgumentException("hasField() can only be called on non-repeated fields.");
-      }
-
-      return fields.get(descriptor) != null;
-    }
-
-    /**
-     * Useful for implementing {@link Message#getField(Descriptors.FieldDescriptor)}. This method
-     * returns {@code null} if the field is not set; in this case it is up to the caller to fetch
-     * the field's default value.
-     */
-    public Object getField(final T descriptor) {
-      Object value = getFieldAllowBuilders(descriptor);
-      return replaceBuilders(descriptor, value);
-    }
-
-    /** Same as {@link #getField(F)}, but allow a {@link MessageLite.Builder} to be returned. */
-    Object getFieldAllowBuilders(final T descriptor) {
-      Object o = fields.get(descriptor);
-      if (o instanceof LazyField) {
-        return ((LazyField) o).getValue();
-      }
-      return o;
-    }
-
-    private void ensureIsMutable() {
-      if (!isMutable) {
-        fields = cloneAllFieldsMap(fields, /* copyList */ true);
-        isMutable = true;
-      }
-    }
-
-    /**
-     * Useful for implementing {@link Message.Builder#setField(Descriptors.FieldDescriptor,
-     * Object)}.
-     */
-    @SuppressWarnings({"unchecked", "rawtypes"})
-    public void setField(final T descriptor, Object value) {
-      ensureIsMutable();
-      if (descriptor.isRepeated()) {
-        if (!(value instanceof List)) {
-          throw new IllegalArgumentException(
-              "Wrong object type used with protocol message reflection.");
-        }
-
-        // Wrap the contents in a new list so that the caller cannot change
-        // the list's contents after setting it.
-        final List newList = new ArrayList();
-        newList.addAll((List) value);
-        for (final Object element : newList) {
-          verifyType(descriptor, element);
-          hasNestedBuilders = hasNestedBuilders || element instanceof MessageLite.Builder;
-        }
-        value = newList;
-      } else {
-        verifyType(descriptor, value);
-      }
-
-      if (value instanceof LazyField) {
-        hasLazyField = true;
-      }
-      hasNestedBuilders = hasNestedBuilders || value instanceof MessageLite.Builder;
-
-      fields.put(descriptor, value);
-    }
-
-    /** Useful for implementing {@link Message.Builder#clearField(Descriptors.FieldDescriptor)}. */
-    public void clearField(final T descriptor) {
-      ensureIsMutable();
-      fields.remove(descriptor);
-      if (fields.isEmpty()) {
-        hasLazyField = false;
-      }
-    }
-
-    /**
-     * Useful for implementing {@link Message#getRepeatedFieldCount(Descriptors.FieldDescriptor)}.
-     */
-    public int getRepeatedFieldCount(final T descriptor) {
-      if (!descriptor.isRepeated()) {
-        throw new IllegalArgumentException(
-            "getRepeatedField() can only be called on repeated fields.");
-      }
-
-      final Object value = getField(descriptor);
-      if (value == null) {
-        return 0;
-      } else {
-        return ((List<?>) value).size();
-      }
-    }
-
-    /**
-     * Useful for implementing {@link Message#getRepeatedField(Descriptors.FieldDescriptor, int)}.
-     */
-    public Object getRepeatedField(final T descriptor, final int index) {
-      if (hasNestedBuilders) {
-        ensureIsMutable();
-      }
-      Object value = getRepeatedFieldAllowBuilders(descriptor, index);
-      return replaceBuilder(value);
-    }
-
-    /**
-     * Same as {@link #getRepeatedField(F, int)}, but allow a {@link MessageLite.Builder} to be
-     * returned.
-     */
-    Object getRepeatedFieldAllowBuilders(final T descriptor, final int index) {
-      if (!descriptor.isRepeated()) {
-        throw new IllegalArgumentException(
-            "getRepeatedField() can only be called on repeated fields.");
-      }
-
-      final Object value = getFieldAllowBuilders(descriptor);
-
-      if (value == null) {
-        throw new IndexOutOfBoundsException();
-      } else {
-        return ((List<?>) value).get(index);
-      }
-    }
-
-    /**
-     * Useful for implementing {@link Message.Builder#setRepeatedField(Descriptors.FieldDescriptor,
-     * int, Object)}.
-     */
-    @SuppressWarnings("unchecked")
-    public void setRepeatedField(final T descriptor, final int index, final Object value) {
-      ensureIsMutable();
-      if (!descriptor.isRepeated()) {
-        throw new IllegalArgumentException(
-            "getRepeatedField() can only be called on repeated fields.");
-      }
-
-      hasNestedBuilders = hasNestedBuilders || value instanceof MessageLite.Builder;
-
-      final Object list = getField(descriptor);
-      if (list == null) {
-        throw new IndexOutOfBoundsException();
-      }
-
-      verifyType(descriptor, value);
-      ((List<Object>) list).set(index, value);
-    }
-
-    /**
-     * Useful for implementing {@link Message.Builder#addRepeatedField(Descriptors.FieldDescriptor,
-     * Object)}.
-     */
-    @SuppressWarnings("unchecked")
-    public void addRepeatedField(final T descriptor, final Object value) {
-      ensureIsMutable();
-      if (!descriptor.isRepeated()) {
-        throw new IllegalArgumentException(
-            "addRepeatedField() can only be called on repeated fields.");
-      }
-
-      hasNestedBuilders = hasNestedBuilders || value instanceof MessageLite.Builder;
-
-      verifyType(descriptor, value);
-
-      final Object existingValue = getField(descriptor);
-      List<Object> list;
-      if (existingValue == null) {
-        list = new ArrayList<>();
-        fields.put(descriptor, list);
-      } else {
-        list = (List<Object>) existingValue;
-      }
-
-      list.add(value);
-    }
-
-    /**
-     * Verifies that the given object is of the correct type to be a valid value for the given
-     * field. (For repeated fields, this checks if the object is the right type to be one element of
-     * the field.)
-     *
-     * @throws IllegalArgumentException The value is not of the right type.
-     */
-    private void verifyType(final T descriptor, final Object value) {
-      if (!FieldSet.isValidType(descriptor.getLiteType(), value)) {
-        // Builder can accept Message.Builder values even though FieldSet will reject.
-        if (descriptor.getLiteType().getJavaType() == WireFormat.JavaType.MESSAGE
-            && value instanceof MessageLite.Builder) {
-          return;
-        }
-        throw new IllegalArgumentException(
-            String.format(
-                "Wrong object type used with protocol message reflection.\n"
-                + "Field number: %d, field java type: %s, value type: %s\n",
-                descriptor.getNumber(),
-                descriptor.getLiteType().getJavaType(),
-                value.getClass().getName()));
-      }
-    }
-
-    /**
-     * See {@link Message#isInitialized()}. Note: Since {@code FieldSet} itself does not have any
-     * way of knowing about required fields that aren't actually present in the set, it is up to the
-     * caller to check that all required fields are present.
-     */
-    public boolean isInitialized() {
-      for (int i = 0; i < fields.getNumArrayEntries(); i++) {
-        if (!FieldSet.isInitialized(fields.getArrayEntryAt(i))) {
-          return false;
-        }
-      }
-      for (final Map.Entry<T, Object> entry : fields.getOverflowEntries()) {
-        if (!FieldSet.isInitialized(entry)) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    /**
-     * Like {@link Message.Builder#mergeFrom(Message)}, but merges from another {@link FieldSet}.
-     */
-    public void mergeFrom(final FieldSet<T> other) {
-      ensureIsMutable();
-      for (int i = 0; i < other.fields.getNumArrayEntries(); i++) {
-        mergeFromField(other.fields.getArrayEntryAt(i));
-      }
-      for (final Map.Entry<T, Object> entry : other.fields.getOverflowEntries()) {
-        mergeFromField(entry);
-      }
-    }
-
-    @SuppressWarnings({"unchecked", "rawtypes"})
-    private void mergeFromField(final Map.Entry<T, Object> entry) {
-      final T descriptor = entry.getKey();
-      Object otherValue = entry.getValue();
-      if (otherValue instanceof LazyField) {
-        otherValue = ((LazyField) otherValue).getValue();
-      }
-
-      if (descriptor.isRepeated()) {
-        Object value = getField(descriptor);
-        if (value == null) {
-          value = new ArrayList<>();
-        }
-        for (Object element : (List) otherValue) {
-          ((List) value).add(FieldSet.cloneIfMutable(element));
-        }
-        fields.put(descriptor, value);
-      } else if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) {
-        Object value = getField(descriptor);
-        if (value == null) {
-          fields.put(descriptor, FieldSet.cloneIfMutable(otherValue));
-        } else {
-          // Merge the messages.
-          if (value instanceof MessageLite.Builder) {
-            descriptor.internalMergeFrom((MessageLite.Builder) value, (MessageLite) otherValue);
-          } else {
-            value =
-                descriptor
-                    .internalMergeFrom(((MessageLite) value).toBuilder(), (MessageLite) otherValue)
-                    .build();
-            fields.put(descriptor, value);
-          }
-        }
-      } else {
-        fields.put(descriptor, cloneIfMutable(otherValue));
-      }
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldType.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldType.java
deleted file mode 100644
index 7232753..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FieldType.java
+++ /dev/null
@@ -1,344 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.util.List;
-
-/** Enumeration identifying all relevant type information for a protobuf field. */
-@ExperimentalApi
-public enum FieldType {
-  DOUBLE(0, Collection.SCALAR, JavaType.DOUBLE),
-  FLOAT(1, Collection.SCALAR, JavaType.FLOAT),
-  INT64(2, Collection.SCALAR, JavaType.LONG),
-  UINT64(3, Collection.SCALAR, JavaType.LONG),
-  INT32(4, Collection.SCALAR, JavaType.INT),
-  FIXED64(5, Collection.SCALAR, JavaType.LONG),
-  FIXED32(6, Collection.SCALAR, JavaType.INT),
-  BOOL(7, Collection.SCALAR, JavaType.BOOLEAN),
-  STRING(8, Collection.SCALAR, JavaType.STRING),
-  MESSAGE(9, Collection.SCALAR, JavaType.MESSAGE),
-  BYTES(10, Collection.SCALAR, JavaType.BYTE_STRING),
-  UINT32(11, Collection.SCALAR, JavaType.INT),
-  ENUM(12, Collection.SCALAR, JavaType.ENUM),
-  SFIXED32(13, Collection.SCALAR, JavaType.INT),
-  SFIXED64(14, Collection.SCALAR, JavaType.LONG),
-  SINT32(15, Collection.SCALAR, JavaType.INT),
-  SINT64(16, Collection.SCALAR, JavaType.LONG),
-  GROUP(17, Collection.SCALAR, JavaType.MESSAGE),
-  DOUBLE_LIST(18, Collection.VECTOR, JavaType.DOUBLE),
-  FLOAT_LIST(19, Collection.VECTOR, JavaType.FLOAT),
-  INT64_LIST(20, Collection.VECTOR, JavaType.LONG),
-  UINT64_LIST(21, Collection.VECTOR, JavaType.LONG),
-  INT32_LIST(22, Collection.VECTOR, JavaType.INT),
-  FIXED64_LIST(23, Collection.VECTOR, JavaType.LONG),
-  FIXED32_LIST(24, Collection.VECTOR, JavaType.INT),
-  BOOL_LIST(25, Collection.VECTOR, JavaType.BOOLEAN),
-  STRING_LIST(26, Collection.VECTOR, JavaType.STRING),
-  MESSAGE_LIST(27, Collection.VECTOR, JavaType.MESSAGE),
-  BYTES_LIST(28, Collection.VECTOR, JavaType.BYTE_STRING),
-  UINT32_LIST(29, Collection.VECTOR, JavaType.INT),
-  ENUM_LIST(30, Collection.VECTOR, JavaType.ENUM),
-  SFIXED32_LIST(31, Collection.VECTOR, JavaType.INT),
-  SFIXED64_LIST(32, Collection.VECTOR, JavaType.LONG),
-  SINT32_LIST(33, Collection.VECTOR, JavaType.INT),
-  SINT64_LIST(34, Collection.VECTOR, JavaType.LONG),
-  DOUBLE_LIST_PACKED(35, Collection.PACKED_VECTOR, JavaType.DOUBLE),
-  FLOAT_LIST_PACKED(36, Collection.PACKED_VECTOR, JavaType.FLOAT),
-  INT64_LIST_PACKED(37, Collection.PACKED_VECTOR, JavaType.LONG),
-  UINT64_LIST_PACKED(38, Collection.PACKED_VECTOR, JavaType.LONG),
-  INT32_LIST_PACKED(39, Collection.PACKED_VECTOR, JavaType.INT),
-  FIXED64_LIST_PACKED(40, Collection.PACKED_VECTOR, JavaType.LONG),
-  FIXED32_LIST_PACKED(41, Collection.PACKED_VECTOR, JavaType.INT),
-  BOOL_LIST_PACKED(42, Collection.PACKED_VECTOR, JavaType.BOOLEAN),
-  UINT32_LIST_PACKED(43, Collection.PACKED_VECTOR, JavaType.INT),
-  ENUM_LIST_PACKED(44, Collection.PACKED_VECTOR, JavaType.ENUM),
-  SFIXED32_LIST_PACKED(45, Collection.PACKED_VECTOR, JavaType.INT),
-  SFIXED64_LIST_PACKED(46, Collection.PACKED_VECTOR, JavaType.LONG),
-  SINT32_LIST_PACKED(47, Collection.PACKED_VECTOR, JavaType.INT),
-  SINT64_LIST_PACKED(48, Collection.PACKED_VECTOR, JavaType.LONG),
-  GROUP_LIST(49, Collection.VECTOR, JavaType.MESSAGE),
-  MAP(50, Collection.MAP, JavaType.VOID);
-
-  private final JavaType javaType;
-  private final int id;
-  private final Collection collection;
-  private final Class<?> elementType;
-  private final boolean primitiveScalar;
-
-  FieldType(int id, Collection collection, JavaType javaType) {
-    this.id = id;
-    this.collection = collection;
-    this.javaType = javaType;
-
-    switch (collection) {
-      case MAP:
-        elementType = javaType.getBoxedType();
-        break;
-      case VECTOR:
-        elementType = javaType.getBoxedType();
-        break;
-      case SCALAR:
-      default:
-        elementType = null;
-        break;
-    }
-
-    boolean primitiveScalar = false;
-    if (collection == Collection.SCALAR) {
-      switch (javaType) {
-        case BYTE_STRING:
-        case MESSAGE:
-        case STRING:
-          break;
-        default:
-          primitiveScalar = true;
-          break;
-      }
-    }
-    this.primitiveScalar = primitiveScalar;
-  }
-
-  /** A reliable unique identifier for this type. */
-  public int id() {
-    return id;
-  }
-
-  /**
-   * Gets the {@link JavaType} for this field. For lists, this identifies the type of the elements
-   * contained within the list.
-   */
-  public JavaType getJavaType() {
-    return javaType;
-  }
-
-  /** Indicates whether a list field should be represented on the wire in packed form. */
-  public boolean isPacked() {
-    return Collection.PACKED_VECTOR.equals(collection);
-  }
-
-  /**
-   * Indicates whether this field type represents a primitive scalar value. If this is {@code true},
-   * then {@link #isScalar()} will also be {@code true}.
-   */
-  public boolean isPrimitiveScalar() {
-    return primitiveScalar;
-  }
-
-  /** Indicates whether this field type represents a scalar value. */
-  public boolean isScalar() {
-    return collection == Collection.SCALAR;
-  }
-
-  /** Indicates whether this field represents a list of values. */
-  public boolean isList() {
-    return collection.isList();
-  }
-
-  /** Indicates whether this field represents a map. */
-  public boolean isMap() {
-    return collection == Collection.MAP;
-  }
-
-  /** Indicates whether or not this {@link FieldType} can be applied to the given {@link Field}. */
-  public boolean isValidForField(Field field) {
-    if (Collection.VECTOR.equals(collection)) {
-      return isValidForList(field);
-    } else {
-      return javaType.getType().isAssignableFrom(field.getType());
-    }
-  }
-
-  private boolean isValidForList(Field field) {
-    Class<?> clazz = field.getType();
-    if (!javaType.getType().isAssignableFrom(clazz)) {
-      // The field isn't a List type.
-      return false;
-    }
-    Type[] types = EMPTY_TYPES;
-    Type genericType = field.getGenericType();
-    if (genericType instanceof ParameterizedType) {
-      types = ((ParameterizedType) field.getGenericType()).getActualTypeArguments();
-    }
-    Type listParameter = getListParameter(clazz, types);
-    if (!(listParameter instanceof Class)) {
-      // It's a wildcard, we should allow anything in the list.
-      return true;
-    }
-    return elementType.isAssignableFrom((Class<?>) listParameter);
-  }
-
-  /**
-   * Looks up the appropriate {@link FieldType} by it's identifier.
-   *
-   * @return the {@link FieldType} or {@code null} if not found.
-   */
-  public static FieldType forId(int id) {
-    if (id < 0 || id >= VALUES.length) {
-      return null;
-    }
-    return VALUES[id];
-  }
-
-  private static final FieldType[] VALUES;
-  private static final Type[] EMPTY_TYPES = new Type[0];
-
-  static {
-    FieldType[] values = values();
-    VALUES = new FieldType[values.length];
-    for (FieldType type : values) {
-      VALUES[type.id] = type;
-    }
-  }
-
-  /**
-   * Given a class, finds a generic super class or interface that extends {@link List}.
-   *
-   * @return the generic super class/interface, or {@code null} if not found.
-   */
-  private static Type getGenericSuperList(Class<?> clazz) {
-    // First look at interfaces.
-    Type[] genericInterfaces = clazz.getGenericInterfaces();
-    for (Type genericInterface : genericInterfaces) {
-      if (genericInterface instanceof ParameterizedType) {
-        ParameterizedType parameterizedType = (ParameterizedType) genericInterface;
-        Class<?> rawType = (Class<?>) parameterizedType.getRawType();
-        if (List.class.isAssignableFrom(rawType)) {
-          return genericInterface;
-        }
-      }
-    }
-
-    // Try the subclass
-    Type type = clazz.getGenericSuperclass();
-    if (type instanceof ParameterizedType) {
-      ParameterizedType parameterizedType = (ParameterizedType) type;
-      Class<?> rawType = (Class<?>) parameterizedType.getRawType();
-      if (List.class.isAssignableFrom(rawType)) {
-        return type;
-      }
-    }
-
-    // No super class/interface extends List.
-    return null;
-  }
-
-  /**
-   * Inspects the inheritance hierarchy for the given class and finds the generic type parameter for
-   * {@link List}.
-   *
-   * @param clazz the class to begin the search.
-   * @param realTypes the array of actual type parameters for {@code clazz}. These will be used to
-   *     substitute generic parameters up the inheritance hierarchy. If {@code clazz} does not have
-   *     any generic parameters, this list should be empty.
-   * @return the {@link List} parameter.
-   */
-  private static Type getListParameter(Class<?> clazz, Type[] realTypes) {
-    top:
-    while (clazz != List.class) {
-      // First look at generic subclass and interfaces.
-      Type genericType = getGenericSuperList(clazz);
-      if (genericType instanceof ParameterizedType) {
-        // Replace any generic parameters with the real values.
-        ParameterizedType parameterizedType = (ParameterizedType) genericType;
-        Type[] superArgs = parameterizedType.getActualTypeArguments();
-        for (int i = 0; i < superArgs.length; ++i) {
-          Type superArg = superArgs[i];
-          if (superArg instanceof TypeVariable) {
-            // Get the type variables for this class so that we can match them to the variables
-            // used on the super class.
-            TypeVariable<?>[] clazzParams = clazz.getTypeParameters();
-            if (realTypes.length != clazzParams.length) {
-              throw new RuntimeException("Type array mismatch");
-            }
-
-            // Replace the variable parameter with the real type.
-            boolean foundReplacement = false;
-            for (int j = 0; j < clazzParams.length; ++j) {
-              if (superArg == clazzParams[j]) {
-                Type realType = realTypes[j];
-                superArgs[i] = realType;
-                foundReplacement = true;
-                break;
-              }
-            }
-            if (!foundReplacement) {
-              throw new RuntimeException("Unable to find replacement for " + superArg);
-            }
-          }
-        }
-
-        Class<?> parent = (Class<?>) parameterizedType.getRawType();
-
-        realTypes = superArgs;
-        clazz = parent;
-        continue;
-      }
-
-      // None of the parameterized types inherit List. Just continue up the inheritance hierarchy
-      // toward the List interface until we can identify the parameters.
-      realTypes = EMPTY_TYPES;
-      for (Class<?> iface : clazz.getInterfaces()) {
-        if (List.class.isAssignableFrom(iface)) {
-          clazz = iface;
-          continue top;
-        }
-      }
-      clazz = clazz.getSuperclass();
-    }
-
-    if (realTypes.length != 1) {
-      throw new RuntimeException("Unable to identify parameter type for List<T>");
-    }
-    return realTypes[0];
-  }
-
-  enum Collection {
-    SCALAR(false),
-    VECTOR(true),
-    PACKED_VECTOR(true),
-    MAP(false);
-
-    private final boolean isList;
-
-    Collection(boolean isList) {
-      this.isList = isList;
-    }
-
-    /** @return the isList */
-    public boolean isList() {
-      return isList;
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FloatArrayList.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/FloatArrayList.java
deleted file mode 100644
index e6feba8..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FloatArrayList.java
+++ /dev/null
@@ -1,297 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.Internal.checkNotNull;
-
-import com.google.protobuf.Internal.FloatList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.RandomAccess;
-
-/**
- * An implementation of {@link FloatList} on top of a primitive array.
- *
- * @author dweis@google.com (Daniel Weis)
- */
-final class FloatArrayList extends AbstractProtobufList<Float>
-    implements FloatList, RandomAccess, PrimitiveNonBoxingCollection {
-
-  private static final FloatArrayList EMPTY_LIST = new FloatArrayList(new float[0], 0);
-  static {
-    EMPTY_LIST.makeImmutable();
-  }
-
-  public static FloatArrayList emptyList() {
-    return EMPTY_LIST;
-  }
-
-  /** The backing store for the list. */
-  private float[] array;
-
-  /**
-   * The size of the list distinct from the length of the array. That is, it is the number of
-   * elements set in the list.
-   */
-  private int size;
-
-  /** Constructs a new mutable {@code FloatArrayList} with default capacity. */
-  FloatArrayList() {
-    this(new float[DEFAULT_CAPACITY], 0);
-  }
-
-  /**
-   * Constructs a new mutable {@code FloatArrayList} containing the same elements as {@code other}.
-   */
-  private FloatArrayList(float[] other, int size) {
-    array = other;
-    this.size = size;
-  }
-
-  @Override
-  protected void removeRange(int fromIndex, int toIndex) {
-    ensureIsMutable();
-    if (toIndex < fromIndex) {
-      throw new IndexOutOfBoundsException("toIndex < fromIndex");
-    }
-
-    System.arraycopy(array, toIndex, array, fromIndex, size - toIndex);
-    size -= (toIndex - fromIndex);
-    modCount++;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (!(o instanceof FloatArrayList)) {
-      return super.equals(o);
-    }
-    FloatArrayList other = (FloatArrayList) o;
-    if (size != other.size) {
-      return false;
-    }
-
-    final float[] arr = other.array;
-    for (int i = 0; i < size; i++) {
-      if (Float.floatToIntBits(array[i]) != Float.floatToIntBits(arr[i])) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = 1;
-    for (int i = 0; i < size; i++) {
-      result = (31 * result) + Float.floatToIntBits(array[i]);
-    }
-    return result;
-  }
-
-  @Override
-  public FloatList mutableCopyWithCapacity(int capacity) {
-    if (capacity < size) {
-      throw new IllegalArgumentException();
-    }
-    return new FloatArrayList(Arrays.copyOf(array, capacity), size);
-  }
-
-  @Override
-  public Float get(int index) {
-    return getFloat(index);
-  }
-
-  @Override
-  public float getFloat(int index) {
-    ensureIndexInRange(index);
-    return array[index];
-  }
-
-  @Override
-  public int indexOf(Object element) {
-    if (!(element instanceof Float)) {
-      return -1;
-    }
-    float unboxedElement = (Float) element;
-    int numElems = size();
-    for (int i = 0; i < numElems; i++) {
-      if (array[i] == unboxedElement) {
-        return i;
-      }
-    }
-    return -1;
-  }
-
-  @Override
-  public boolean contains(Object element) {
-    return indexOf(element) != -1;
-  }
-
-  @Override
-  public int size() {
-    return size;
-  }
-
-  @Override
-  public Float set(int index, Float element) {
-    return setFloat(index, element);
-  }
-
-  @Override
-  public float setFloat(int index, float element) {
-    ensureIsMutable();
-    ensureIndexInRange(index);
-    float previousValue = array[index];
-    array[index] = element;
-    return previousValue;
-  }
-
-  @Override
-  public boolean add(Float element) {
-    addFloat(element);
-    return true;
-  }
-
-  @Override
-  public void add(int index, Float element) {
-    addFloat(index, element);
-  }
-
-  /** Like {@link #add(Float)} but more efficient in that it doesn't box the element. */
-  @Override
-  public void addFloat(float element) {
-    ensureIsMutable();
-    if (size == array.length) {
-      // Resize to 1.5x the size
-      int length = ((size * 3) / 2) + 1;
-      float[] newArray = new float[length];
-
-      System.arraycopy(array, 0, newArray, 0, size);
-      array = newArray;
-    }
-
-    array[size++] = element;
-  }
-
-  /** Like {@link #add(int, Float)} but more efficient in that it doesn't box the element. */
-  private void addFloat(int index, float element) {
-    ensureIsMutable();
-    if (index < 0 || index > size) {
-      throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index));
-    }
-
-    if (size < array.length) {
-      // Shift everything over to make room
-      System.arraycopy(array, index, array, index + 1, size - index);
-    } else {
-      // Resize to 1.5x the size
-      int length = ((size * 3) / 2) + 1;
-      float[] newArray = new float[length];
-
-      // Copy the first part directly
-      System.arraycopy(array, 0, newArray, 0, index);
-
-      // Copy the rest shifted over by one to make room
-      System.arraycopy(array, index, newArray, index + 1, size - index);
-      array = newArray;
-    }
-
-    array[index] = element;
-    size++;
-    modCount++;
-  }
-
-  @Override
-  public boolean addAll(Collection<? extends Float> collection) {
-    ensureIsMutable();
-
-    checkNotNull(collection);
-
-    // We specialize when adding another FloatArrayList to avoid boxing elements.
-    if (!(collection instanceof FloatArrayList)) {
-      return super.addAll(collection);
-    }
-
-    FloatArrayList list = (FloatArrayList) collection;
-    if (list.size == 0) {
-      return false;
-    }
-
-    int overflow = Integer.MAX_VALUE - size;
-    if (overflow < list.size) {
-      // We can't actually represent a list this large.
-      throw new OutOfMemoryError();
-    }
-
-    int newSize = size + list.size;
-    if (newSize > array.length) {
-      array = Arrays.copyOf(array, newSize);
-    }
-
-    System.arraycopy(list.array, 0, array, size, list.size);
-    size = newSize;
-    modCount++;
-    return true;
-  }
-
-  @Override
-  public Float remove(int index) {
-    ensureIsMutable();
-    ensureIndexInRange(index);
-    float value = array[index];
-    if (index < size - 1) {
-      System.arraycopy(array, index + 1, array, index, size - index - 1);
-    }
-    size--;
-    modCount++;
-    return value;
-  }
-
-  /**
-   * Ensures that the provided {@code index} is within the range of {@code [0, size]}. Throws an
-   * {@link IndexOutOfBoundsException} if it is not.
-   *
-   * @param index the index to verify is in range
-   */
-  private void ensureIndexInRange(int index) {
-    if (index < 0 || index >= size) {
-      throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index));
-    }
-  }
-
-  private String makeOutOfBoundsExceptionMessage(int index) {
-    return "Index:" + index + ", Size:" + size;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FloatValue.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/FloatValue.java
deleted file mode 100644
index 06e8566..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FloatValue.java
+++ /dev/null
@@ -1,276 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/wrappers.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * Wrapper message for `float`.
- * The JSON representation for `FloatValue` is JSON number.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.FloatValue}
- */
-public  final class FloatValue extends
-    com.google.protobuf.GeneratedMessageLite<
-        FloatValue, FloatValue.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.FloatValue)
-    FloatValueOrBuilder {
-  private FloatValue() {
-  }
-  public static final int VALUE_FIELD_NUMBER = 1;
-  private float value_;
-  /**
-   * <pre>
-   * The float value.
-   * </pre>
-   *
-   * <code>float value = 1;</code>
-   * @return The value.
-   */
-  @java.lang.Override
-  public float getValue() {
-    return value_;
-  }
-  /**
-   * <pre>
-   * The float value.
-   * </pre>
-   *
-   * <code>float value = 1;</code>
-   * @param value The value to set.
-   */
-  private void setValue(float value) {
-    
-    value_ = value;
-  }
-  /**
-   * <pre>
-   * The float value.
-   * </pre>
-   *
-   * <code>float value = 1;</code>
-   */
-  private void clearValue() {
-    
-    value_ = 0F;
-  }
-
-  public static com.google.protobuf.FloatValue parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.FloatValue parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.FloatValue parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.FloatValue parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.FloatValue parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.FloatValue parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.FloatValue parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.FloatValue parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.FloatValue parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.FloatValue parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.FloatValue parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.FloatValue parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.FloatValue prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * Wrapper message for `float`.
-   * The JSON representation for `FloatValue` is JSON number.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.FloatValue}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.FloatValue, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.FloatValue)
-      com.google.protobuf.FloatValueOrBuilder {
-    // Construct using com.google.protobuf.FloatValue.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * The float value.
-     * </pre>
-     *
-     * <code>float value = 1;</code>
-     * @return The value.
-     */
-    @java.lang.Override
-    public float getValue() {
-      return instance.getValue();
-    }
-    /**
-     * <pre>
-     * The float value.
-     * </pre>
-     *
-     * <code>float value = 1;</code>
-     * @param value The value to set.
-     * @return This builder for chaining.
-     */
-    public Builder setValue(float value) {
-      copyOnWrite();
-      instance.setValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The float value.
-     * </pre>
-     *
-     * <code>float value = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearValue() {
-      copyOnWrite();
-      instance.clearValue();
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.FloatValue)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.FloatValue();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "value_",
-          };
-          java.lang.String info =
-              "\u0000\u0001\u0000\u0000\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u0001";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.FloatValue> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.FloatValue.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.FloatValue>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.FloatValue)
-  private static final com.google.protobuf.FloatValue DEFAULT_INSTANCE;
-  static {
-    FloatValue defaultInstance = new FloatValue();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      FloatValue.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.FloatValue getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  public static com.google.protobuf.FloatValue of(float value) {
-    return newBuilder().setValue(value).build();
-  }
-
-  private static volatile com.google.protobuf.Parser<FloatValue> PARSER;
-
-  public static com.google.protobuf.Parser<FloatValue> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FloatValueOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/FloatValueOrBuilder.java
deleted file mode 100644
index d44feeb..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/FloatValueOrBuilder.java
+++ /dev/null
@@ -1,19 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/wrappers.proto
-
-package com.google.protobuf;
-
-public interface FloatValueOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.FloatValue)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * The float value.
-   * </pre>
-   *
-   * <code>float value = 1;</code>
-   * @return The value.
-   */
-  float getValue();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/GeneratedMessageInfoFactory.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/GeneratedMessageInfoFactory.java
deleted file mode 100644
index 3e3efb9..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/GeneratedMessageInfoFactory.java
+++ /dev/null
@@ -1,65 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-/** A factory for message info that is generated into the message itself. */
-@ExperimentalApi
-class GeneratedMessageInfoFactory implements MessageInfoFactory {
-
-  private static final GeneratedMessageInfoFactory instance = new GeneratedMessageInfoFactory();
-
-  // Disallow construction - it's a singleton.
-  private GeneratedMessageInfoFactory() {}
-
-  public static GeneratedMessageInfoFactory getInstance() {
-    return instance;
-  }
-
-  @Override
-  public boolean isSupported(Class<?> messageType) {
-    return GeneratedMessageLite.class.isAssignableFrom(messageType);
-  }
-
-  @Override
-  public MessageInfo messageInfoFor(Class<?> messageType) {
-    if (!GeneratedMessageLite.class.isAssignableFrom(messageType)) {
-      throw new IllegalArgumentException("Unsupported message type: " + messageType.getName());
-    }
-
-    try {
-      return (MessageInfo) GeneratedMessageLite.getDefaultInstance(
-          messageType.asSubclass(GeneratedMessageLite.class))
-          .buildMessageInfo();
-    } catch (Exception e) {
-      throw new RuntimeException("Unable to get message info for " + messageType.getName(), e);
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/GeneratedMessageLite.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/GeneratedMessageLite.java
deleted file mode 100644
index 7db8f32..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/GeneratedMessageLite.java
+++ /dev/null
@@ -1,1758 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream;
-import com.google.protobuf.Internal.BooleanList;
-import com.google.protobuf.Internal.DoubleList;
-import com.google.protobuf.Internal.FloatList;
-import com.google.protobuf.Internal.IntList;
-import com.google.protobuf.Internal.LongList;
-import com.google.protobuf.Internal.ProtobufList;
-import com.google.protobuf.WireFormat.FieldType;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectStreamException;
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Lite version of {@link GeneratedMessage}.
- *
- * @author kenton@google.com Kenton Varda
- */
-public abstract class GeneratedMessageLite<
-        MessageType extends GeneratedMessageLite<MessageType, BuilderType>,
-        BuilderType extends GeneratedMessageLite.Builder<MessageType, BuilderType>>
-    extends AbstractMessageLite<MessageType, BuilderType> {
-
-  /** For use by generated code only. Lazily initialized to reduce allocations. */
-  protected UnknownFieldSetLite unknownFields = UnknownFieldSetLite.getDefaultInstance();
-
-  /** For use by generated code only. */
-  protected int memoizedSerializedSize = -1;
-
-  @Override
-  @SuppressWarnings("unchecked") // Guaranteed by runtime.
-  public final Parser<MessageType> getParserForType() {
-    return (Parser<MessageType>) dynamicMethod(MethodToInvoke.GET_PARSER);
-  }
-
-  @Override
-  @SuppressWarnings("unchecked") // Guaranteed by runtime.
-  public final MessageType getDefaultInstanceForType() {
-    return (MessageType) dynamicMethod(MethodToInvoke.GET_DEFAULT_INSTANCE);
-  }
-
-  @Override
-  @SuppressWarnings("unchecked") // Guaranteed by runtime.
-  public final BuilderType newBuilderForType() {
-    return (BuilderType) dynamicMethod(MethodToInvoke.NEW_BUILDER);
-  }
-
-  /**
-   * A reflective toString function. This is primarily intended as a developer aid, while keeping
-   * binary size down. The first line of the {@code toString()} representation includes a commented
-   * version of {@code super.toString()} to act as an indicator that this should not be relied on
-   * for comparisons.
-   *
-   * <p>NOTE: This method relies on the field getter methods not being stripped or renamed by
-   * proguard. If they are, the fields will not be included in the returned string representation.
-   *
-   * <p>NOTE: This implementation is liable to change in the future, and should not be relied on in
-   * code.
-   */
-  @Override
-  public String toString() {
-    return MessageLiteToString.toString(this, super.toString());
-  }
-
-  @SuppressWarnings("unchecked") // Guaranteed by runtime
-  @Override
-  public int hashCode() {
-    if (memoizedHashCode != 0) {
-      return memoizedHashCode;
-    }
-    memoizedHashCode = Protobuf.getInstance().schemaFor(this).hashCode(this);
-    return memoizedHashCode;
-  }
-
-  @SuppressWarnings("unchecked") // Guaranteed by isInstance + runtime
-  @Override
-  public boolean equals(
-          Object other) {
-    if (this == other) {
-      return true;
-    }
-
-    if (other == null) {
-      return false;
-    }
-
-    if (this.getClass() != other.getClass()) {
-      return false;
-    }
-
-    return Protobuf.getInstance().schemaFor(this).equals(this, (MessageType) other);
-  }
-
-  // The general strategy for unknown fields is to use an UnknownFieldSetLite that is treated as
-  // mutable during the parsing constructor and immutable after. This allows us to avoid
-  // any unnecessary intermediary allocations while reducing the generated code size.
-
-  /** Lazily initializes unknown fields. */
-  private final void ensureUnknownFieldsInitialized() {
-    if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
-      unknownFields = UnknownFieldSetLite.newInstance();
-    }
-  }
-
-  /**
-   * Called by subclasses to parse an unknown field. For use by generated code only.
-   *
-   * @return {@code true} unless the tag is an end-group tag.
-   */
-  protected boolean parseUnknownField(int tag, CodedInputStream input) throws IOException {
-    // This will avoid the allocation of unknown fields when a group tag is encountered.
-    if (WireFormat.getTagWireType(tag) == WireFormat.WIRETYPE_END_GROUP) {
-      return false;
-    }
-
-    ensureUnknownFieldsInitialized();
-    return unknownFields.mergeFieldFrom(tag, input);
-  }
-
-  /** Called by subclasses to parse an unknown field. For use by generated code only. */
-  protected void mergeVarintField(int tag, int value) {
-    ensureUnknownFieldsInitialized();
-    unknownFields.mergeVarintField(tag, value);
-  }
-
-  /** Called by subclasses to parse an unknown field. For use by generated code only. */
-  protected void mergeLengthDelimitedField(int fieldNumber, ByteString value) {
-    ensureUnknownFieldsInitialized();
-    unknownFields.mergeLengthDelimitedField(fieldNumber, value);
-  }
-
-  /** Called by subclasses to complete parsing. For use by generated code only. */
-  protected void makeImmutable() {
-    Protobuf.getInstance().schemaFor(this).makeImmutable(this);
-  }
-
-  protected final <
-          MessageType extends GeneratedMessageLite<MessageType, BuilderType>,
-          BuilderType extends GeneratedMessageLite.Builder<MessageType, BuilderType>>
-      BuilderType createBuilder() {
-    return (BuilderType) dynamicMethod(MethodToInvoke.NEW_BUILDER);
-  }
-
-  protected final <
-          MessageType extends GeneratedMessageLite<MessageType, BuilderType>,
-          BuilderType extends GeneratedMessageLite.Builder<MessageType, BuilderType>>
-      BuilderType createBuilder(MessageType prototype) {
-    return ((BuilderType) createBuilder()).mergeFrom(prototype);
-  }
-
-  @Override
-  public final boolean isInitialized() {
-    return isInitialized((MessageType) this, Boolean.TRUE);
-  }
-
-  @Override
-  @SuppressWarnings("unchecked")
-  public final BuilderType toBuilder() {
-    BuilderType builder = (BuilderType) dynamicMethod(MethodToInvoke.NEW_BUILDER);
-    builder.mergeFrom((MessageType) this);
-    return builder;
-  }
-
-  /**
-   * Defines which method path to invoke in {@link GeneratedMessageLite
-   * #dynamicMethod(MethodToInvoke, Object...)}.
-   *
-   * <p>For use by generated code only.
-   */
-  public static enum MethodToInvoke {
-    // Rely on/modify instance state
-    GET_MEMOIZED_IS_INITIALIZED,
-    SET_MEMOIZED_IS_INITIALIZED,
-
-    // Rely on static state
-    BUILD_MESSAGE_INFO,
-    NEW_MUTABLE_INSTANCE,
-    NEW_BUILDER,
-    GET_DEFAULT_INSTANCE,
-    GET_PARSER;
-  }
-
-  /**
-   * A method that implements different types of operations described in {@link MethodToInvoke}.
-   * These different kinds of operations are required to implement message-level operations for
-   * builders in the runtime. This method bundles those operations to reduce the generated methods
-   * count.
-   *
-   * <ul>
-   *   <li>{@code NEW_INSTANCE} returns a new instance of the protocol buffer that has not yet been
-   *       made immutable. See {@code MAKE_IMMUTABLE}.
-   *   <li>{@code IS_INITIALIZED} returns {@code null} for false and the default instance for true.
-   *       It doesn't use or modify any memoized value.
-   *   <li>{@code GET_MEMOIZED_IS_INITIALIZED} returns the memoized {@code isInitialized} byte
-   *       value.
-   *   <li>{@code SET_MEMOIZED_IS_INITIALIZED} sets the memoized {@code isInitialized} byte value to
-   *       1 if the first parameter is not null, or to 0 if the first parameter is null.
-   *   <li>{@code NEW_BUILDER} returns a {@code BuilderType} instance.
-   * </ul>
-   *
-   * This method, plus the implementation of the Builder, enables the Builder class to be proguarded
-   * away entirely on Android.
-   *
-   * <p>For use by generated code only.
-   */
-  protected abstract Object dynamicMethod(MethodToInvoke method, Object arg0, Object arg1);
-
-  /** Same as {@link #dynamicMethod(MethodToInvoke, Object, Object)} with {@code null} padding. */
-  protected Object dynamicMethod(MethodToInvoke method, Object arg0) {
-    return dynamicMethod(method, arg0, null);
-  }
-
-  /** Same as {@link #dynamicMethod(MethodToInvoke, Object, Object)} with {@code null} padding. */
-  protected Object dynamicMethod(MethodToInvoke method) {
-    return dynamicMethod(method, null, null);
-  }
-
-  @Override
-  int getMemoizedSerializedSize() {
-    return memoizedSerializedSize;
-  }
-
-  @Override
-  void setMemoizedSerializedSize(int size) {
-    memoizedSerializedSize = size;
-  }
-
-  @Override
-  public void writeTo(CodedOutputStream output) throws IOException {
-    Protobuf.getInstance()
-        .schemaFor(this)
-        .writeTo(this, CodedOutputStreamWriter.forCodedOutput(output));
-  }
-
-  @Override
-  public int getSerializedSize() {
-    if (memoizedSerializedSize == -1) {
-      memoizedSerializedSize = Protobuf.getInstance().schemaFor(this).getSerializedSize(this);
-    }
-    return memoizedSerializedSize;
-  }
-
-  /** Constructs a {@link MessageInfo} for this message type. */
-  Object buildMessageInfo() throws Exception {
-    return dynamicMethod(MethodToInvoke.BUILD_MESSAGE_INFO);
-  }
-
-  private static Map<Object, GeneratedMessageLite<?, ?>> defaultInstanceMap =
-      new ConcurrentHashMap<Object, GeneratedMessageLite<?, ?>>();
-
-  @SuppressWarnings("unchecked")
-  static <T extends GeneratedMessageLite<?, ?>> T getDefaultInstance(Class<T> clazz) {
-    T result = (T) defaultInstanceMap.get(clazz);
-    if (result == null) {
-      // Foo.class does not initialize the class so we need to force the initialization in order to
-      // get the default instance registered.
-      try {
-        Class.forName(clazz.getName(), true, clazz.getClassLoader());
-      } catch (ClassNotFoundException e) {
-        throw new IllegalStateException("Class initialization cannot fail.", e);
-      }
-      result = (T) defaultInstanceMap.get(clazz);
-    }
-    if (result == null) {
-      // On some Samsung devices, this still doesn't return a valid value for some reason. We add a
-      // reflective fallback to keep the device running. See b/114675342.
-      result = (T) UnsafeUtil.allocateInstance(clazz).getDefaultInstanceForType();
-      // A sanity check to ensure that <clinit> was actually invoked.
-      if (result == null) {
-        throw new IllegalStateException();
-      }
-      defaultInstanceMap.put(clazz, result);
-    }
-    return result;
-  }
-
-  protected static <T extends GeneratedMessageLite<?, ?>> void registerDefaultInstance(
-      Class<T> clazz, T defaultInstance) {
-    defaultInstanceMap.put(clazz, defaultInstance);
-  }
-
-  protected static Object newMessageInfo(
-      MessageLite defaultInstance, String info, Object[] objects) {
-    return new RawMessageInfo(defaultInstance, info, objects);
-  }
-
-  /**
-   * Merge some unknown fields into the {@link UnknownFieldSetLite} for this message.
-   *
-   * <p>For use by generated code only.
-   */
-  protected final void mergeUnknownFields(UnknownFieldSetLite unknownFields) {
-    this.unknownFields = UnknownFieldSetLite.mutableCopyOf(this.unknownFields, unknownFields);
-  }
-
-  @SuppressWarnings("unchecked")
-  public abstract static class Builder<
-          MessageType extends GeneratedMessageLite<MessageType, BuilderType>,
-          BuilderType extends Builder<MessageType, BuilderType>>
-      extends AbstractMessageLite.Builder<MessageType, BuilderType> {
-
-    private final MessageType defaultInstance;
-    protected MessageType instance;
-    protected boolean isBuilt;
-
-    protected Builder(MessageType defaultInstance) {
-      this.defaultInstance = defaultInstance;
-      this.instance =
-          (MessageType) defaultInstance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
-      isBuilt = false;
-    }
-
-    /**
-     * Called before any method that would mutate the builder to ensure that it correctly copies any
-     * state before the write happens to preserve immutability guarantees.
-     */
-    protected final void copyOnWrite() {
-      if (isBuilt) {
-        copyOnWriteInternal();
-        isBuilt = false;
-      }
-    }
-
-    protected void copyOnWriteInternal() {
-      MessageType newInstance =
-          (MessageType) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
-      mergeFromInstance(newInstance, instance);
-      instance = newInstance;
-    }
-
-    @Override
-    public final boolean isInitialized() {
-      return GeneratedMessageLite.isInitialized(instance, /* shouldMemoize= */ false);
-    }
-
-    @Override
-    public final BuilderType clear() {
-      // No need to copy on write since we're dropping the instance anyways.
-      instance = (MessageType) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
-      return (BuilderType) this;
-    }
-
-    @Override
-    public BuilderType clone() {
-      BuilderType builder = (BuilderType) getDefaultInstanceForType().newBuilderForType();
-      builder.mergeFrom(buildPartial());
-      return builder;
-    }
-
-    @Override
-    public MessageType buildPartial() {
-      if (isBuilt) {
-        return instance;
-      }
-
-      instance.makeImmutable();
-
-      isBuilt = true;
-      return instance;
-    }
-
-    @Override
-    public final MessageType build() {
-      MessageType result = buildPartial();
-      if (!result.isInitialized()) {
-        throw newUninitializedMessageException(result);
-      }
-      return result;
-    }
-
-    @Override
-    protected BuilderType internalMergeFrom(MessageType message) {
-      return mergeFrom(message);
-    }
-
-    /** All subclasses implement this. */
-    public BuilderType mergeFrom(MessageType message) {
-      copyOnWrite();
-      mergeFromInstance(instance, message);
-      return (BuilderType) this;
-    }
-
-    private void mergeFromInstance(MessageType dest, MessageType src) {
-      Protobuf.getInstance().schemaFor(dest).mergeFrom(dest, src);
-    }
-
-    @Override
-    public MessageType getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    @Override
-    public BuilderType mergeFrom(
-        byte[] input, int offset, int length, ExtensionRegistryLite extensionRegistry)
-        throws InvalidProtocolBufferException {
-      copyOnWrite();
-      try {
-        Protobuf.getInstance().schemaFor(instance).mergeFrom(
-            instance, input, offset, offset + length,
-            new ArrayDecoders.Registers(extensionRegistry));
-      } catch (InvalidProtocolBufferException e) {
-        throw e;
-      } catch (IndexOutOfBoundsException e) {
-        throw InvalidProtocolBufferException.truncatedMessage();
-      } catch (IOException e) {
-        throw new RuntimeException("Reading from byte array should not throw IOException.", e);
-      }
-      return (BuilderType) this;
-    }
-
-    @Override
-    public BuilderType mergeFrom(
-        byte[] input, int offset, int length)
-        throws InvalidProtocolBufferException {
-      return mergeFrom(input, offset, length, ExtensionRegistryLite.getEmptyRegistry());
-    }
-
-    @Override
-    public BuilderType mergeFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      copyOnWrite();
-      try {
-        // TODO(yilunchong): Try to make input with type CodedInputStream.ArrayDecoder use
-        // fast path.
-        Protobuf.getInstance().schemaFor(instance).mergeFrom(
-            instance, CodedInputStreamReader.forCodedInput(input), extensionRegistry);
-      } catch (RuntimeException e) {
-        if (e.getCause() instanceof IOException) {
-          throw (IOException) e.getCause();
-        }
-        throw e;
-      }
-      return (BuilderType) this;
-    }
-  }
-
-
-  // =================================================================
-  // Extensions-related stuff
-
-  /** Lite equivalent of {@link com.google.protobuf.GeneratedMessage.ExtendableMessageOrBuilder}. */
-  public interface ExtendableMessageOrBuilder<
-          MessageType extends ExtendableMessage<MessageType, BuilderType>,
-          BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
-      extends MessageLiteOrBuilder {
-
-    /** Check if a singular extension is present. */
-    <Type> boolean hasExtension(ExtensionLite<MessageType, Type> extension);
-
-    /** Get the number of elements in a repeated extension. */
-    <Type> int getExtensionCount(ExtensionLite<MessageType, List<Type>> extension);
-
-    /** Get the value of an extension. */
-    <Type> Type getExtension(ExtensionLite<MessageType, Type> extension);
-
-    /** Get one element of a repeated extension. */
-    <Type> Type getExtension(ExtensionLite<MessageType, List<Type>> extension, int index);
-  }
-
-  /** Lite equivalent of {@link GeneratedMessage.ExtendableMessage}. */
-  public abstract static class ExtendableMessage<
-          MessageType extends ExtendableMessage<MessageType, BuilderType>,
-          BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
-      extends GeneratedMessageLite<MessageType, BuilderType>
-      implements ExtendableMessageOrBuilder<MessageType, BuilderType> {
-
-    /** Represents the set of extensions on this message. For use by generated code only. */
-    protected FieldSet<ExtensionDescriptor> extensions = FieldSet.emptySet();
-
-    @SuppressWarnings("unchecked")
-    protected final void mergeExtensionFields(final MessageType other) {
-      if (extensions.isImmutable()) {
-        extensions = extensions.clone();
-      }
-      extensions.mergeFrom(((ExtendableMessage) other).extensions);
-    }
-
-    /**
-     * Parse an unknown field or an extension. For use by generated code only.
-     *
-     * <p>For use by generated code only.
-     *
-     * @return {@code true} unless the tag is an end-group tag.
-     */
-    protected <MessageType extends MessageLite> boolean parseUnknownField(
-        MessageType defaultInstance,
-        CodedInputStream input,
-        ExtensionRegistryLite extensionRegistry,
-        int tag)
-        throws IOException {
-      int fieldNumber = WireFormat.getTagFieldNumber(tag);
-
-      // TODO(dweis): How much bytecode would be saved by not requiring the generated code to
-      //     provide the default instance?
-      GeneratedExtension<MessageType, ?> extension =
-          extensionRegistry.findLiteExtensionByNumber(defaultInstance, fieldNumber);
-
-      return parseExtension(input, extensionRegistry, extension, tag, fieldNumber);
-    }
-
-    private boolean parseExtension(
-        CodedInputStream input,
-        ExtensionRegistryLite extensionRegistry,
-        GeneratedExtension<?, ?> extension,
-        int tag,
-        int fieldNumber)
-        throws IOException {
-      int wireType = WireFormat.getTagWireType(tag);
-      boolean unknown = false;
-      boolean packed = false;
-      if (extension == null) {
-        unknown = true; // Unknown field.
-      } else if (wireType
-          == FieldSet.getWireFormatForFieldType(
-              extension.descriptor.getLiteType(), /* isPacked= */ false)) {
-        packed = false; // Normal, unpacked value.
-      } else if (extension.descriptor.isRepeated
-          && extension.descriptor.type.isPackable()
-          && wireType
-              == FieldSet.getWireFormatForFieldType(
-                  extension.descriptor.getLiteType(), /* isPacked= */ true)) {
-        packed = true; // Packed value.
-      } else {
-        unknown = true; // Wrong wire type.
-      }
-
-      if (unknown) { // Unknown field or wrong wire type.  Skip.
-        return parseUnknownField(tag, input);
-      }
-
-      ensureExtensionsAreMutable();
-
-      if (packed) {
-        int length = input.readRawVarint32();
-        int limit = input.pushLimit(length);
-        if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) {
-          while (input.getBytesUntilLimit() > 0) {
-            int rawValue = input.readEnum();
-            Object value = extension.descriptor.getEnumType().findValueByNumber(rawValue);
-            if (value == null) {
-              // If the number isn't recognized as a valid value for this
-              // enum, drop it (don't even add it to unknownFields).
-              return true;
-            }
-            extensions.addRepeatedField(
-                extension.descriptor, extension.singularToFieldSetType(value));
-          }
-        } else {
-          while (input.getBytesUntilLimit() > 0) {
-            Object value =
-                FieldSet.readPrimitiveField(
-                    input, extension.descriptor.getLiteType(), /*checkUtf8=*/ false);
-            extensions.addRepeatedField(extension.descriptor, value);
-          }
-        }
-        input.popLimit(limit);
-      } else {
-        Object value;
-        switch (extension.descriptor.getLiteJavaType()) {
-          case MESSAGE:
-            {
-              MessageLite.Builder subBuilder = null;
-              if (!extension.descriptor.isRepeated()) {
-                MessageLite existingValue = (MessageLite) extensions.getField(extension.descriptor);
-                if (existingValue != null) {
-                  subBuilder = existingValue.toBuilder();
-                }
-              }
-              if (subBuilder == null) {
-                subBuilder = extension.getMessageDefaultInstance().newBuilderForType();
-              }
-              if (extension.descriptor.getLiteType() == WireFormat.FieldType.GROUP) {
-                input.readGroup(extension.getNumber(), subBuilder, extensionRegistry);
-              } else {
-                input.readMessage(subBuilder, extensionRegistry);
-              }
-              value = subBuilder.build();
-              break;
-            }
-          case ENUM:
-            int rawValue = input.readEnum();
-            value = extension.descriptor.getEnumType().findValueByNumber(rawValue);
-            // If the number isn't recognized as a valid value for this enum,
-            // write it to unknown fields object.
-            if (value == null) {
-              mergeVarintField(fieldNumber, rawValue);
-              return true;
-            }
-            break;
-          default:
-            value =
-                FieldSet.readPrimitiveField(
-                    input, extension.descriptor.getLiteType(), /*checkUtf8=*/ false);
-            break;
-        }
-
-        if (extension.descriptor.isRepeated()) {
-          extensions.addRepeatedField(
-              extension.descriptor, extension.singularToFieldSetType(value));
-        } else {
-          extensions.setField(extension.descriptor, extension.singularToFieldSetType(value));
-        }
-      }
-      return true;
-    }
-
-    /**
-     * Parse an unknown field or an extension. For use by generated code only.
-     *
-     * <p>For use by generated code only.
-     *
-     * @return {@code true} unless the tag is an end-group tag.
-     */
-    protected <MessageType extends MessageLite> boolean parseUnknownFieldAsMessageSet(
-        MessageType defaultInstance,
-        CodedInputStream input,
-        ExtensionRegistryLite extensionRegistry,
-        int tag)
-        throws IOException {
-
-      if (tag == WireFormat.MESSAGE_SET_ITEM_TAG) {
-        mergeMessageSetExtensionFromCodedStream(defaultInstance, input, extensionRegistry);
-        return true;
-      }
-
-      // TODO(dweis): Do we really want to support non message set wire format in message sets?
-      // Full runtime does... So we do for now.
-      int wireType = WireFormat.getTagWireType(tag);
-      if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-        return parseUnknownField(defaultInstance, input, extensionRegistry, tag);
-      } else {
-        // TODO(dweis): Should we throw on invalid input? Full runtime does not...
-        return input.skipField(tag);
-      }
-    }
-
-    /**
-     * Merges the message set from the input stream; requires message set wire format.
-     *
-     * @param defaultInstance the default instance of the containing message we are parsing in
-     * @param input the stream to parse from
-     * @param extensionRegistry the registry to use when parsing
-     */
-    private <MessageType extends MessageLite> void mergeMessageSetExtensionFromCodedStream(
-        MessageType defaultInstance,
-        CodedInputStream input,
-        ExtensionRegistryLite extensionRegistry)
-        throws IOException {
-      // The wire format for MessageSet is:
-      //   message MessageSet {
-      //     repeated group Item = 1 {
-      //       required int32 typeId = 2;
-      //       required bytes message = 3;
-      //     }
-      //   }
-      // "typeId" is the extension's field number.  The extension can only be
-      // a message type, where "message" contains the encoded bytes of that
-      // message.
-      //
-      // In practice, we will probably never see a MessageSet item in which
-      // the message appears before the type ID, or where either field does not
-      // appear exactly once.  However, in theory such cases are valid, so we
-      // should be prepared to accept them.
-
-      int typeId = 0;
-      ByteString rawBytes = null; // If we encounter "message" before "typeId"
-      GeneratedExtension<?, ?> extension = null;
-
-      // Read bytes from input, if we get it's type first then parse it eagerly,
-      // otherwise we store the raw bytes in a local variable.
-      while (true) {
-        final int tag = input.readTag();
-        if (tag == 0) {
-          break;
-        }
-
-        if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) {
-          typeId = input.readUInt32();
-          if (typeId != 0) {
-            extension = extensionRegistry.findLiteExtensionByNumber(defaultInstance, typeId);
-          }
-
-        } else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) {
-          if (typeId != 0) {
-            if (extension != null) {
-              // We already know the type, so we can parse directly from the
-              // input with no copying.  Hooray!
-              eagerlyMergeMessageSetExtension(input, extension, extensionRegistry, typeId);
-              rawBytes = null;
-              continue;
-            }
-          }
-          // We haven't seen a type ID yet or we want parse message lazily.
-          rawBytes = input.readBytes();
-
-        } else { // Unknown tag. Skip it.
-          if (!input.skipField(tag)) {
-            break; // End of group
-          }
-        }
-      }
-      input.checkLastTagWas(WireFormat.MESSAGE_SET_ITEM_END_TAG);
-
-      // Process the raw bytes.
-      if (rawBytes != null && typeId != 0) { // Zero is not a valid type ID.
-        if (extension != null) { // We known the type
-          mergeMessageSetExtensionFromBytes(rawBytes, extensionRegistry, extension);
-        } else { // We don't know how to parse this. Ignore it.
-          if (rawBytes != null) {
-            mergeLengthDelimitedField(typeId, rawBytes);
-          }
-        }
-      }
-    }
-
-    private void eagerlyMergeMessageSetExtension(
-        CodedInputStream input,
-        GeneratedExtension<?, ?> extension,
-        ExtensionRegistryLite extensionRegistry,
-        int typeId)
-        throws IOException {
-      int fieldNumber = typeId;
-      int tag = WireFormat.makeTag(typeId, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-      parseExtension(input, extensionRegistry, extension, tag, fieldNumber);
-    }
-
-    private void mergeMessageSetExtensionFromBytes(
-        ByteString rawBytes,
-        ExtensionRegistryLite extensionRegistry,
-        GeneratedExtension<?, ?> extension)
-        throws IOException {
-      MessageLite.Builder subBuilder = null;
-      MessageLite existingValue = (MessageLite) extensions.getField(extension.descriptor);
-      if (existingValue != null) {
-        subBuilder = existingValue.toBuilder();
-      }
-      if (subBuilder == null) {
-        subBuilder = extension.getMessageDefaultInstance().newBuilderForType();
-      }
-      subBuilder.mergeFrom(rawBytes, extensionRegistry);
-      MessageLite value = subBuilder.build();
-
-      ensureExtensionsAreMutable()
-          .setField(extension.descriptor, extension.singularToFieldSetType(value));
-    }
-
-    FieldSet<ExtensionDescriptor> ensureExtensionsAreMutable() {
-      if (extensions.isImmutable()) {
-        extensions = extensions.clone();
-      }
-      return extensions;
-    }
-
-    private void verifyExtensionContainingType(final GeneratedExtension<MessageType, ?> extension) {
-      if (extension.getContainingTypeDefaultInstance() != getDefaultInstanceForType()) {
-        // This can only happen if someone uses unchecked operations.
-        throw new IllegalArgumentException(
-            "This extension is for a different message type.  Please make "
-                + "sure that you are not suppressing any generics type warnings.");
-      }
-    }
-
-    /** Check if a singular extension is present. */
-    @Override
-    public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extension) {
-      GeneratedExtension<MessageType, Type> extensionLite = checkIsLite(extension);
-
-      verifyExtensionContainingType(extensionLite);
-      return extensions.hasField(extensionLite.descriptor);
-    }
-
-    /** Get the number of elements in a repeated extension. */
-    @Override
-    public final <Type> int getExtensionCount(
-        final ExtensionLite<MessageType, List<Type>> extension) {
-      GeneratedExtension<MessageType, List<Type>> extensionLite = checkIsLite(extension);
-
-      verifyExtensionContainingType(extensionLite);
-      return extensions.getRepeatedFieldCount(extensionLite.descriptor);
-    }
-
-    /** Get the value of an extension. */
-    @Override
-    @SuppressWarnings("unchecked")
-    public final <Type> Type getExtension(final ExtensionLite<MessageType, Type> extension) {
-      GeneratedExtension<MessageType, Type> extensionLite = checkIsLite(extension);
-
-      verifyExtensionContainingType(extensionLite);
-      final Object value = extensions.getField(extensionLite.descriptor);
-      if (value == null) {
-        return extensionLite.defaultValue;
-      } else {
-        return (Type) extensionLite.fromFieldSetType(value);
-      }
-    }
-
-    /** Get one element of a repeated extension. */
-    @Override
-    @SuppressWarnings("unchecked")
-    public final <Type> Type getExtension(
-        final ExtensionLite<MessageType, List<Type>> extension, final int index) {
-      GeneratedExtension<MessageType, List<Type>> extensionLite = checkIsLite(extension);
-
-      verifyExtensionContainingType(extensionLite);
-      return (Type)
-          extensionLite.singularFromFieldSetType(
-              extensions.getRepeatedField(extensionLite.descriptor, index));
-    }
-
-    /** Called by subclasses to check if all extensions are initialized. */
-    protected boolean extensionsAreInitialized() {
-      return extensions.isInitialized();
-    }
-
-    /**
-     * Used by subclasses to serialize extensions. Extension ranges may be interleaved with field
-     * numbers, but we must write them in canonical (sorted by field number) order. ExtensionWriter
-     * helps us write individual ranges of extensions at once.
-     */
-    protected class ExtensionWriter {
-      // Imagine how much simpler this code would be if Java iterators had
-      // a way to get the next element without advancing the iterator.
-
-      private final Iterator<Map.Entry<ExtensionDescriptor, Object>> iter = extensions.iterator();
-      private Map.Entry<ExtensionDescriptor, Object> next;
-      private final boolean messageSetWireFormat;
-
-      private ExtensionWriter(boolean messageSetWireFormat) {
-        if (iter.hasNext()) {
-          next = iter.next();
-        }
-        this.messageSetWireFormat = messageSetWireFormat;
-      }
-
-      public void writeUntil(final int end, final CodedOutputStream output) throws IOException {
-        while (next != null && next.getKey().getNumber() < end) {
-          ExtensionDescriptor extension = next.getKey();
-          if (messageSetWireFormat
-              && extension.getLiteJavaType() == WireFormat.JavaType.MESSAGE
-              && !extension.isRepeated()) {
-            output.writeMessageSetExtension(extension.getNumber(), (MessageLite) next.getValue());
-          } else {
-            FieldSet.writeField(extension, next.getValue(), output);
-          }
-          if (iter.hasNext()) {
-            next = iter.next();
-          } else {
-            next = null;
-          }
-        }
-      }
-    }
-
-    protected ExtensionWriter newExtensionWriter() {
-      return new ExtensionWriter(false);
-    }
-
-    protected ExtensionWriter newMessageSetExtensionWriter() {
-      return new ExtensionWriter(true);
-    }
-
-    /** Called by subclasses to compute the size of extensions. */
-    protected int extensionsSerializedSize() {
-      return extensions.getSerializedSize();
-    }
-
-    protected int extensionsSerializedSizeAsMessageSet() {
-      return extensions.getMessageSetSerializedSize();
-    }
-  }
-
-  /** Lite equivalent of {@link GeneratedMessage.ExtendableBuilder}. */
-  @SuppressWarnings("unchecked")
-  public abstract static class ExtendableBuilder<
-          MessageType extends ExtendableMessage<MessageType, BuilderType>,
-          BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
-      extends Builder<MessageType, BuilderType>
-      implements ExtendableMessageOrBuilder<MessageType, BuilderType> {
-    protected ExtendableBuilder(MessageType defaultInstance) {
-      super(defaultInstance);
-    }
-
-    // For immutable message conversion.
-    void internalSetExtensionSet(FieldSet<ExtensionDescriptor> extensions) {
-      copyOnWrite();
-      instance.extensions = extensions;
-    }
-
-    @Override
-    protected void copyOnWriteInternal() {
-      super.copyOnWriteInternal();
-      instance.extensions = instance.extensions.clone();
-    }
-
-    private FieldSet<ExtensionDescriptor> ensureExtensionsAreMutable() {
-      FieldSet<ExtensionDescriptor> extensions = instance.extensions;
-      if (extensions.isImmutable()) {
-        extensions = extensions.clone();
-        instance.extensions = extensions;
-      }
-      return extensions;
-    }
-
-    @Override
-    public final MessageType buildPartial() {
-      if (isBuilt) {
-        return instance;
-      }
-
-      instance.extensions.makeImmutable();
-      return super.buildPartial();
-    }
-
-    private void verifyExtensionContainingType(final GeneratedExtension<MessageType, ?> extension) {
-      if (extension.getContainingTypeDefaultInstance() != getDefaultInstanceForType()) {
-        // This can only happen if someone uses unchecked operations.
-        throw new IllegalArgumentException(
-            "This extension is for a different message type.  Please make "
-                + "sure that you are not suppressing any generics type warnings.");
-      }
-    }
-
-    /** Check if a singular extension is present. */
-    @Override
-    public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extension) {
-      return instance.hasExtension(extension);
-    }
-
-    /** Get the number of elements in a repeated extension. */
-    @Override
-    public final <Type> int getExtensionCount(
-        final ExtensionLite<MessageType, List<Type>> extension) {
-      return instance.getExtensionCount(extension);
-    }
-
-    /** Get the value of an extension. */
-    @Override
-    @SuppressWarnings("unchecked")
-    public final <Type> Type getExtension(final ExtensionLite<MessageType, Type> extension) {
-      return instance.getExtension(extension);
-    }
-
-    /** Get one element of a repeated extension. */
-    @Override
-    @SuppressWarnings("unchecked")
-    public final <Type> Type getExtension(
-        final ExtensionLite<MessageType, List<Type>> extension, final int index) {
-      return instance.getExtension(extension, index);
-    }
-
-    /** Set the value of an extension. */
-    public final <Type> BuilderType setExtension(
-        final ExtensionLite<MessageType, Type> extension, final Type value) {
-      GeneratedExtension<MessageType, Type> extensionLite = checkIsLite(extension);
-
-      verifyExtensionContainingType(extensionLite);
-      copyOnWrite();
-      ensureExtensionsAreMutable()
-          .setField(extensionLite.descriptor, extensionLite.toFieldSetType(value));
-      return (BuilderType) this;
-    }
-
-    /** Set the value of one element of a repeated extension. */
-    public final <Type> BuilderType setExtension(
-        final ExtensionLite<MessageType, List<Type>> extension, final int index, final Type value) {
-      GeneratedExtension<MessageType, List<Type>> extensionLite = checkIsLite(extension);
-
-      verifyExtensionContainingType(extensionLite);
-      copyOnWrite();
-      ensureExtensionsAreMutable()
-          .setRepeatedField(
-              extensionLite.descriptor, index, extensionLite.singularToFieldSetType(value));
-      return (BuilderType) this;
-    }
-
-    /** Append a value to a repeated extension. */
-    public final <Type> BuilderType addExtension(
-        final ExtensionLite<MessageType, List<Type>> extension, final Type value) {
-      GeneratedExtension<MessageType, List<Type>> extensionLite = checkIsLite(extension);
-
-      verifyExtensionContainingType(extensionLite);
-      copyOnWrite();
-      ensureExtensionsAreMutable()
-          .addRepeatedField(extensionLite.descriptor, extensionLite.singularToFieldSetType(value));
-      return (BuilderType) this;
-    }
-
-    /** Clear an extension. */
-    public final BuilderType clearExtension(final ExtensionLite<MessageType, ?> extension) {
-      GeneratedExtension<MessageType, ?> extensionLite = checkIsLite(extension);
-
-      verifyExtensionContainingType(extensionLite);
-      copyOnWrite();
-      ensureExtensionsAreMutable().clearField(extensionLite.descriptor);
-      return (BuilderType) this;
-    }
-  }
-
-  // -----------------------------------------------------------------
-
-  /** For use by generated code only. */
-  public static <ContainingType extends MessageLite, Type>
-      GeneratedExtension<ContainingType, Type> newSingularGeneratedExtension(
-          final ContainingType containingTypeDefaultInstance,
-          final Type defaultValue,
-          final MessageLite messageDefaultInstance,
-          final Internal.EnumLiteMap<?> enumTypeMap,
-          final int number,
-          final WireFormat.FieldType type,
-          final Class singularType) {
-    return new GeneratedExtension<ContainingType, Type>(
-        containingTypeDefaultInstance,
-        defaultValue,
-        messageDefaultInstance,
-        new ExtensionDescriptor(
-            enumTypeMap, number, type, /* isRepeated= */ false, /* isPacked= */ false),
-        singularType);
-  }
-
-  /** For use by generated code only. */
-  public static <ContainingType extends MessageLite, Type>
-      GeneratedExtension<ContainingType, Type> newRepeatedGeneratedExtension(
-          final ContainingType containingTypeDefaultInstance,
-          final MessageLite messageDefaultInstance,
-          final Internal.EnumLiteMap<?> enumTypeMap,
-          final int number,
-          final WireFormat.FieldType type,
-          final boolean isPacked,
-          final Class singularType) {
-    @SuppressWarnings("unchecked") // Subclasses ensure Type is a List
-    Type emptyList = (Type) Collections.emptyList();
-    return new GeneratedExtension<ContainingType, Type>(
-        containingTypeDefaultInstance,
-        emptyList,
-        messageDefaultInstance,
-        new ExtensionDescriptor(enumTypeMap, number, type, /* isRepeated= */ true, isPacked),
-        singularType);
-  }
-
-  static final class ExtensionDescriptor
-      implements FieldSet.FieldDescriptorLite<ExtensionDescriptor> {
-    ExtensionDescriptor(
-        final Internal.EnumLiteMap<?> enumTypeMap,
-        final int number,
-        final WireFormat.FieldType type,
-        final boolean isRepeated,
-        final boolean isPacked) {
-      this.enumTypeMap = enumTypeMap;
-      this.number = number;
-      this.type = type;
-      this.isRepeated = isRepeated;
-      this.isPacked = isPacked;
-    }
-
-    final Internal.EnumLiteMap<?> enumTypeMap;
-    final int number;
-    final WireFormat.FieldType type;
-    final boolean isRepeated;
-    final boolean isPacked;
-
-    @Override
-    public int getNumber() {
-      return number;
-    }
-
-    @Override
-    public WireFormat.FieldType getLiteType() {
-      return type;
-    }
-
-    @Override
-    public WireFormat.JavaType getLiteJavaType() {
-      return type.getJavaType();
-    }
-
-    @Override
-    public boolean isRepeated() {
-      return isRepeated;
-    }
-
-    @Override
-    public boolean isPacked() {
-      return isPacked;
-    }
-
-    @Override
-    public Internal.EnumLiteMap<?> getEnumType() {
-      return enumTypeMap;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public MessageLite.Builder internalMergeFrom(MessageLite.Builder to, MessageLite from) {
-      return ((Builder) to).mergeFrom((GeneratedMessageLite) from);
-    }
-
-
-    @Override
-    public int compareTo(ExtensionDescriptor other) {
-      return number - other.number;
-    }
-  }
-
-  // =================================================================
-
-  /** Calls Class.getMethod and throws a RuntimeException if it fails. */
-  @SuppressWarnings("unchecked")
-  static Method getMethodOrDie(Class clazz, String name, Class... params) {
-    try {
-      return clazz.getMethod(name, params);
-    } catch (NoSuchMethodException e) {
-      throw new RuntimeException(
-          "Generated message class \"" + clazz.getName() + "\" missing method \"" + name + "\".",
-          e);
-    }
-  }
-
-  /** Calls invoke and throws a RuntimeException if it fails. */
-  static Object invokeOrDie(Method method, Object object, Object... params) {
-    try {
-      return method.invoke(object, params);
-    } catch (IllegalAccessException e) {
-      throw new RuntimeException(
-          "Couldn't use Java reflection to implement protocol message reflection.", e);
-    } catch (InvocationTargetException e) {
-      final Throwable cause = e.getCause();
-      if (cause instanceof RuntimeException) {
-        throw (RuntimeException) cause;
-      } else if (cause instanceof Error) {
-        throw (Error) cause;
-      } else {
-        throw new RuntimeException(
-            "Unexpected exception thrown by generated accessor method.", cause);
-      }
-    }
-  }
-
-
-  /**
-   * Lite equivalent to {@link GeneratedMessage.GeneratedExtension}.
-   *
-   * <p>Users should ignore the contents of this class and only use objects of this type as
-   * parameters to extension accessors and ExtensionRegistry.add().
-   */
-  public static class GeneratedExtension<ContainingType extends MessageLite, Type>
-      extends ExtensionLite<ContainingType, Type> {
-
-    /**
-     * Create a new instance with the given parameters.
-     *
-     * <p>The last parameter {@code singularType} is only needed for enum types. We store integer
-     * values for enum types in a {@link ExtendableMessage} and use Java reflection to convert an
-     * integer value back into a concrete enum object.
-     */
-    GeneratedExtension(
-        final ContainingType containingTypeDefaultInstance,
-        final Type defaultValue,
-        final MessageLite messageDefaultInstance,
-        final ExtensionDescriptor descriptor,
-        final Class singularType) {
-      // Defensive checks to verify the correct initialization order of
-      // GeneratedExtensions and their related GeneratedMessages.
-      if (containingTypeDefaultInstance == null) {
-        throw new IllegalArgumentException("Null containingTypeDefaultInstance");
-      }
-      if (descriptor.getLiteType() == WireFormat.FieldType.MESSAGE
-          && messageDefaultInstance == null) {
-        throw new IllegalArgumentException("Null messageDefaultInstance");
-      }
-      this.containingTypeDefaultInstance = containingTypeDefaultInstance;
-      this.defaultValue = defaultValue;
-      this.messageDefaultInstance = messageDefaultInstance;
-      this.descriptor = descriptor;
-    }
-
-    final ContainingType containingTypeDefaultInstance;
-    final Type defaultValue;
-    final MessageLite messageDefaultInstance;
-    final ExtensionDescriptor descriptor;
-
-    /** Default instance of the type being extended, used to identify that type. */
-    public ContainingType getContainingTypeDefaultInstance() {
-      return containingTypeDefaultInstance;
-    }
-
-    /** Get the field number. */
-    @Override
-    public int getNumber() {
-      return descriptor.getNumber();
-    }
-
-    /**
-     * If the extension is an embedded message or group, returns the default instance of the
-     * message.
-     */
-    @Override
-    public MessageLite getMessageDefaultInstance() {
-      return messageDefaultInstance;
-    }
-
-    @SuppressWarnings("unchecked")
-    Object fromFieldSetType(final Object value) {
-      if (descriptor.isRepeated()) {
-        if (descriptor.getLiteJavaType() == WireFormat.JavaType.ENUM) {
-          final List result = new ArrayList<>();
-          for (final Object element : (List) value) {
-            result.add(singularFromFieldSetType(element));
-          }
-          return result;
-        } else {
-          return value;
-        }
-      } else {
-        return singularFromFieldSetType(value);
-      }
-    }
-
-    Object singularFromFieldSetType(final Object value) {
-      if (descriptor.getLiteJavaType() == WireFormat.JavaType.ENUM) {
-        return descriptor.enumTypeMap.findValueByNumber((Integer) value);
-      } else {
-        return value;
-      }
-    }
-
-    @SuppressWarnings("unchecked")
-    Object toFieldSetType(final Object value) {
-      if (descriptor.isRepeated()) {
-        if (descriptor.getLiteJavaType() == WireFormat.JavaType.ENUM) {
-          final List result = new ArrayList<>();
-          for (final Object element : (List) value) {
-            result.add(singularToFieldSetType(element));
-          }
-          return result;
-        } else {
-          return value;
-        }
-      } else {
-        return singularToFieldSetType(value);
-      }
-    }
-
-    Object singularToFieldSetType(final Object value) {
-      if (descriptor.getLiteJavaType() == WireFormat.JavaType.ENUM) {
-        return ((Internal.EnumLite) value).getNumber();
-      } else {
-        return value;
-      }
-    }
-
-    @Override
-    public FieldType getLiteType() {
-      return descriptor.getLiteType();
-    }
-
-    @Override
-    public boolean isRepeated() {
-      return descriptor.isRepeated;
-    }
-
-    @Override
-    public Type getDefaultValue() {
-      return defaultValue;
-    }
-  }
-
-  /**
-   * A serialized (serializable) form of the generated message. Stores the message as a class name
-   * and a byte array.
-   */
-  protected static final class SerializedForm implements Serializable {
-
-    public static SerializedForm of(MessageLite message) {
-      return new SerializedForm(message);
-    }
-
-    private static final long serialVersionUID = 0L;
-
-    // since v3.6.1
-    private final Class<?> messageClass;
-    // only included for backwards compatibility before messageClass was added
-    private final String messageClassName;
-    private final byte[] asBytes;
-
-    /**
-     * Creates the serialized form by calling {@link com.google.protobuf.MessageLite#toByteArray}.
-     *
-     * @param regularForm the message to serialize
-     */
-    SerializedForm(MessageLite regularForm) {
-      messageClass = regularForm.getClass();
-      messageClassName = messageClass.getName();
-      asBytes = regularForm.toByteArray();
-    }
-
-    /**
-     * When read from an ObjectInputStream, this method converts this object back to the regular
-     * form. Part of Java's serialization magic.
-     *
-     * @return a GeneratedMessage of the type that was serialized
-     */
-    @SuppressWarnings("unchecked")
-    protected Object readResolve() throws ObjectStreamException {
-      try {
-        Class<?> messageClass = resolveMessageClass();
-        java.lang.reflect.Field defaultInstanceField =
-            messageClass.getDeclaredField("DEFAULT_INSTANCE");
-        defaultInstanceField.setAccessible(true);
-        MessageLite defaultInstance = (MessageLite) defaultInstanceField.get(null);
-        return defaultInstance.newBuilderForType().mergeFrom(asBytes).buildPartial();
-      } catch (ClassNotFoundException e) {
-        throw new RuntimeException("Unable to find proto buffer class: " + messageClassName, e);
-      } catch (NoSuchFieldException e) {
-        return readResolveFallback();
-      } catch (SecurityException e) {
-        throw new RuntimeException("Unable to call DEFAULT_INSTANCE in " + messageClassName, e);
-      } catch (IllegalAccessException e) {
-        throw new RuntimeException("Unable to call parsePartialFrom", e);
-      } catch (InvalidProtocolBufferException e) {
-        throw new RuntimeException("Unable to understand proto buffer", e);
-      }
-    }
-
-    /**
-     * @deprecated from v3.0.0-beta-3+, for compatibility with v2.5.0 and v2.6.1 generated code.
-     */
-    @Deprecated
-    private Object readResolveFallback() throws ObjectStreamException {
-      try {
-        Class<?> messageClass = resolveMessageClass();
-        java.lang.reflect.Field defaultInstanceField =
-            messageClass.getDeclaredField("defaultInstance");
-        defaultInstanceField.setAccessible(true);
-        MessageLite defaultInstance = (MessageLite) defaultInstanceField.get(null);
-        return defaultInstance.newBuilderForType()
-            .mergeFrom(asBytes)
-            .buildPartial();
-      } catch (ClassNotFoundException e) {
-        throw new RuntimeException("Unable to find proto buffer class: " + messageClassName, e);
-      } catch (NoSuchFieldException e) {
-        throw new RuntimeException("Unable to find defaultInstance in " + messageClassName, e);
-      } catch (SecurityException e) {
-        throw new RuntimeException("Unable to call defaultInstance in " + messageClassName, e);
-      } catch (IllegalAccessException e) {
-        throw new RuntimeException("Unable to call parsePartialFrom", e);
-      } catch (InvalidProtocolBufferException e) {
-        throw new RuntimeException("Unable to understand proto buffer", e);
-      }
-    }
-
-    private Class<?> resolveMessageClass() throws ClassNotFoundException {
-      return messageClass != null ? messageClass : Class.forName(messageClassName);
-    }
-  }
-
-  /** Checks that the {@link Extension} is Lite and returns it as a {@link GeneratedExtension}. */
-  private static <
-          MessageType extends ExtendableMessage<MessageType, BuilderType>,
-          BuilderType extends ExtendableBuilder<MessageType, BuilderType>,
-          T>
-      GeneratedExtension<MessageType, T> checkIsLite(ExtensionLite<MessageType, T> extension) {
-    if (!extension.isLite()) {
-      throw new IllegalArgumentException("Expected a lite extension.");
-    }
-
-    return (GeneratedExtension<MessageType, T>) extension;
-  }
-
-  /**
-   * A static helper method for checking if a message is initialized, optionally memoizing.
-   *
-   * <p>For use by generated code only.
-   */
-  protected static final <T extends GeneratedMessageLite<T, ?>> boolean isInitialized(
-      T message, boolean shouldMemoize) {
-    byte memoizedIsInitialized =
-        (Byte) message.dynamicMethod(MethodToInvoke.GET_MEMOIZED_IS_INITIALIZED);
-    if (memoizedIsInitialized == 1) {
-      return true;
-    }
-    if (memoizedIsInitialized == 0) {
-      return false;
-    }
-    boolean isInitialized = Protobuf.getInstance().schemaFor(message).isInitialized(message);
-    if (shouldMemoize) {
-      message.dynamicMethod(
-          MethodToInvoke.SET_MEMOIZED_IS_INITIALIZED, isInitialized ? message : null);
-    }
-    return isInitialized;
-  }
-
-  protected static IntList emptyIntList() {
-    return IntArrayList.emptyList();
-  }
-
-  protected static IntList mutableCopy(IntList list) {
-    int size = list.size();
-    return list.mutableCopyWithCapacity(
-        size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
-  }
-
-  protected static LongList emptyLongList() {
-    return LongArrayList.emptyList();
-  }
-
-  protected static LongList mutableCopy(LongList list) {
-    int size = list.size();
-    return list.mutableCopyWithCapacity(
-        size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
-  }
-
-  protected static FloatList emptyFloatList() {
-    return FloatArrayList.emptyList();
-  }
-
-  protected static FloatList mutableCopy(FloatList list) {
-    int size = list.size();
-    return list.mutableCopyWithCapacity(
-        size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
-  }
-
-  protected static DoubleList emptyDoubleList() {
-    return DoubleArrayList.emptyList();
-  }
-
-  protected static DoubleList mutableCopy(DoubleList list) {
-    int size = list.size();
-    return list.mutableCopyWithCapacity(
-        size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
-  }
-
-  protected static BooleanList emptyBooleanList() {
-    return BooleanArrayList.emptyList();
-  }
-
-  protected static BooleanList mutableCopy(BooleanList list) {
-    int size = list.size();
-    return list.mutableCopyWithCapacity(
-        size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
-  }
-
-  protected static <E> ProtobufList<E> emptyProtobufList() {
-    return ProtobufArrayList.emptyList();
-  }
-
-  protected static <E> ProtobufList<E> mutableCopy(ProtobufList<E> list) {
-    int size = list.size();
-    return list.mutableCopyWithCapacity(
-        size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
-  }
-
-  /**
-   * A {@link Parser} implementation that delegates to the default instance.
-   *
-   * <p>For use by generated code only.
-   */
-  protected static class DefaultInstanceBasedParser<T extends GeneratedMessageLite<T, ?>>
-      extends AbstractParser<T> {
-
-    private final T defaultInstance;
-
-    public DefaultInstanceBasedParser(T defaultInstance) {
-      this.defaultInstance = defaultInstance;
-    }
-
-    @Override
-    public T parsePartialFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
-        throws InvalidProtocolBufferException {
-      return GeneratedMessageLite.parsePartialFrom(defaultInstance, input, extensionRegistry);
-    }
-
-    @Override
-    public T parsePartialFrom(
-        byte[] input, int offset, int length, ExtensionRegistryLite extensionRegistry)
-        throws InvalidProtocolBufferException {
-      return GeneratedMessageLite.parsePartialFrom(
-          defaultInstance, input, offset, length, extensionRegistry);
-    }
-  }
-
-  /**
-   * A static helper method for parsing a partial from input using the extension registry and the
-   * instance.
-   */
-  // TODO(dweis): Should this verify that the last tag was 0?
-  static <T extends GeneratedMessageLite<T, ?>> T parsePartialFrom(
-      T instance, CodedInputStream input, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    @SuppressWarnings("unchecked") // Guaranteed by protoc
-    T result = (T) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
-    try {
-      // TODO(yilunchong): Try to make input with type CodedInpuStream.ArrayDecoder use
-      // fast path.
-      Schema<T> schema = Protobuf.getInstance().schemaFor(result);
-      schema.mergeFrom(result, CodedInputStreamReader.forCodedInput(input), extensionRegistry);
-      schema.makeImmutable(result);
-    } catch (InvalidProtocolBufferException e) {
-      if (e.getThrownFromInputStream()) {
-        e = new InvalidProtocolBufferException(e);
-      }
-      throw e.setUnfinishedMessage(result);
-    } catch (IOException e) {
-      if (e.getCause() instanceof InvalidProtocolBufferException) {
-        throw (InvalidProtocolBufferException) e.getCause();
-      }
-      throw new InvalidProtocolBufferException(e).setUnfinishedMessage(result);
-    } catch (RuntimeException e) {
-      if (e.getCause() instanceof InvalidProtocolBufferException) {
-        throw (InvalidProtocolBufferException) e.getCause();
-      }
-      throw e;
-    }
-    return result;
-  }
-
-  /** A static helper method for parsing a partial from byte array. */
-  static <T extends GeneratedMessageLite<T, ?>> T parsePartialFrom(
-      T instance, byte[] input, int offset, int length, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    @SuppressWarnings("unchecked") // Guaranteed by protoc
-    T result = (T) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
-    try {
-      Schema<T> schema = Protobuf.getInstance().schemaFor(result);
-      schema.mergeFrom(
-          result, input, offset, offset + length, new ArrayDecoders.Registers(extensionRegistry));
-      schema.makeImmutable(result);
-      if (result.memoizedHashCode != 0) {
-        throw new RuntimeException();
-      }
-    } catch (InvalidProtocolBufferException e) {
-      if (e.getThrownFromInputStream()) {
-        e = new InvalidProtocolBufferException(e);
-      }
-      throw e.setUnfinishedMessage(result);
-    } catch (IOException e) {
-      if (e.getCause() instanceof InvalidProtocolBufferException) {
-        throw (InvalidProtocolBufferException) e.getCause();
-      }
-      throw new InvalidProtocolBufferException(e).setUnfinishedMessage(result);
-    } catch (IndexOutOfBoundsException e) {
-      throw InvalidProtocolBufferException.truncatedMessage().setUnfinishedMessage(result);
-    }
-    return result;
-  }
-
-  protected static <T extends GeneratedMessageLite<T, ?>> T parsePartialFrom(
-      T defaultInstance, CodedInputStream input) throws InvalidProtocolBufferException {
-    return parsePartialFrom(defaultInstance, input, ExtensionRegistryLite.getEmptyRegistry());
-  }
-
-  /**
-   * Helper method to check if message is initialized.
-   *
-   * @throws InvalidProtocolBufferException if it is not initialized.
-   * @return The message to check.
-   */
-  private static <T extends GeneratedMessageLite<T, ?>> T checkMessageInitialized(T message)
-      throws InvalidProtocolBufferException {
-    if (message != null && !message.isInitialized()) {
-      throw message
-          .newUninitializedMessageException()
-          .asInvalidProtocolBufferException()
-          .setUnfinishedMessage(message);
-    }
-    return message;
-  }
-
-  // Validates last tag.
-  protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
-      T defaultInstance, ByteBuffer data, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    return checkMessageInitialized(
-        parseFrom(defaultInstance, CodedInputStream.newInstance(data), extensionRegistry));
-  }
-
-  // Validates last tag.
-  protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
-      T defaultInstance, ByteBuffer data) throws InvalidProtocolBufferException {
-    return parseFrom(defaultInstance, data, ExtensionRegistryLite.getEmptyRegistry());
-  }
-
-  // Validates last tag.
-  protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
-      T defaultInstance, ByteString data) throws InvalidProtocolBufferException {
-    return checkMessageInitialized(
-        parseFrom(defaultInstance, data, ExtensionRegistryLite.getEmptyRegistry()));
-  }
-
-  // Validates last tag.
-  protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
-      T defaultInstance, ByteString data, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    return checkMessageInitialized(parsePartialFrom(defaultInstance, data, extensionRegistry));
-  }
-
-  // This is a special case since we want to verify that the last tag is 0. We assume we exhaust the
-  // ByteString.
-  private static <T extends GeneratedMessageLite<T, ?>> T parsePartialFrom(
-      T defaultInstance, ByteString data, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    T message;
-    try {
-      CodedInputStream input = data.newCodedInput();
-      message = parsePartialFrom(defaultInstance, input, extensionRegistry);
-      try {
-        input.checkLastTagWas(0);
-      } catch (InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(message);
-      }
-      return message;
-    } catch (InvalidProtocolBufferException e) {
-      throw e;
-    }
-  }
-
-  // This is a special case since we want to verify that the last tag is 0. We assume we exhaust the
-  // ByteString.
-  private static <T extends GeneratedMessageLite<T, ?>> T parsePartialFrom(
-      T defaultInstance, byte[] data, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    return checkMessageInitialized(
-        parsePartialFrom(defaultInstance, data, 0, data.length, extensionRegistry));
-  }
-
-  // Validates last tag.
-  protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
-      T defaultInstance, byte[] data) throws InvalidProtocolBufferException {
-    return checkMessageInitialized(parsePartialFrom(
-        defaultInstance, data, 0, data.length, ExtensionRegistryLite.getEmptyRegistry()));
-  }
-
-  // Validates last tag.
-  protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
-      T defaultInstance, byte[] data, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    return checkMessageInitialized(
-        parsePartialFrom(defaultInstance, data, 0, data.length, extensionRegistry));
-  }
-
-  // Does not validate last tag.
-  protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
-      T defaultInstance, InputStream input) throws InvalidProtocolBufferException {
-    return checkMessageInitialized(
-        parsePartialFrom(
-            defaultInstance,
-            CodedInputStream.newInstance(input),
-            ExtensionRegistryLite.getEmptyRegistry()));
-  }
-
-  // Does not validate last tag.
-  protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
-      T defaultInstance, InputStream input, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    return checkMessageInitialized(
-        parsePartialFrom(defaultInstance, CodedInputStream.newInstance(input), extensionRegistry));
-  }
-
-  // Does not validate last tag.
-  protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
-      T defaultInstance, CodedInputStream input) throws InvalidProtocolBufferException {
-    return parseFrom(defaultInstance, input, ExtensionRegistryLite.getEmptyRegistry());
-  }
-
-  // Does not validate last tag.
-  protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
-      T defaultInstance, CodedInputStream input, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    return checkMessageInitialized(parsePartialFrom(defaultInstance, input, extensionRegistry));
-  }
-
-  // Validates last tag.
-  protected static <T extends GeneratedMessageLite<T, ?>> T parseDelimitedFrom(
-      T defaultInstance, InputStream input) throws InvalidProtocolBufferException {
-    return checkMessageInitialized(
-        parsePartialDelimitedFrom(
-            defaultInstance, input, ExtensionRegistryLite.getEmptyRegistry()));
-  }
-
-  // Validates last tag.
-  protected static <T extends GeneratedMessageLite<T, ?>> T parseDelimitedFrom(
-      T defaultInstance, InputStream input, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    return checkMessageInitialized(
-        parsePartialDelimitedFrom(defaultInstance, input, extensionRegistry));
-  }
-
-  private static <T extends GeneratedMessageLite<T, ?>> T parsePartialDelimitedFrom(
-      T defaultInstance, InputStream input, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException {
-    int size;
-    try {
-      int firstByte = input.read();
-      if (firstByte == -1) {
-        return null;
-      }
-      size = CodedInputStream.readRawVarint32(firstByte, input);
-    } catch (InvalidProtocolBufferException e) {
-      if (e.getThrownFromInputStream()) {
-        e = new InvalidProtocolBufferException(e);
-      }
-      throw e;
-    } catch (IOException e) {
-      throw new InvalidProtocolBufferException(e);
-    }
-    InputStream limitedInput = new LimitedInputStream(input, size);
-    CodedInputStream codedInput = CodedInputStream.newInstance(limitedInput);
-    T message = parsePartialFrom(defaultInstance, codedInput, extensionRegistry);
-    try {
-      codedInput.checkLastTagWas(0);
-    } catch (InvalidProtocolBufferException e) {
-      throw e.setUnfinishedMessage(message);
-    }
-    return message;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Int32Value.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Int32Value.java
deleted file mode 100644
index 290ea05..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Int32Value.java
+++ /dev/null
@@ -1,276 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/wrappers.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * Wrapper message for `int32`.
- * The JSON representation for `Int32Value` is JSON number.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.Int32Value}
- */
-public  final class Int32Value extends
-    com.google.protobuf.GeneratedMessageLite<
-        Int32Value, Int32Value.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.Int32Value)
-    Int32ValueOrBuilder {
-  private Int32Value() {
-  }
-  public static final int VALUE_FIELD_NUMBER = 1;
-  private int value_;
-  /**
-   * <pre>
-   * The int32 value.
-   * </pre>
-   *
-   * <code>int32 value = 1;</code>
-   * @return The value.
-   */
-  @java.lang.Override
-  public int getValue() {
-    return value_;
-  }
-  /**
-   * <pre>
-   * The int32 value.
-   * </pre>
-   *
-   * <code>int32 value = 1;</code>
-   * @param value The value to set.
-   */
-  private void setValue(int value) {
-    
-    value_ = value;
-  }
-  /**
-   * <pre>
-   * The int32 value.
-   * </pre>
-   *
-   * <code>int32 value = 1;</code>
-   */
-  private void clearValue() {
-    
-    value_ = 0;
-  }
-
-  public static com.google.protobuf.Int32Value parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Int32Value parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Int32Value parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Int32Value parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Int32Value parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Int32Value parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Int32Value parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Int32Value parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Int32Value parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Int32Value parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Int32Value parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Int32Value parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.Int32Value prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * Wrapper message for `int32`.
-   * The JSON representation for `Int32Value` is JSON number.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.Int32Value}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.Int32Value, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.Int32Value)
-      com.google.protobuf.Int32ValueOrBuilder {
-    // Construct using com.google.protobuf.Int32Value.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * The int32 value.
-     * </pre>
-     *
-     * <code>int32 value = 1;</code>
-     * @return The value.
-     */
-    @java.lang.Override
-    public int getValue() {
-      return instance.getValue();
-    }
-    /**
-     * <pre>
-     * The int32 value.
-     * </pre>
-     *
-     * <code>int32 value = 1;</code>
-     * @param value The value to set.
-     * @return This builder for chaining.
-     */
-    public Builder setValue(int value) {
-      copyOnWrite();
-      instance.setValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The int32 value.
-     * </pre>
-     *
-     * <code>int32 value = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearValue() {
-      copyOnWrite();
-      instance.clearValue();
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.Int32Value)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.Int32Value();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "value_",
-          };
-          java.lang.String info =
-              "\u0000\u0001\u0000\u0000\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u0004";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.Int32Value> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.Int32Value.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.Int32Value>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.Int32Value)
-  private static final com.google.protobuf.Int32Value DEFAULT_INSTANCE;
-  static {
-    Int32Value defaultInstance = new Int32Value();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      Int32Value.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.Int32Value getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  public static com.google.protobuf.Int32Value of(int value) {
-    return newBuilder().setValue(value).build();
-  }
-
-  private static volatile com.google.protobuf.Parser<Int32Value> PARSER;
-
-  public static com.google.protobuf.Parser<Int32Value> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Int32ValueOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Int32ValueOrBuilder.java
deleted file mode 100644
index d6c7890..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Int32ValueOrBuilder.java
+++ /dev/null
@@ -1,19 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/wrappers.proto
-
-package com.google.protobuf;
-
-public interface Int32ValueOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.Int32Value)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * The int32 value.
-   * </pre>
-   *
-   * <code>int32 value = 1;</code>
-   * @return The value.
-   */
-  int getValue();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Int64Value.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Int64Value.java
deleted file mode 100644
index 149609e..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Int64Value.java
+++ /dev/null
@@ -1,276 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/wrappers.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * Wrapper message for `int64`.
- * The JSON representation for `Int64Value` is JSON string.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.Int64Value}
- */
-public  final class Int64Value extends
-    com.google.protobuf.GeneratedMessageLite<
-        Int64Value, Int64Value.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.Int64Value)
-    Int64ValueOrBuilder {
-  private Int64Value() {
-  }
-  public static final int VALUE_FIELD_NUMBER = 1;
-  private long value_;
-  /**
-   * <pre>
-   * The int64 value.
-   * </pre>
-   *
-   * <code>int64 value = 1;</code>
-   * @return The value.
-   */
-  @java.lang.Override
-  public long getValue() {
-    return value_;
-  }
-  /**
-   * <pre>
-   * The int64 value.
-   * </pre>
-   *
-   * <code>int64 value = 1;</code>
-   * @param value The value to set.
-   */
-  private void setValue(long value) {
-    
-    value_ = value;
-  }
-  /**
-   * <pre>
-   * The int64 value.
-   * </pre>
-   *
-   * <code>int64 value = 1;</code>
-   */
-  private void clearValue() {
-    
-    value_ = 0L;
-  }
-
-  public static com.google.protobuf.Int64Value parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Int64Value parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Int64Value parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Int64Value parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Int64Value parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Int64Value parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Int64Value parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Int64Value parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Int64Value parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Int64Value parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Int64Value parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Int64Value parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.Int64Value prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * Wrapper message for `int64`.
-   * The JSON representation for `Int64Value` is JSON string.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.Int64Value}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.Int64Value, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.Int64Value)
-      com.google.protobuf.Int64ValueOrBuilder {
-    // Construct using com.google.protobuf.Int64Value.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * The int64 value.
-     * </pre>
-     *
-     * <code>int64 value = 1;</code>
-     * @return The value.
-     */
-    @java.lang.Override
-    public long getValue() {
-      return instance.getValue();
-    }
-    /**
-     * <pre>
-     * The int64 value.
-     * </pre>
-     *
-     * <code>int64 value = 1;</code>
-     * @param value The value to set.
-     * @return This builder for chaining.
-     */
-    public Builder setValue(long value) {
-      copyOnWrite();
-      instance.setValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The int64 value.
-     * </pre>
-     *
-     * <code>int64 value = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearValue() {
-      copyOnWrite();
-      instance.clearValue();
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.Int64Value)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.Int64Value();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "value_",
-          };
-          java.lang.String info =
-              "\u0000\u0001\u0000\u0000\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u0002";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.Int64Value> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.Int64Value.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.Int64Value>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.Int64Value)
-  private static final com.google.protobuf.Int64Value DEFAULT_INSTANCE;
-  static {
-    Int64Value defaultInstance = new Int64Value();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      Int64Value.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.Int64Value getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  public static com.google.protobuf.Int64Value of(long value) {
-    return newBuilder().setValue(value).build();
-  }
-
-  private static volatile com.google.protobuf.Parser<Int64Value> PARSER;
-
-  public static com.google.protobuf.Parser<Int64Value> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Int64ValueOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Int64ValueOrBuilder.java
deleted file mode 100644
index 30df2ee..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Int64ValueOrBuilder.java
+++ /dev/null
@@ -1,19 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/wrappers.proto
-
-package com.google.protobuf;
-
-public interface Int64ValueOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.Int64Value)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * The int64 value.
-   * </pre>
-   *
-   * <code>int64 value = 1;</code>
-   * @return The value.
-   */
-  long getValue();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/IntArrayList.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/IntArrayList.java
deleted file mode 100644
index 9daeebe..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/IntArrayList.java
+++ /dev/null
@@ -1,297 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.Internal.checkNotNull;
-
-import com.google.protobuf.Internal.IntList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.RandomAccess;
-
-/**
- * An implementation of {@link IntList} on top of a primitive array.
- *
- * @author dweis@google.com (Daniel Weis)
- */
-final class IntArrayList extends AbstractProtobufList<Integer>
-    implements IntList, RandomAccess, PrimitiveNonBoxingCollection {
-
-  private static final IntArrayList EMPTY_LIST = new IntArrayList(new int[0], 0);
-  static {
-    EMPTY_LIST.makeImmutable();
-  }
-
-  public static IntArrayList emptyList() {
-    return EMPTY_LIST;
-  }
-
-  /** The backing store for the list. */
-  private int[] array;
-
-  /**
-   * The size of the list distinct from the length of the array. That is, it is the number of
-   * elements set in the list.
-   */
-  private int size;
-
-  /** Constructs a new mutable {@code IntArrayList} with default capacity. */
-  IntArrayList() {
-    this(new int[DEFAULT_CAPACITY], 0);
-  }
-
-  /**
-   * Constructs a new mutable {@code IntArrayList} containing the same elements as {@code other}.
-   */
-  private IntArrayList(int[] other, int size) {
-    array = other;
-    this.size = size;
-  }
-
-  @Override
-  protected void removeRange(int fromIndex, int toIndex) {
-    ensureIsMutable();
-    if (toIndex < fromIndex) {
-      throw new IndexOutOfBoundsException("toIndex < fromIndex");
-    }
-
-    System.arraycopy(array, toIndex, array, fromIndex, size - toIndex);
-    size -= (toIndex - fromIndex);
-    modCount++;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (!(o instanceof IntArrayList)) {
-      return super.equals(o);
-    }
-    IntArrayList other = (IntArrayList) o;
-    if (size != other.size) {
-      return false;
-    }
-
-    final int[] arr = other.array;
-    for (int i = 0; i < size; i++) {
-      if (array[i] != arr[i]) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = 1;
-    for (int i = 0; i < size; i++) {
-      result = (31 * result) + array[i];
-    }
-    return result;
-  }
-
-  @Override
-  public IntList mutableCopyWithCapacity(int capacity) {
-    if (capacity < size) {
-      throw new IllegalArgumentException();
-    }
-    return new IntArrayList(Arrays.copyOf(array, capacity), size);
-  }
-
-  @Override
-  public Integer get(int index) {
-    return getInt(index);
-  }
-
-  @Override
-  public int getInt(int index) {
-    ensureIndexInRange(index);
-    return array[index];
-  }
-
-  @Override
-  public int indexOf(Object element) {
-    if (!(element instanceof Integer)) {
-      return -1;
-    }
-    int unboxedElement = (Integer) element;
-    int numElems = size();
-    for (int i = 0; i < numElems; i++) {
-      if (array[i] == unboxedElement) {
-        return i;
-      }
-    }
-    return -1;
-  }
-
-  @Override
-  public boolean contains(Object element) {
-    return indexOf(element) != -1;
-  }
-
-  @Override
-  public int size() {
-    return size;
-  }
-
-  @Override
-  public Integer set(int index, Integer element) {
-    return setInt(index, element);
-  }
-
-  @Override
-  public int setInt(int index, int element) {
-    ensureIsMutable();
-    ensureIndexInRange(index);
-    int previousValue = array[index];
-    array[index] = element;
-    return previousValue;
-  }
-
-  @Override
-  public boolean add(Integer element) {
-    addInt(element);
-    return true;
-  }
-
-  @Override
-  public void add(int index, Integer element) {
-    addInt(index, element);
-  }
-
-  /** Like {@link #add(Integer)} but more efficient in that it doesn't box the element. */
-  @Override
-  public void addInt(int element) {
-    ensureIsMutable();
-    if (size == array.length) {
-      // Resize to 1.5x the size
-      int length = ((size * 3) / 2) + 1;
-      int[] newArray = new int[length];
-
-      System.arraycopy(array, 0, newArray, 0, size);
-      array = newArray;
-    }
-
-    array[size++] = element;
-  }
-
-  /** Like {@link #add(int, Integer)} but more efficient in that it doesn't box the element. */
-  private void addInt(int index, int element) {
-    ensureIsMutable();
-    if (index < 0 || index > size) {
-      throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index));
-    }
-
-    if (size < array.length) {
-      // Shift everything over to make room
-      System.arraycopy(array, index, array, index + 1, size - index);
-    } else {
-      // Resize to 1.5x the size
-      int length = ((size * 3) / 2) + 1;
-      int[] newArray = new int[length];
-
-      // Copy the first part directly
-      System.arraycopy(array, 0, newArray, 0, index);
-
-      // Copy the rest shifted over by one to make room
-      System.arraycopy(array, index, newArray, index + 1, size - index);
-      array = newArray;
-    }
-
-    array[index] = element;
-    size++;
-    modCount++;
-  }
-
-  @Override
-  public boolean addAll(Collection<? extends Integer> collection) {
-    ensureIsMutable();
-
-    checkNotNull(collection);
-
-    // We specialize when adding another IntArrayList to avoid boxing elements.
-    if (!(collection instanceof IntArrayList)) {
-      return super.addAll(collection);
-    }
-
-    IntArrayList list = (IntArrayList) collection;
-    if (list.size == 0) {
-      return false;
-    }
-
-    int overflow = Integer.MAX_VALUE - size;
-    if (overflow < list.size) {
-      // We can't actually represent a list this large.
-      throw new OutOfMemoryError();
-    }
-
-    int newSize = size + list.size;
-    if (newSize > array.length) {
-      array = Arrays.copyOf(array, newSize);
-    }
-
-    System.arraycopy(list.array, 0, array, size, list.size);
-    size = newSize;
-    modCount++;
-    return true;
-  }
-
-  @Override
-  public Integer remove(int index) {
-    ensureIsMutable();
-    ensureIndexInRange(index);
-    int value = array[index];
-    if (index < size - 1) {
-      System.arraycopy(array, index + 1, array, index, size - index - 1);
-    }
-    size--;
-    modCount++;
-    return value;
-  }
-
-  /**
-   * Ensures that the provided {@code index} is within the range of {@code [0, size]}. Throws an
-   * {@link IndexOutOfBoundsException} if it is not.
-   *
-   * @param index the index to verify is in range
-   */
-  private void ensureIndexInRange(int index) {
-    if (index < 0 || index >= size) {
-      throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index));
-    }
-  }
-
-  private String makeOutOfBoundsExceptionMessage(int index) {
-    return "Index:" + index + ", Size:" + size;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Internal.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Internal.java
deleted file mode 100644
index 90643b8..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Internal.java
+++ /dev/null
@@ -1,686 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.lang.reflect.Method;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.AbstractList;
-import java.util.AbstractMap;
-import java.util.AbstractSet;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.RandomAccess;
-import java.util.Set;
-
-/**
- * The classes contained within are used internally by the Protocol Buffer library and generated
- * message implementations. They are public only because those generated messages do not reside in
- * the {@code protobuf} package. Others should not use this class directly.
- *
- * @author kenton@google.com (Kenton Varda)
- */
-public final class Internal {
-
-  private Internal() {}
-
-  static final Charset UTF_8 = Charset.forName("UTF-8");
-  static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
-
-  /** Throws an appropriate {@link NullPointerException} if the given objects is {@code null}. */
-  static <T> T checkNotNull(T obj) {
-    if (obj == null) {
-      throw new NullPointerException();
-    }
-    return obj;
-  }
-
-  /** Throws an appropriate {@link NullPointerException} if the given objects is {@code null}. */
-  static <T> T checkNotNull(T obj, String message) {
-    if (obj == null) {
-      throw new NullPointerException(message);
-    }
-    return obj;
-  }
-
-  /**
-   * Helper called by generated code to construct default values for string fields.
-   *
-   * <p>The protocol compiler does not actually contain a UTF-8 decoder -- it just pushes
-   * UTF-8-encoded text around without touching it. The one place where this presents a problem is
-   * when generating Java string literals. Unicode characters in the string literal would normally
-   * need to be encoded using a Unicode escape sequence, which would require decoding them. To get
-   * around this, protoc instead embeds the UTF-8 bytes into the generated code and leaves it to the
-   * runtime library to decode them.
-   *
-   * <p>It gets worse, though. If protoc just generated a byte array, like: new byte[] {0x12, 0x34,
-   * 0x56, 0x78} Java actually generates *code* which allocates an array and then fills in each
-   * value. This is much less efficient than just embedding the bytes directly into the bytecode. To
-   * get around this, we need another work-around. String literals are embedded directly, so protoc
-   * actually generates a string literal corresponding to the bytes. The easiest way to do this is
-   * to use the ISO-8859-1 character set, which corresponds to the first 256 characters of the
-   * Unicode range. Protoc can then use good old CEscape to generate the string.
-   *
-   * <p>So we have a string literal which represents a set of bytes which represents another string.
-   * This function -- stringDefaultValue -- converts from the generated string to the string we
-   * actually want. The generated code calls this automatically.
-   */
-  public static String stringDefaultValue(String bytes) {
-    return new String(bytes.getBytes(ISO_8859_1), UTF_8);
-  }
-
-  /**
-   * Helper called by generated code to construct default values for bytes fields.
-   *
-   * <p>This is a lot like {@link #stringDefaultValue}, but for bytes fields. In this case we only
-   * need the second of the two hacks -- allowing us to embed raw bytes as a string literal with
-   * ISO-8859-1 encoding.
-   */
-  public static ByteString bytesDefaultValue(String bytes) {
-    return ByteString.copyFrom(bytes.getBytes(ISO_8859_1));
-  }
-  /**
-   * Helper called by generated code to construct default values for bytes fields.
-   *
-   * <p>This is like {@link #bytesDefaultValue}, but returns a byte array.
-   */
-  public static byte[] byteArrayDefaultValue(String bytes) {
-    return bytes.getBytes(ISO_8859_1);
-  }
-
-  /**
-   * Helper called by generated code to construct default values for bytes fields.
-   *
-   * <p>This is like {@link #bytesDefaultValue}, but returns a ByteBuffer.
-   */
-  public static ByteBuffer byteBufferDefaultValue(String bytes) {
-    return ByteBuffer.wrap(byteArrayDefaultValue(bytes));
-  }
-
-  /**
-   * Create a new ByteBuffer and copy all the content of {@code source} ByteBuffer to the new
-   * ByteBuffer. The new ByteBuffer's limit and capacity will be source.capacity(), and its position
-   * will be 0. Note that the state of {@code source} ByteBuffer won't be changed.
-   */
-  public static ByteBuffer copyByteBuffer(ByteBuffer source) {
-    // Make a duplicate of the source ByteBuffer and read data from the
-    // duplicate. This is to avoid affecting the source ByteBuffer's state.
-    ByteBuffer temp = source.duplicate();
-    // We want to copy all the data in the source ByteBuffer, not just the
-    // remaining bytes.
-    temp.clear();
-    ByteBuffer result = ByteBuffer.allocate(temp.capacity());
-    result.put(temp);
-    result.clear();
-    return result;
-  }
-
-  /**
-   * Helper called by generated code to determine if a byte array is a valid UTF-8 encoded string
-   * such that the original bytes can be converted to a String object and then back to a byte array
-   * round tripping the bytes without loss. More precisely, returns {@code true} whenever:
-   *
-   * <pre>{@code
-   * Arrays.equals(byteString.toByteArray(),
-   *     new String(byteString.toByteArray(), "UTF-8").getBytes("UTF-8"))
-   * }</pre>
-   *
-   * <p>This method rejects "overlong" byte sequences, as well as 3-byte sequences that would map to
-   * a surrogate character, in accordance with the restricted definition of UTF-8 introduced in
-   * Unicode 3.1. Note that the UTF-8 decoder included in Oracle's JDK has been modified to also
-   * reject "overlong" byte sequences, but currently (2011) still accepts 3-byte surrogate character
-   * byte sequences.
-   *
-   * <p>See the Unicode Standard,<br>
-   * Table 3-6. <em>UTF-8 Bit Distribution</em>,<br>
-   * Table 3-7. <em>Well Formed UTF-8 Byte Sequences</em>.
-   *
-   * <p>As of 2011-02, this method simply returns the result of {@link ByteString#isValidUtf8()}.
-   * Calling that method directly is preferred.
-   *
-   * @param byteString the string to check
-   * @return whether the byte array is round trippable
-   */
-  public static boolean isValidUtf8(ByteString byteString) {
-    return byteString.isValidUtf8();
-  }
-
-  /** Like {@link #isValidUtf8(ByteString)} but for byte arrays. */
-  public static boolean isValidUtf8(byte[] byteArray) {
-    return Utf8.isValidUtf8(byteArray);
-  }
-
-  /** Helper method to get the UTF-8 bytes of a string. */
-  public static byte[] toByteArray(String value) {
-    return value.getBytes(UTF_8);
-  }
-
-  /** Helper method to convert a byte array to a string using UTF-8 encoding. */
-  public static String toStringUtf8(byte[] bytes) {
-    return new String(bytes, UTF_8);
-  }
-
-  /**
-   * Interface for an enum value or value descriptor, to be used in FieldSet. The lite library
-   * stores enum values directly in FieldSets but the full library stores EnumValueDescriptors in
-   * order to better support reflection.
-   */
-  public interface EnumLite {
-    int getNumber();
-  }
-
-  /**
-   * Interface for an object which maps integers to {@link EnumLite}s. {@link
-   * Descriptors.EnumDescriptor} implements this interface by mapping numbers to {@link
-   * Descriptors.EnumValueDescriptor}s. Additionally, every generated enum type has a static method
-   * internalGetValueMap() which returns an implementation of this type that maps numbers to enum
-   * values.
-   */
-  public interface EnumLiteMap<T extends EnumLite> {
-    T findValueByNumber(int number);
-  }
-
-  /** Interface for an object which verifies integers are in range. */
-  public interface EnumVerifier {
-    boolean isInRange(int number);
-  }
-
-  /**
-   * Helper method for implementing {@link Message#hashCode()} for longs.
-   *
-   * @see Long#hashCode()
-   */
-  public static int hashLong(long n) {
-    return (int) (n ^ (n >>> 32));
-  }
-
-  /**
-   * Helper method for implementing {@link Message#hashCode()} for booleans.
-   *
-   * @see Boolean#hashCode()
-   */
-  public static int hashBoolean(boolean b) {
-    return b ? 1231 : 1237;
-  }
-
-  /**
-   * Helper method for implementing {@link Message#hashCode()} for enums.
-   *
-   * <p>This is needed because {@link java.lang.Enum#hashCode()} is final, but we need to use the
-   * field number as the hash code to ensure compatibility between statically and dynamically
-   * generated enum objects.
-   */
-  public static int hashEnum(EnumLite e) {
-    return e.getNumber();
-  }
-
-  /** Helper method for implementing {@link Message#hashCode()} for enum lists. */
-  public static int hashEnumList(List<? extends EnumLite> list) {
-    int hash = 1;
-    for (EnumLite e : list) {
-      hash = 31 * hash + hashEnum(e);
-    }
-    return hash;
-  }
-
-  /** Helper method for implementing {@link Message#equals(Object)} for bytes field. */
-  public static boolean equals(List<byte[]> a, List<byte[]> b) {
-    if (a.size() != b.size()) return false;
-    for (int i = 0; i < a.size(); ++i) {
-      if (!Arrays.equals(a.get(i), b.get(i))) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  /** Helper method for implementing {@link Message#hashCode()} for bytes field. */
-  public static int hashCode(List<byte[]> list) {
-    int hash = 1;
-    for (byte[] bytes : list) {
-      hash = 31 * hash + hashCode(bytes);
-    }
-    return hash;
-  }
-
-  /** Helper method for implementing {@link Message#hashCode()} for bytes field. */
-  public static int hashCode(byte[] bytes) {
-    // The hash code for a byte array should be the same as the hash code for a
-    // ByteString with the same content. This is to ensure that the generated
-    // hashCode() method will return the same value as the pure reflection
-    // based hashCode() method.
-    return Internal.hashCode(bytes, 0, bytes.length);
-  }
-
-  /** Helper method for implementing {@link LiteralByteString#hashCode()}. */
-  static int hashCode(byte[] bytes, int offset, int length) {
-    // The hash code for a byte array should be the same as the hash code for a
-    // ByteString with the same content. This is to ensure that the generated
-    // hashCode() method will return the same value as the pure reflection
-    // based hashCode() method.
-    int h = Internal.partialHash(length, bytes, offset, length);
-    return h == 0 ? 1 : h;
-  }
-
-  /** Helper method for continuously hashing bytes. */
-  static int partialHash(int h, byte[] bytes, int offset, int length) {
-    for (int i = offset; i < offset + length; i++) {
-      h = h * 31 + bytes[i];
-    }
-    return h;
-  }
-
-  /** Helper method for implementing {@link Message#equals(Object)} for bytes field. */
-  public static boolean equalsByteBuffer(ByteBuffer a, ByteBuffer b) {
-    if (a.capacity() != b.capacity()) {
-      return false;
-    }
-    // ByteBuffer.equals() will only compare the remaining bytes, but we want to
-    // compare all the content.
-    return a.duplicate().clear().equals(b.duplicate().clear());
-  }
-
-  /** Helper method for implementing {@link Message#equals(Object)} for bytes field. */
-  public static boolean equalsByteBuffer(List<ByteBuffer> a, List<ByteBuffer> b) {
-    if (a.size() != b.size()) {
-      return false;
-    }
-    for (int i = 0; i < a.size(); ++i) {
-      if (!equalsByteBuffer(a.get(i), b.get(i))) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  /** Helper method for implementing {@link Message#hashCode()} for bytes field. */
-  public static int hashCodeByteBuffer(List<ByteBuffer> list) {
-    int hash = 1;
-    for (ByteBuffer bytes : list) {
-      hash = 31 * hash + hashCodeByteBuffer(bytes);
-    }
-    return hash;
-  }
-
-  private static final int DEFAULT_BUFFER_SIZE = 4096;
-
-  /** Helper method for implementing {@link Message#hashCode()} for bytes field. */
-  public static int hashCodeByteBuffer(ByteBuffer bytes) {
-    if (bytes.hasArray()) {
-      // Fast path.
-      int h = partialHash(bytes.capacity(), bytes.array(), bytes.arrayOffset(), bytes.capacity());
-      return h == 0 ? 1 : h;
-    } else {
-      // Read the data into a temporary byte array before calculating the
-      // hash value.
-      final int bufferSize =
-          bytes.capacity() > DEFAULT_BUFFER_SIZE ? DEFAULT_BUFFER_SIZE : bytes.capacity();
-      final byte[] buffer = new byte[bufferSize];
-      final ByteBuffer duplicated = bytes.duplicate();
-      duplicated.clear();
-      int h = bytes.capacity();
-      while (duplicated.remaining() > 0) {
-        final int length =
-            duplicated.remaining() <= bufferSize ? duplicated.remaining() : bufferSize;
-        duplicated.get(buffer, 0, length);
-        h = partialHash(h, buffer, 0, length);
-      }
-      return h == 0 ? 1 : h;
-    }
-  }
-
-  @SuppressWarnings("unchecked")
-  public static <T extends MessageLite> T getDefaultInstance(Class<T> clazz) {
-    try {
-      Method method = clazz.getMethod("getDefaultInstance");
-      return (T) method.invoke(method);
-    } catch (Exception e) {
-      throw new RuntimeException("Failed to get default instance for " + clazz, e);
-    }
-  }
-
-
-  /** An empty byte array constant used in generated code. */
-  public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
-
-  /** An empty byte array constant used in generated code. */
-  public static final ByteBuffer EMPTY_BYTE_BUFFER = ByteBuffer.wrap(EMPTY_BYTE_ARRAY);
-
-  /** An empty coded input stream constant used in generated code. */
-  public static final CodedInputStream EMPTY_CODED_INPUT_STREAM =
-      CodedInputStream.newInstance(EMPTY_BYTE_ARRAY);
-
-
-  /** Helper method to merge two MessageLite instances. */
-  static Object mergeMessage(Object destination, Object source) {
-    return ((MessageLite) destination).toBuilder().mergeFrom((MessageLite) source).buildPartial();
-  }
-
-  /**
-   * Provides an immutable view of {@code List<T>} around a {@code List<F>}.
-   *
-   * <p>Protobuf internal. Used in protobuf generated code only.
-   */
-  public static class ListAdapter<F, T> extends AbstractList<T> {
-    /** Convert individual elements of the List from F to T. */
-    public interface Converter<F, T> {
-      T convert(F from);
-    }
-
-    private final List<F> fromList;
-    private final Converter<F, T> converter;
-
-    public ListAdapter(List<F> fromList, Converter<F, T> converter) {
-      this.fromList = fromList;
-      this.converter = converter;
-    }
-
-    @Override
-    public T get(int index) {
-      return converter.convert(fromList.get(index));
-    }
-
-    @Override
-    public int size() {
-      return fromList.size();
-    }
-  }
-
-  /** Wrap around a {@code Map<K, RealValue>} and provide a {@code Map<K, V>} interface. */
-  public static class MapAdapter<K, V, RealValue> extends AbstractMap<K, V> {
-    /** An interface used to convert between two types. */
-    public interface Converter<A, B> {
-      B doForward(A object);
-
-      A doBackward(B object);
-    }
-
-    public static <T extends EnumLite> Converter<Integer, T> newEnumConverter(
-        final EnumLiteMap<T> enumMap, final T unrecognizedValue) {
-      return new Converter<Integer, T>() {
-        @Override
-        public T doForward(Integer value) {
-          T result = enumMap.findValueByNumber(value);
-          return result == null ? unrecognizedValue : result;
-        }
-
-        @Override
-        public Integer doBackward(T value) {
-          return value.getNumber();
-        }
-      };
-    }
-
-    private final Map<K, RealValue> realMap;
-    private final Converter<RealValue, V> valueConverter;
-
-    public MapAdapter(Map<K, RealValue> realMap, Converter<RealValue, V> valueConverter) {
-      this.realMap = realMap;
-      this.valueConverter = valueConverter;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public V get(Object key) {
-      RealValue result = realMap.get(key);
-      if (result == null) {
-        return null;
-      }
-      return valueConverter.doForward(result);
-    }
-
-    @Override
-    public V put(K key, V value) {
-      RealValue oldValue = realMap.put(key, valueConverter.doBackward(value));
-      if (oldValue == null) {
-        return null;
-      }
-      return valueConverter.doForward(oldValue);
-    }
-
-    @Override
-    public Set<java.util.Map.Entry<K, V>> entrySet() {
-      return new SetAdapter(realMap.entrySet());
-    }
-
-    private class SetAdapter extends AbstractSet<Map.Entry<K, V>> {
-      private final Set<Map.Entry<K, RealValue>> realSet;
-
-      public SetAdapter(Set<Map.Entry<K, RealValue>> realSet) {
-        this.realSet = realSet;
-      }
-
-      @Override
-      public Iterator<java.util.Map.Entry<K, V>> iterator() {
-        return new IteratorAdapter(realSet.iterator());
-      }
-
-      @Override
-      public int size() {
-        return realSet.size();
-      }
-    }
-
-    private class IteratorAdapter implements Iterator<Map.Entry<K, V>> {
-      private final Iterator<Map.Entry<K, RealValue>> realIterator;
-
-      public IteratorAdapter(Iterator<Map.Entry<K, RealValue>> realIterator) {
-        this.realIterator = realIterator;
-      }
-
-      @Override
-      public boolean hasNext() {
-        return realIterator.hasNext();
-      }
-
-      @Override
-      public java.util.Map.Entry<K, V> next() {
-        return new EntryAdapter(realIterator.next());
-      }
-
-      @Override
-      public void remove() {
-        realIterator.remove();
-      }
-    }
-
-    private class EntryAdapter implements Map.Entry<K, V> {
-      private final Map.Entry<K, RealValue> realEntry;
-
-      public EntryAdapter(Map.Entry<K, RealValue> realEntry) {
-        this.realEntry = realEntry;
-      }
-
-      @Override
-      public K getKey() {
-        return realEntry.getKey();
-      }
-
-      @Override
-      public V getValue() {
-        return valueConverter.doForward(realEntry.getValue());
-      }
-
-      @Override
-      public V setValue(V value) {
-        RealValue oldValue = realEntry.setValue(valueConverter.doBackward(value));
-        if (oldValue == null) {
-          return null;
-        }
-        return valueConverter.doForward(oldValue);
-      }
-
-      @Override
-      public boolean equals(Object o) {
-        if (o == this) {
-          return true;
-        }
-        if (!(o instanceof Map.Entry)) {
-          return false;
-        }
-        @SuppressWarnings("unchecked")
-        Map.Entry<?, ?> other = (Map.Entry<?, ?>) o;
-        return getKey().equals(other.getKey()) && getValue().equals(getValue());
-      }
-
-      @Override
-      public int hashCode() {
-        return realEntry.hashCode();
-      }
-    }
-  }
-
-  /**
-   * Extends {@link List} to add the capability to make the list immutable and inspect if it is
-   * modifiable.
-   *
-   * <p>All implementations must support efficient random access.
-   */
-  public static interface ProtobufList<E> extends List<E>, RandomAccess {
-
-    /**
-     * Makes this list immutable. All subsequent modifications will throw an {@link
-     * UnsupportedOperationException}.
-     */
-    void makeImmutable();
-
-    /**
-     * Returns whether this list can be modified via the publicly accessible {@link List} methods.
-     */
-    boolean isModifiable();
-
-    /** Returns a mutable clone of this list with the specified capacity. */
-    ProtobufList<E> mutableCopyWithCapacity(int capacity);
-  }
-
-  /**
-   * A {@link java.util.List} implementation that avoids boxing the elements into Integers if
-   * possible. Does not support null elements.
-   */
-  public static interface IntList extends ProtobufList<Integer> {
-
-    /** Like {@link #get(int)} but more efficient in that it doesn't box the returned value. */
-    int getInt(int index);
-
-    /** Like {@link #add(Object)} but more efficient in that it doesn't box the element. */
-    void addInt(int element);
-
-    /** Like {@link #set(int, Object)} but more efficient in that it doesn't box the element. */
-    int setInt(int index, int element);
-
-    /** Returns a mutable clone of this list with the specified capacity. */
-    @Override
-    IntList mutableCopyWithCapacity(int capacity);
-  }
-
-  /**
-   * A {@link java.util.List} implementation that avoids boxing the elements into Booleans if
-   * possible. Does not support null elements.
-   */
-  public static interface BooleanList extends ProtobufList<Boolean> {
-
-    /** Like {@link #get(int)} but more efficient in that it doesn't box the returned value. */
-    boolean getBoolean(int index);
-
-    /** Like {@link #add(Object)} but more efficient in that it doesn't box the element. */
-    void addBoolean(boolean element);
-
-    /** Like {@link #set(int, Object)} but more efficient in that it doesn't box the element. */
-    boolean setBoolean(int index, boolean element);
-
-    /** Returns a mutable clone of this list with the specified capacity. */
-    @Override
-    BooleanList mutableCopyWithCapacity(int capacity);
-  }
-
-  /**
-   * A {@link java.util.List} implementation that avoids boxing the elements into Longs if possible.
-   * Does not support null elements.
-   */
-  public static interface LongList extends ProtobufList<Long> {
-
-    /** Like {@link #get(int)} but more efficient in that it doesn't box the returned value. */
-    long getLong(int index);
-
-    /** Like {@link #add(Object)} but more efficient in that it doesn't box the element. */
-    void addLong(long element);
-
-    /** Like {@link #set(int, Object)} but more efficient in that it doesn't box the element. */
-    long setLong(int index, long element);
-
-    /** Returns a mutable clone of this list with the specified capacity. */
-    @Override
-    LongList mutableCopyWithCapacity(int capacity);
-  }
-
-  /**
-   * A {@link java.util.List} implementation that avoids boxing the elements into Doubles if
-   * possible. Does not support null elements.
-   */
-  public static interface DoubleList extends ProtobufList<Double> {
-
-    /** Like {@link #get(int)} but more efficient in that it doesn't box the returned value. */
-    double getDouble(int index);
-
-    /** Like {@link #add(Object)} but more efficient in that it doesn't box the element. */
-    void addDouble(double element);
-
-    /** Like {@link #set(int, Object)} but more efficient in that it doesn't box the element. */
-    double setDouble(int index, double element);
-
-    /** Returns a mutable clone of this list with the specified capacity. */
-    @Override
-    DoubleList mutableCopyWithCapacity(int capacity);
-  }
-
-  /**
-   * A {@link java.util.List} implementation that avoids boxing the elements into Floats if
-   * possible. Does not support null elements.
-   */
-  public static interface FloatList extends ProtobufList<Float> {
-
-    /** Like {@link #get(int)} but more efficient in that it doesn't box the returned value. */
-    float getFloat(int index);
-
-    /** Like {@link #add(Object)} but more efficient in that it doesn't box the element. */
-    void addFloat(float element);
-
-    /** Like {@link #set(int, Object)} but more efficient in that it doesn't box the element. */
-    float setFloat(int index, float element);
-
-    /** Returns a mutable clone of this list with the specified capacity. */
-    @Override
-    FloatList mutableCopyWithCapacity(int capacity);
-  }
-
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/InvalidProtocolBufferException.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/InvalidProtocolBufferException.java
deleted file mode 100644
index 4b43033..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/InvalidProtocolBufferException.java
+++ /dev/null
@@ -1,166 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.io.IOException;
-
-/**
- * Thrown when a protocol message being parsed is invalid in some way, e.g. it contains a malformed
- * varint or a negative byte length.
- *
- * @author kenton@google.com Kenton Varda
- */
-public class InvalidProtocolBufferException extends IOException {
-  private static final long serialVersionUID = -1616151763072450476L;
-  private MessageLite unfinishedMessage = null;
-  private boolean wasThrownFromInputStream;
-
-  public InvalidProtocolBufferException(final String description) {
-    super(description);
-  }
-
-  public InvalidProtocolBufferException(IOException e) {
-    super(e.getMessage(), e);
-  }
-
-  public InvalidProtocolBufferException(final String description, IOException e) {
-    super(description, e);
-  }
-
-  /**
-   * Attaches an unfinished message to the exception to support best-effort parsing in {@code
-   * Parser} interface.
-   *
-   * @return this
-   */
-  public InvalidProtocolBufferException setUnfinishedMessage(MessageLite unfinishedMessage) {
-    this.unfinishedMessage = unfinishedMessage;
-    return this;
-  }
-
-  /**
-   * Returns the unfinished message attached to the exception, or null if no message is attached.
-   */
-  public MessageLite getUnfinishedMessage() {
-    return unfinishedMessage;
-  }
-
-  /** Set by CodedInputStream */
-  void setThrownFromInputStream() {
-    /* This write can be racy if the same exception is stored and then thrown by multiple custom
-     * InputStreams on different threads. But since it only ever moves from false->true, there's no
-     * problem. A thread checking this condition after catching this exception from a delegate
-     * stream of CodedInputStream is guaranteed to always observe true, because a write on the same
-     * thread set the value when the exception left the delegate. A thread checking the same
-     * condition with an exception created by CodedInputStream is guaranteed to always see false,
-     * because the exception has not been exposed to any code that could publish it to other threads
-     * and cause a write.
-     */
-    wasThrownFromInputStream = true;
-  }
-
-  /**
-   * Allows code catching IOException from CodedInputStream to tell whether this instance was thrown
-   * by a delegate InputStream, rather than directly by a parse failure.
-   */
-  boolean getThrownFromInputStream() {
-    return wasThrownFromInputStream;
-  }
-
-  /**
-   * Unwraps the underlying {@link IOException} if this exception was caused by an I/O problem.
-   * Otherwise, returns {@code this}.
-   */
-  public IOException unwrapIOException() {
-    return getCause() instanceof IOException ? (IOException) getCause() : this;
-  }
-
-  static InvalidProtocolBufferException truncatedMessage() {
-    return new InvalidProtocolBufferException(
-        "While parsing a protocol message, the input ended unexpectedly "
-            + "in the middle of a field.  This could mean either that the "
-            + "input has been truncated or that an embedded message "
-            + "misreported its own length.");
-  }
-
-  static InvalidProtocolBufferException negativeSize() {
-    return new InvalidProtocolBufferException(
-        "CodedInputStream encountered an embedded string or message "
-            + "which claimed to have negative size.");
-  }
-
-  static InvalidProtocolBufferException malformedVarint() {
-    return new InvalidProtocolBufferException("CodedInputStream encountered a malformed varint.");
-  }
-
-  static InvalidProtocolBufferException invalidTag() {
-    return new InvalidProtocolBufferException("Protocol message contained an invalid tag (zero).");
-  }
-
-  static InvalidProtocolBufferException invalidEndTag() {
-    return new InvalidProtocolBufferException(
-        "Protocol message end-group tag did not match expected tag.");
-  }
-
-  static InvalidWireTypeException invalidWireType() {
-    return new InvalidWireTypeException("Protocol message tag had invalid wire type.");
-  }
-
-  /** Exception indicating that and unexpected wire type was encountered for a field. */
-  @ExperimentalApi
-  public static class InvalidWireTypeException extends InvalidProtocolBufferException {
-    private static final long serialVersionUID = 3283890091615336259L;
-
-    public InvalidWireTypeException(String description) {
-      super(description);
-    }
-  }
-
-  static InvalidProtocolBufferException recursionLimitExceeded() {
-    return new InvalidProtocolBufferException(
-        "Protocol message had too many levels of nesting.  May be malicious.  "
-            + "Use CodedInputStream.setRecursionLimit() to increase the depth limit.");
-  }
-
-  static InvalidProtocolBufferException sizeLimitExceeded() {
-    return new InvalidProtocolBufferException(
-        "Protocol message was too large.  May be malicious.  "
-            + "Use CodedInputStream.setSizeLimit() to increase the size limit.");
-  }
-
-  static InvalidProtocolBufferException parseFailure() {
-    return new InvalidProtocolBufferException("Failed to parse the message.");
-  }
-
-  static InvalidProtocolBufferException invalidUtf8() {
-    return new InvalidProtocolBufferException("Protocol message had invalid UTF-8.");
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/IterableByteBufferInputStream.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/IterableByteBufferInputStream.java
deleted file mode 100644
index 713e806..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/IterableByteBufferInputStream.java
+++ /dev/null
@@ -1,150 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.Internal.EMPTY_BYTE_BUFFER;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.util.Iterator;
-
-class IterableByteBufferInputStream extends InputStream {
-  /** The {@link Iterator} with type {@link ByteBuffer} of {@code input} */
-  private Iterator<ByteBuffer> iterator;
-  /** The current ByteBuffer; */
-  private ByteBuffer currentByteBuffer;
-  /** The number of ByteBuffers in the input data. */
-  private int dataSize;
-  /**
-   * Current {@code ByteBuffer}'s index
-   *
-   * <p>If index equals dataSize, then all the data in the InputStream has been consumed
-   */
-  private int currentIndex;
-  /** The current position for current ByteBuffer */
-  private int currentByteBufferPos;
-  /** Whether current ByteBuffer has an array */
-  private boolean hasArray;
-  /**
-   * If the current ByteBuffer is unsafe-direct based, currentArray is null; otherwise should be the
-   * array inside ByteBuffer.
-   */
-  private byte[] currentArray;
-  /** Current ByteBuffer's array offset */
-  private int currentArrayOffset;
-  /**
-   * If the current ByteBuffer is unsafe-direct based, currentAddress is the start address of this
-   * ByteBuffer; otherwise should be zero.
-   */
-  private long currentAddress;
-
-  IterableByteBufferInputStream(Iterable<ByteBuffer> data) {
-    iterator = data.iterator();
-    dataSize = 0;
-    for (ByteBuffer unused : data) {
-      dataSize++;
-    }
-    currentIndex = -1;
-
-    if (!getNextByteBuffer()) {
-      currentByteBuffer = EMPTY_BYTE_BUFFER;
-      currentIndex = 0;
-      currentByteBufferPos = 0;
-      currentAddress = 0;
-    }
-  }
-
-  private boolean getNextByteBuffer() {
-    currentIndex++;
-    if (!iterator.hasNext()) {
-      return false;
-    }
-    currentByteBuffer = iterator.next();
-    currentByteBufferPos = currentByteBuffer.position();
-    if (currentByteBuffer.hasArray()) {
-      hasArray = true;
-      currentArray = currentByteBuffer.array();
-      currentArrayOffset = currentByteBuffer.arrayOffset();
-    } else {
-      hasArray = false;
-      currentAddress = UnsafeUtil.addressOffset(currentByteBuffer);
-      currentArray = null;
-    }
-    return true;
-  }
-
-  private void updateCurrentByteBufferPos(int numberOfBytesRead) {
-    currentByteBufferPos += numberOfBytesRead;
-    if (currentByteBufferPos == currentByteBuffer.limit()) {
-      getNextByteBuffer();
-    }
-  }
-
-  @Override
-  public int read() throws IOException {
-    if (currentIndex == dataSize) {
-      return -1;
-    }
-    if (hasArray) {
-      int result = currentArray[currentByteBufferPos + currentArrayOffset] & 0xFF;
-      updateCurrentByteBufferPos(1);
-      return result;
-    } else {
-      int result = UnsafeUtil.getByte(currentByteBufferPos + currentAddress) & 0xFF;
-      updateCurrentByteBufferPos(1);
-      return result;
-    }
-  }
-
-  @Override
-  public int read(byte[] output, int offset, int length) throws IOException {
-    if (currentIndex == dataSize) {
-      return -1;
-    }
-    int remaining = currentByteBuffer.limit() - currentByteBufferPos;
-    if (length > remaining) {
-      length = remaining;
-    }
-    if (hasArray) {
-      System.arraycopy(
-          currentArray, currentByteBufferPos + currentArrayOffset, output, offset, length);
-      updateCurrentByteBufferPos(length);
-    } else {
-      int prevPos = currentByteBuffer.position();
-      currentByteBuffer.position(currentByteBufferPos);
-      currentByteBuffer.get(output, offset, length);
-      currentByteBuffer.position(prevPos);
-      updateCurrentByteBufferPos(length);
-    }
-    return length;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/JavaType.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/JavaType.java
deleted file mode 100644
index 770aa9e..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/JavaType.java
+++ /dev/null
@@ -1,76 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-/** Enum that identifies the Java types required to store protobuf fields. */
-@ExperimentalApi
-public enum JavaType {
-  VOID(Void.class, Void.class, null),
-  INT(int.class, Integer.class, 0),
-  LONG(long.class, Long.class, 0L),
-  FLOAT(float.class, Float.class, 0F),
-  DOUBLE(double.class, Double.class, 0D),
-  BOOLEAN(boolean.class, Boolean.class, false),
-  STRING(String.class, String.class, ""),
-  BYTE_STRING(ByteString.class, ByteString.class, ByteString.EMPTY),
-  ENUM(int.class, Integer.class, null),
-  MESSAGE(Object.class, Object.class, null);
-
-  private final Class<?> type;
-  private final Class<?> boxedType;
-  private final Object defaultDefault;
-
-  JavaType(Class<?> type, Class<?> boxedType, Object defaultDefault) {
-    this.type = type;
-    this.boxedType = boxedType;
-    this.defaultDefault = defaultDefault;
-  }
-
-  /** The default default value for fields of this type, if it's a primitive type. */
-  public Object getDefaultDefault() {
-    return defaultDefault;
-  }
-
-  /** Gets the required type for a field that would hold a value of this type. */
-  public Class<?> getType() {
-    return type;
-  }
-
-  /** @return the boxedType */
-  public Class<?> getBoxedType() {
-    return boxedType;
-  }
-
-  /** Indicates whether or not this {@link JavaType} can be applied to a field of the given type. */
-  public boolean isValidType(Class<?> t) {
-    return type.isAssignableFrom(t);
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/LazyField.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/LazyField.java
deleted file mode 100644
index 891171d..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/LazyField.java
+++ /dev/null
@@ -1,154 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.util.Iterator;
-import java.util.Map.Entry;
-
-/**
- * LazyField encapsulates the logic of lazily parsing message fields. It stores the message in a
- * ByteString initially and then parse it on-demand.
- *
- * <p>Most of key methods are implemented in {@link LazyFieldLite} but this class can contain
- * default instance of the message to provide {@code hashCode()}, {@code euqals()} and {@code
- * toString()}.
- *
- * @author xiangl@google.com (Xiang Li)
- */
-public class LazyField extends LazyFieldLite {
-
-  /**
-   * Carry a message's default instance which is used by {@code hashCode()}, {@code euqals()} and
-   * {@code toString()}.
-   */
-  private final MessageLite defaultInstance;
-
-  public LazyField(
-      MessageLite defaultInstance, ExtensionRegistryLite extensionRegistry, ByteString bytes) {
-    super(extensionRegistry, bytes);
-
-    this.defaultInstance = defaultInstance;
-  }
-
-  @Override
-  public boolean containsDefaultInstance() {
-    return super.containsDefaultInstance() || value == defaultInstance;
-  }
-
-  public MessageLite getValue() {
-    return getValue(defaultInstance);
-  }
-
-  @Override
-  public int hashCode() {
-    return getValue().hashCode();
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    return getValue().equals(obj);
-  }
-
-  @Override
-  public String toString() {
-    return getValue().toString();
-  }
-
-  // ====================================================
-
-  /**
-   * LazyEntry and LazyIterator are used to encapsulate the LazyField, when users iterate all fields
-   * from FieldSet.
-   */
-  static class LazyEntry<K> implements Entry<K, Object> {
-    private Entry<K, LazyField> entry;
-
-    private LazyEntry(Entry<K, LazyField> entry) {
-      this.entry = entry;
-    }
-
-    @Override
-    public K getKey() {
-      return entry.getKey();
-    }
-
-    @Override
-    public Object getValue() {
-      LazyField field = entry.getValue();
-      if (field == null) {
-        return null;
-      }
-      return field.getValue();
-    }
-
-    public LazyField getField() {
-      return entry.getValue();
-    }
-
-    @Override
-    public Object setValue(Object value) {
-      if (!(value instanceof MessageLite)) {
-        throw new IllegalArgumentException(
-            "LazyField now only used for MessageSet, "
-                + "and the value of MessageSet must be an instance of MessageLite");
-      }
-      return entry.getValue().setValue((MessageLite) value);
-    }
-  }
-
-  static class LazyIterator<K> implements Iterator<Entry<K, Object>> {
-    private Iterator<Entry<K, Object>> iterator;
-
-    public LazyIterator(Iterator<Entry<K, Object>> iterator) {
-      this.iterator = iterator;
-    }
-
-    @Override
-    public boolean hasNext() {
-      return iterator.hasNext();
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public Entry<K, Object> next() {
-      Entry<K, ?> entry = iterator.next();
-      if (entry.getValue() instanceof LazyField) {
-        return new LazyEntry<K>((Entry<K, LazyField>) entry);
-      }
-      return (Entry<K, Object>) entry;
-    }
-
-    @Override
-    public void remove() {
-      iterator.remove();
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/LazyFieldLite.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/LazyFieldLite.java
deleted file mode 100644
index 6fab26f..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/LazyFieldLite.java
+++ /dev/null
@@ -1,441 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.io.IOException;
-
-/**
- * LazyFieldLite encapsulates the logic of lazily parsing message fields. It stores the message in a
- * ByteString initially and then parses it on-demand.
- *
- * <p>LazyFieldLite is thread-compatible: concurrent reads are safe once the proto that this
- * LazyFieldLite is a part of is no longer being mutated by its Builder. However, explicit
- * synchronization is needed under read/write situations.
- *
- * <p>When a LazyFieldLite is used in the context of a MessageLite object, its behavior is
- * considered to be immutable and none of the setter methods in its API are expected to be invoked.
- * All of the getters are expected to be thread-safe. When used in the context of a
- * MessageLite.Builder, setters can be invoked, but there is no guarantee of thread safety.
- *
- * <p>TODO(yatin,dweis): Consider splitting this class's functionality and put the mutable methods
- * into a separate builder class to allow us to give stronger compile-time guarantees.
- *
- * <p>This class is internal implementation detail of the protobuf library, so you don't need to use
- * it directly.
- *
- * @author xiangl@google.com (Xiang Li)
- */
-public class LazyFieldLite {
-  private static final ExtensionRegistryLite EMPTY_REGISTRY =
-      ExtensionRegistryLite.getEmptyRegistry();
-
-  /*
-   * The value associated with the LazyFieldLite object is stored in one or more of the following
-   * three fields (delayedBytes, value, memoizedBytes). They should together be interpreted as
-   * follows.
-   *
-   * 1) delayedBytes can be non-null, while value and memoizedBytes is null. The object will be in
-   * this state while the value for the object has not yet been parsed.
-   *
-   * 2) Both delayedBytes and value are non-null. The object transitions to this state as soon as
-   * some caller needs to access the value (by invoking getValue()).
-   *
-   * 3) memoizedBytes is merely an optimization for calls to LazyFieldLite.toByteString() to avoid
-   * recomputing the ByteString representation on each call. Instead, when the value is parsed from
-   * delayedBytes, we will also assign the contents of delayedBytes to memoizedBytes (since that is
-   * the ByteString representation of value).
-   *
-   * 4) Finally, if the LazyFieldLite was created directly with a parsed MessageLite value, then
-   * delayedBytes will be null, and memoizedBytes will be initialized only upon the first call to
-   * LazyFieldLite.toByteString().
-   *
-   * <p>Given the above conditions, any caller that needs a serialized representation of this object
-   * must first check if the memoizedBytes or delayedBytes ByteString is non-null and use it
-   * directly; if both of those are null, it can look at the parsed value field. Similarly, any
-   * caller that needs a parsed value must first check if the value field is already non-null, if
-   * not it must parse the value from delayedBytes.
-   */
-
-  /**
-   * A delayed-parsed version of the contents of this field. When this field is non-null, then the
-   * "value" field is allowed to be null until the time that the value needs to be read.
-   *
-   * <p>When delayedBytes is non-null then {@code extensionRegistry} is required to also be
-   * non-null. {@code value} and {@code memoizedBytes} will be initialized lazily.
-   */
-  private ByteString delayedBytes;
-
-  /**
-   * An {@code ExtensionRegistryLite} for parsing bytes. It is non-null on a best-effort basis. It
-   * is only guaranteed to be non-null if this message was initialized using bytes and an {@code
-   * ExtensionRegistry}. If it directly had a value set then it will be null, unless it has been
-   * merged with another {@code LazyFieldLite} that had an {@code ExtensionRegistry}.
-   */
-  private ExtensionRegistryLite extensionRegistry;
-
-  /**
-   * The parsed value. When this is null and a caller needs access to the MessageLite value, then
-   * {@code delayedBytes} will be parsed lazily at that time.
-   */
-  protected volatile MessageLite value;
-
-  /**
-   * The memoized bytes for {@code value}. This is an optimization for the toByteString() method to
-   * not have to recompute its return-value on each invocation. TODO(yatin): Figure out whether this
-   * optimization is actually necessary.
-   */
-  private volatile ByteString memoizedBytes;
-
-  /** Constructs a LazyFieldLite with bytes that will be parsed lazily. */
-  public LazyFieldLite(ExtensionRegistryLite extensionRegistry, ByteString bytes) {
-    checkArguments(extensionRegistry, bytes);
-    this.extensionRegistry = extensionRegistry;
-    this.delayedBytes = bytes;
-  }
-
-  /** Constructs a LazyFieldLite with no contents, and no ability to parse extensions. */
-  public LazyFieldLite() {}
-
-  /**
-   * Constructs a LazyFieldLite instance with a value. The LazyFieldLite may not be able to parse
-   * the extensions in the value as it has no ExtensionRegistry.
-   */
-  public static LazyFieldLite fromValue(MessageLite value) {
-    LazyFieldLite lf = new LazyFieldLite();
-    lf.setValue(value);
-    return lf;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-
-    if (!(o instanceof LazyFieldLite)) {
-      return false;
-    }
-
-    LazyFieldLite other = (LazyFieldLite) o;
-
-    // Lazy fields do not work well with equals... If both are delayedBytes, we do not have a
-    // mechanism to deserialize them so we rely on bytes equality. Otherwise we coerce into an
-    // actual message (if necessary) and call equals on the message itself. This implies that two
-    // messages can by unequal but then be turned equal simply be invoking a getter on a lazy field.
-    MessageLite value1 = value;
-    MessageLite value2 = other.value;
-    if (value1 == null && value2 == null) {
-      return toByteString().equals(other.toByteString());
-    } else if (value1 != null && value2 != null) {
-      return value1.equals(value2);
-    } else if (value1 != null) {
-      return value1.equals(other.getValue(value1.getDefaultInstanceForType()));
-    } else {
-      return getValue(value2.getDefaultInstanceForType()).equals(value2);
-    }
-  }
-
-  @Override
-  public int hashCode() {
-    // We can't provide a memoizable hash code for lazy fields. The byte strings may have different
-    // hash codes but evaluate to equivalent messages. And we have no facility for constructing
-    // a message here if we were not already holding a value.
-    return 1;
-  }
-
-  /**
-   * Determines whether this LazyFieldLite instance represents the default instance of this type.
-   */
-  public boolean containsDefaultInstance() {
-    return memoizedBytes == ByteString.EMPTY
-        || value == null && (delayedBytes == null || delayedBytes == ByteString.EMPTY);
-  }
-
-  /**
-   * Clears the value state of this instance.
-   *
-   * <p>LazyField is not thread-safe for write access. Synchronizations are needed under read/write
-   * situations.
-   */
-  public void clear() {
-    // Don't clear the ExtensionRegistry. It might prove useful later on when merging in another
-    // value, but there is no guarantee that it will contain all extensions that were directly set
-    // on the values that need to be merged.
-    delayedBytes = null;
-    value = null;
-    memoizedBytes = null;
-  }
-
-  /**
-   * Overrides the contents of this LazyField.
-   *
-   * <p>LazyField is not thread-safe for write access. Synchronizations are needed under read/write
-   * situations.
-   */
-  public void set(LazyFieldLite other) {
-    this.delayedBytes = other.delayedBytes;
-    this.value = other.value;
-    this.memoizedBytes = other.memoizedBytes;
-    // If the other LazyFieldLite was created by directly setting the value rather than first by
-    // parsing, then it will not have an extensionRegistry. In this case we hold on to the existing
-    // extensionRegistry, which has no guarantees that it has all the extensions that will be
-    // directly set on the value.
-    if (other.extensionRegistry != null) {
-      this.extensionRegistry = other.extensionRegistry;
-    }
-  }
-
-  /**
-   * Returns message instance. It may do some thread-safe delayed parsing of bytes.
-   *
-   * @param defaultInstance its message's default instance. It's also used to get parser for the
-   *     message type.
-   */
-  public MessageLite getValue(MessageLite defaultInstance) {
-    ensureInitialized(defaultInstance);
-    return value;
-  }
-
-  /**
-   * Sets the value of the instance and returns the old value without delay parsing anything.
-   *
-   * <p>LazyField is not thread-safe for write access. Synchronizations are needed under read/write
-   * situations.
-   */
-  public MessageLite setValue(MessageLite value) {
-    MessageLite originalValue = this.value;
-    this.delayedBytes = null;
-    this.memoizedBytes = null;
-    this.value = value;
-    return originalValue;
-  }
-
-  /**
-   * Merges another instance's contents. In some cases may drop some extensions if both fields
-   * contain data. If the other field has an {@code ExtensionRegistry} but this does not, then this
-   * field will copy over that {@code ExtensionRegistry}.
-   *
-   * <p>LazyField is not thread-safe for write access. Synchronizations are needed under read/write
-   * situations.
-   */
-  public void merge(LazyFieldLite other) {
-    if (other.containsDefaultInstance()) {
-      return;
-    }
-
-    if (this.containsDefaultInstance()) {
-      set(other);
-      return;
-    }
-
-    // If the other field has an extension registry but this does not, copy over the other extension
-    // registry.
-    if (this.extensionRegistry == null) {
-      this.extensionRegistry = other.extensionRegistry;
-    }
-
-    // In the case that both of them are not parsed we simply concatenate the bytes to save time. In
-    // the (probably rare) case that they have different extension registries there is a chance that
-    // some of the extensions may be dropped, but the tradeoff of making this operation fast seems
-    // to outway the benefits of combining the extension registries, which is not normally done for
-    // lite protos anyways.
-    if (this.delayedBytes != null && other.delayedBytes != null) {
-      this.delayedBytes = this.delayedBytes.concat(other.delayedBytes);
-      return;
-    }
-
-    // At least one is parsed and both contain data. We won't drop any extensions here directly, but
-    // in the case that the extension registries are not the same then we might in the future if we
-    // need to serialize and parse a message again.
-    if (this.value == null && other.value != null) {
-      setValue(mergeValueAndBytes(other.value, this.delayedBytes, this.extensionRegistry));
-      return;
-    } else if (this.value != null && other.value == null) {
-      setValue(mergeValueAndBytes(this.value, other.delayedBytes, other.extensionRegistry));
-      return;
-    }
-
-    // At this point we have two fully parsed messages.
-    setValue(this.value.toBuilder().mergeFrom(other.value).build());
-  }
-
-  /**
-   * Merges another instance's contents from a stream.
-   *
-   * <p>LazyField is not thread-safe for write access. Synchronizations are needed under read/write
-   * situations.
-   */
-  public void mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    if (this.containsDefaultInstance()) {
-      setByteString(input.readBytes(), extensionRegistry);
-      return;
-    }
-
-    // If the other field has an extension registry but this does not, copy over the other extension
-    // registry.
-    if (this.extensionRegistry == null) {
-      this.extensionRegistry = extensionRegistry;
-    }
-
-    // In the case that both of them are not parsed we simply concatenate the bytes to save time. In
-    // the (probably rare) case that they have different extension registries there is a chance that
-    // some of the extensions may be dropped, but the tradeoff of making this operation fast seems
-    // to outway the benefits of combining the extension registries, which is not normally done for
-    // lite protos anyways.
-    if (this.delayedBytes != null) {
-      setByteString(this.delayedBytes.concat(input.readBytes()), this.extensionRegistry);
-      return;
-    }
-
-    // We are parsed and both contain data. We won't drop any extensions here directly, but in the
-    // case that the extension registries are not the same then we might in the future if we
-    // need to serialize and parse a message again.
-    try {
-      setValue(value.toBuilder().mergeFrom(input, extensionRegistry).build());
-    } catch (InvalidProtocolBufferException e) {
-      // Nothing is logged and no exceptions are thrown. Clients will be unaware that a proto
-      // was invalid.
-    }
-  }
-
-  private static MessageLite mergeValueAndBytes(
-      MessageLite value, ByteString otherBytes, ExtensionRegistryLite extensionRegistry) {
-    try {
-      return value.toBuilder().mergeFrom(otherBytes, extensionRegistry).build();
-    } catch (InvalidProtocolBufferException e) {
-      // Nothing is logged and no exceptions are thrown. Clients will be unaware that a proto
-      // was invalid.
-      return value;
-    }
-  }
-
-  /** Sets this field with bytes to delay-parse. */
-  public void setByteString(ByteString bytes, ExtensionRegistryLite extensionRegistry) {
-    checkArguments(extensionRegistry, bytes);
-    this.delayedBytes = bytes;
-    this.extensionRegistry = extensionRegistry;
-    this.value = null;
-    this.memoizedBytes = null;
-  }
-
-  /**
-   * Due to the optional field can be duplicated at the end of serialized bytes, which will make the
-   * serialized size changed after LazyField parsed. Be careful when using this method.
-   */
-  public int getSerializedSize() {
-    // We *must* return delayed bytes size if it was ever set because the dependent messages may
-    // have memoized serialized size based off of it.
-    if (memoizedBytes != null) {
-      return memoizedBytes.size();
-    } else if (delayedBytes != null) {
-      return delayedBytes.size();
-    } else if (value != null) {
-      return value.getSerializedSize();
-    } else {
-      return 0;
-    }
-  }
-
-  /** Returns a BytesString for this field in a thread-safe way. */
-  public ByteString toByteString() {
-    if (memoizedBytes != null) {
-      return memoizedBytes;
-    }
-    // We *must* return delayed bytes if it was set because the dependent messages may have
-    // memoized serialized size based off of it.
-    if (delayedBytes != null) {
-      return delayedBytes;
-    }
-    synchronized (this) {
-      if (memoizedBytes != null) {
-        return memoizedBytes;
-      }
-      if (value == null) {
-        memoizedBytes = ByteString.EMPTY;
-      } else {
-        memoizedBytes = value.toByteString();
-      }
-      return memoizedBytes;
-    }
-  }
-
-  /** Writes this lazy field into a {@link Writer}. */
-  void writeTo(Writer writer, int fieldNumber) throws IOException {
-    if (memoizedBytes != null) {
-      writer.writeBytes(fieldNumber, memoizedBytes);
-    } else if (delayedBytes != null) {
-      writer.writeBytes(fieldNumber, delayedBytes);
-    } else if (value != null) {
-      writer.writeMessage(fieldNumber, value);
-    } else {
-      writer.writeBytes(fieldNumber, ByteString.EMPTY);
-    }
-  }
-
-  /** Might lazily parse the bytes that were previously passed in. Is thread-safe. */
-  protected void ensureInitialized(MessageLite defaultInstance) {
-    if (value != null) {
-      return;
-    }
-    synchronized (this) {
-      if (value != null) {
-        return;
-      }
-      try {
-        if (delayedBytes != null) {
-          // The extensionRegistry shouldn't be null here since we have delayedBytes.
-          MessageLite parsedValue =
-              defaultInstance.getParserForType().parseFrom(delayedBytes, extensionRegistry);
-          this.value = parsedValue;
-          this.memoizedBytes = delayedBytes;
-        } else {
-          this.value = defaultInstance;
-          this.memoizedBytes = ByteString.EMPTY;
-        }
-      } catch (InvalidProtocolBufferException e) {
-        // Nothing is logged and no exceptions are thrown. Clients will be unaware that this proto
-        // was invalid.
-        this.value = defaultInstance;
-        this.memoizedBytes = ByteString.EMPTY;
-      }
-    }
-  }
-
-  private static void checkArguments(ExtensionRegistryLite extensionRegistry, ByteString bytes) {
-    if (extensionRegistry == null) {
-      throw new NullPointerException("found null ExtensionRegistry");
-    }
-    if (bytes == null) {
-      throw new NullPointerException("found null ByteString");
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/LazyStringArrayList.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/LazyStringArrayList.java
deleted file mode 100644
index a2de6f9..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/LazyStringArrayList.java
+++ /dev/null
@@ -1,417 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.util.AbstractList;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.RandomAccess;
-
-/**
- * An implementation of {@link LazyStringList} that wraps an ArrayList. Each element is one of
- * String, ByteString, or byte[]. It caches the last one requested which is most likely the one
- * needed next. This minimizes memory usage while satisfying the most common use cases.
- *
- * <p><strong>Note that this implementation is not synchronized.</strong> If multiple threads access
- * an <tt>ArrayList</tt> instance concurrently, and at least one of the threads modifies the list
- * structurally, it <i>must</i> be synchronized externally. (A structural modification is any
- * operation that adds or deletes one or more elements, or explicitly resizes the backing array;
- * merely setting the value of an element is not a structural modification.) This is typically
- * accomplished by synchronizing on some object that naturally encapsulates the list.
- *
- * <p>If the implementation is accessed via concurrent reads, this is thread safe. Conversions are
- * done in a thread safe manner. It's possible that the conversion may happen more than once if two
- * threads attempt to access the same element and the modifications were not visible to each other,
- * but this will not result in any corruption of the list or change in behavior other than
- * performance.
- *
- * @author jonp@google.com (Jon Perlow)
- */
-public class LazyStringArrayList extends AbstractProtobufList<String>
-    implements LazyStringList, RandomAccess {
-
-  private static final LazyStringArrayList EMPTY_LIST = new LazyStringArrayList();
-
-  static {
-    EMPTY_LIST.makeImmutable();
-  }
-
-  static LazyStringArrayList emptyList() {
-    return EMPTY_LIST;
-  }
-
-  // For compatibility with older runtimes.
-  public static final LazyStringList EMPTY = EMPTY_LIST;
-
-  private final List<Object> list;
-
-  public LazyStringArrayList() {
-    this(DEFAULT_CAPACITY);
-  }
-
-  public LazyStringArrayList(int initialCapacity) {
-    this(new ArrayList<Object>(initialCapacity));
-  }
-
-  public LazyStringArrayList(LazyStringList from) {
-    list = new ArrayList<Object>(from.size());
-    addAll(from);
-  }
-
-  public LazyStringArrayList(List<String> from) {
-    this(new ArrayList<Object>(from));
-  }
-
-  private LazyStringArrayList(ArrayList<Object> list) {
-    this.list = list;
-  }
-
-  @Override
-  public LazyStringArrayList mutableCopyWithCapacity(int capacity) {
-    if (capacity < size()) {
-      throw new IllegalArgumentException();
-    }
-    ArrayList<Object> newList = new ArrayList<Object>(capacity);
-    newList.addAll(list);
-    return new LazyStringArrayList(newList);
-  }
-
-  @Override
-  public String get(int index) {
-    Object o = list.get(index);
-    if (o instanceof String) {
-      return (String) o;
-    } else if (o instanceof ByteString) {
-      ByteString bs = (ByteString) o;
-      String s = bs.toStringUtf8();
-      if (bs.isValidUtf8()) {
-        list.set(index, s);
-      }
-      return s;
-    } else {
-      byte[] ba = (byte[]) o;
-      String s = Internal.toStringUtf8(ba);
-      if (Internal.isValidUtf8(ba)) {
-        list.set(index, s);
-      }
-      return s;
-    }
-  }
-
-  @Override
-  public int size() {
-    return list.size();
-  }
-
-  @Override
-  public String set(int index, String s) {
-    ensureIsMutable();
-    Object o = list.set(index, s);
-    return asString(o);
-  }
-
-  @Override
-  public void add(int index, String element) {
-    ensureIsMutable();
-    list.add(index, element);
-    modCount++;
-  }
-
-  private void add(int index, ByteString element) {
-    ensureIsMutable();
-    list.add(index, element);
-    modCount++;
-  }
-
-  private void add(int index, byte[] element) {
-    ensureIsMutable();
-    list.add(index, element);
-    modCount++;
-  }
-
-  @Override
-  public boolean addAll(Collection<? extends String> c) {
-    // The default implementation of AbstractCollection.addAll(Collection)
-    // delegates to add(Object). This implementation instead delegates to
-    // addAll(int, Collection), which makes a special case for Collections
-    // which are instances of LazyStringList.
-    return addAll(size(), c);
-  }
-
-  @Override
-  public boolean addAll(int index, Collection<? extends String> c) {
-    ensureIsMutable();
-    // When copying from another LazyStringList, directly copy the underlying
-    // elements rather than forcing each element to be decoded to a String.
-    Collection<?> collection =
-        c instanceof LazyStringList ? ((LazyStringList) c).getUnderlyingElements() : c;
-    boolean ret = list.addAll(index, collection);
-    modCount++;
-    return ret;
-  }
-
-  @Override
-  public boolean addAllByteString(Collection<? extends ByteString> values) {
-    ensureIsMutable();
-    boolean ret = list.addAll(values);
-    modCount++;
-    return ret;
-  }
-
-  @Override
-  public boolean addAllByteArray(Collection<byte[]> c) {
-    ensureIsMutable();
-    boolean ret = list.addAll(c);
-    modCount++;
-    return ret;
-  }
-
-  @Override
-  public String remove(int index) {
-    ensureIsMutable();
-    Object o = list.remove(index);
-    modCount++;
-    return asString(o);
-  }
-
-  @Override
-  public void clear() {
-    ensureIsMutable();
-    list.clear();
-    modCount++;
-  }
-
-  @Override
-  public void add(ByteString element) {
-    ensureIsMutable();
-    list.add(element);
-    modCount++;
-  }
-
-  @Override
-  public void add(byte[] element) {
-    ensureIsMutable();
-    list.add(element);
-    modCount++;
-  }
-
-  @Override
-  public Object getRaw(int index) {
-    return list.get(index);
-  }
-
-  @Override
-  public ByteString getByteString(int index) {
-    Object o = list.get(index);
-    ByteString b = asByteString(o);
-    if (b != o) {
-      list.set(index, b);
-    }
-    return b;
-  }
-
-  @Override
-  public byte[] getByteArray(int index) {
-    Object o = list.get(index);
-    byte[] b = asByteArray(o);
-    if (b != o) {
-      list.set(index, b);
-    }
-    return b;
-  }
-
-  @Override
-  public void set(int index, ByteString s) {
-    setAndReturn(index, s);
-  }
-
-  private Object setAndReturn(int index, ByteString s) {
-    ensureIsMutable();
-    return list.set(index, s);
-  }
-
-  @Override
-  public void set(int index, byte[] s) {
-    setAndReturn(index, s);
-  }
-
-  private Object setAndReturn(int index, byte[] s) {
-    ensureIsMutable();
-    return list.set(index, s);
-  }
-
-  private static String asString(Object o) {
-    if (o instanceof String) {
-      return (String) o;
-    } else if (o instanceof ByteString) {
-      return ((ByteString) o).toStringUtf8();
-    } else {
-      return Internal.toStringUtf8((byte[]) o);
-    }
-  }
-
-  private static ByteString asByteString(Object o) {
-    if (o instanceof ByteString) {
-      return (ByteString) o;
-    } else if (o instanceof String) {
-      return ByteString.copyFromUtf8((String) o);
-    } else {
-      return ByteString.copyFrom((byte[]) o);
-    }
-  }
-
-  private static byte[] asByteArray(Object o) {
-    if (o instanceof byte[]) {
-      return (byte[]) o;
-    } else if (o instanceof String) {
-      return Internal.toByteArray((String) o);
-    } else {
-      return ((ByteString) o).toByteArray();
-    }
-  }
-
-  @Override
-  public List<?> getUnderlyingElements() {
-    return Collections.unmodifiableList(list);
-  }
-
-  @Override
-  public void mergeFrom(LazyStringList other) {
-    ensureIsMutable();
-    for (Object o : other.getUnderlyingElements()) {
-      if (o instanceof byte[]) {
-        byte[] b = (byte[]) o;
-        // Byte array's content is mutable so they should be copied rather than
-        // shared when merging from one message to another.
-        list.add(Arrays.copyOf(b, b.length));
-      } else {
-        list.add(o);
-      }
-    }
-  }
-
-  private static class ByteArrayListView extends AbstractList<byte[]> implements RandomAccess {
-    private final LazyStringArrayList list;
-
-    ByteArrayListView(LazyStringArrayList list) {
-      this.list = list;
-    }
-
-    @Override
-    public byte[] get(int index) {
-      return list.getByteArray(index);
-    }
-
-    @Override
-    public int size() {
-      return list.size();
-    }
-
-    @Override
-    public byte[] set(int index, byte[] s) {
-      Object o = list.setAndReturn(index, s);
-      modCount++;
-      return asByteArray(o);
-    }
-
-    @Override
-    public void add(int index, byte[] s) {
-      list.add(index, s);
-      modCount++;
-    }
-
-    @Override
-    public byte[] remove(int index) {
-      Object o = list.remove(index);
-      modCount++;
-      return asByteArray(o);
-    }
-  }
-
-  @Override
-  public List<byte[]> asByteArrayList() {
-    return new ByteArrayListView(this);
-  }
-
-  private static class ByteStringListView extends AbstractList<ByteString> implements RandomAccess {
-    private final LazyStringArrayList list;
-
-    ByteStringListView(LazyStringArrayList list) {
-      this.list = list;
-    }
-
-    @Override
-    public ByteString get(int index) {
-      return list.getByteString(index);
-    }
-
-    @Override
-    public int size() {
-      return list.size();
-    }
-
-    @Override
-    public ByteString set(int index, ByteString s) {
-      Object o = list.setAndReturn(index, s);
-      modCount++;
-      return asByteString(o);
-    }
-
-    @Override
-    public void add(int index, ByteString s) {
-      list.add(index, s);
-      modCount++;
-    }
-
-    @Override
-    public ByteString remove(int index) {
-      Object o = list.remove(index);
-      modCount++;
-      return asByteString(o);
-    }
-  }
-
-  @Override
-  public List<ByteString> asByteStringList() {
-    return new ByteStringListView(this);
-  }
-
-  @Override
-  public LazyStringList getUnmodifiableView() {
-    if (isModifiable()) {
-      return new UnmodifiableLazyStringList(this);
-    }
-    return this;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/LazyStringList.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/LazyStringList.java
deleted file mode 100644
index 6b55022..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/LazyStringList.java
+++ /dev/null
@@ -1,164 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * An interface extending {@code List<String>} that also provides access to the items of the list as
- * UTF8-encoded ByteString or byte[] objects. This is used by the protocol buffer implementation to
- * support lazily converting bytes parsed over the wire to String objects until needed and also
- * increases the efficiency of serialization if the String was never requested as the ByteString or
- * byte[] is already cached. The ByteString methods are used in immutable API only and byte[]
- * methods used in mutable API only for they use different representations for string/bytes fields.
- *
- * @author jonp@google.com (Jon Perlow)
- */
-public interface LazyStringList extends ProtocolStringList {
-
-  /**
-   * Returns the element at the specified position in this list as a ByteString.
-   *
-   * @param index index of the element to return
-   * @return the element at the specified position in this list
-   * @throws IndexOutOfBoundsException if the index is out of range ({@code index < 0 || index >=
-   *     size()})
-   */
-  ByteString getByteString(int index);
-
-  /**
-   * Returns the element at the specified position in this list as an Object that will either be a
-   * String or a ByteString.
-   *
-   * @param index index of the element to return
-   * @return the element at the specified position in this list
-   * @throws IndexOutOfBoundsException if the index is out of range ({@code index < 0 || index >=
-   *     size()})
-   */
-  Object getRaw(int index);
-
-  /**
-   * Returns the element at the specified position in this list as byte[].
-   *
-   * @param index index of the element to return
-   * @return the element at the specified position in this list
-   * @throws IndexOutOfBoundsException if the index is out of range ({@code index < 0 || index >=
-   *     size()})
-   */
-  byte[] getByteArray(int index);
-
-  /**
-   * Appends the specified element to the end of this list (optional operation).
-   *
-   * @param element element to be appended to this list
-   * @throws UnsupportedOperationException if the <tt>add</tt> operation is not supported by this
-   *     list
-   */
-  void add(ByteString element);
-
-  /**
-   * Appends the specified element to the end of this list (optional operation).
-   *
-   * @param element element to be appended to this list
-   * @throws UnsupportedOperationException if the <tt>add</tt> operation is not supported by this
-   *     list
-   */
-  void add(byte[] element);
-
-  /**
-   * Replaces the element at the specified position in this list with the specified element
-   * (optional operation).
-   *
-   * @param index index of the element to replace
-   * @param element the element to be stored at the specified position
-   * @throws UnsupportedOperationException if the <tt>set</tt> operation is not supported by this
-   *     list IndexOutOfBoundsException if the index is out of range ({@code index < 0 || index >=
-   *     size()})
-   */
-  void set(int index, ByteString element);
-
-  /**
-   * Replaces the element at the specified position in this list with the specified element
-   * (optional operation).
-   *
-   * @param index index of the element to replace
-   * @param element the element to be stored at the specified position
-   * @throws UnsupportedOperationException if the <tt>set</tt> operation is not supported by this
-   *     list IndexOutOfBoundsException if the index is out of range ({@code index < 0 || index >=
-   *     size()})
-   */
-  void set(int index, byte[] element);
-
-  /**
-   * Appends all elements in the specified ByteString collection to the end of this list.
-   *
-   * @param c collection whose elements are to be added to this list
-   * @return true if this list changed as a result of the call
-   * @throws UnsupportedOperationException if the <tt>addAllByteString</tt> operation is not
-   *     supported by this list
-   */
-  boolean addAllByteString(Collection<? extends ByteString> c);
-
-  /**
-   * Appends all elements in the specified byte[] collection to the end of this list.
-   *
-   * @param c collection whose elements are to be added to this list
-   * @return true if this list changed as a result of the call
-   * @throws UnsupportedOperationException if the <tt>addAllByteArray</tt> operation is not
-   *     supported by this list
-   */
-  boolean addAllByteArray(Collection<byte[]> c);
-
-  /**
-   * Returns an unmodifiable List of the underlying elements, each of which is either a {@code
-   * String} or its equivalent UTF-8 encoded {@code ByteString} or byte[]. It is an error for the
-   * caller to modify the returned List, and attempting to do so will result in an {@link
-   * UnsupportedOperationException}.
-   */
-  List<?> getUnderlyingElements();
-
-  /**
-   * Merges all elements from another LazyStringList into this one. This method differs from {@link
-   * #addAll(Collection)} on that underlying byte arrays are copied instead of reference shared.
-   * Immutable API doesn't need to use this method as byte[] is not used there at all.
-   */
-  void mergeFrom(LazyStringList other);
-
-  /**
-   * Returns a mutable view of this list. Changes to the view will be made into the original list.
-   * This method is used in mutable API only.
-   */
-  List<byte[]> asByteArrayList();
-
-  /** Returns an unmodifiable view of the list. */
-  LazyStringList getUnmodifiableView();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ListFieldSchema.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ListFieldSchema.java
deleted file mode 100644
index ebc8561..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ListFieldSchema.java
+++ /dev/null
@@ -1,190 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import com.google.protobuf.Internal.ProtobufList;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Utility class that aids in properly manipulating list fields for either the lite or full runtime.
- */
-abstract class ListFieldSchema {
-  // Disallow construction.
-  private ListFieldSchema() {}
-
-  private static final ListFieldSchema FULL_INSTANCE = new ListFieldSchemaFull();
-  private static final ListFieldSchema LITE_INSTANCE = new ListFieldSchemaLite();
-
-  abstract <L> List<L> mutableListAt(Object msg, long offset);
-
-  abstract void makeImmutableListAt(Object msg, long offset);
-
-  abstract <L> void mergeListsAt(Object msg, Object otherMsg, long offset);
-
-  static ListFieldSchema full() {
-    return FULL_INSTANCE;
-  }
-
-  static ListFieldSchema lite() {
-    return LITE_INSTANCE;
-  }
-
-  /** Implementation for the full runtime. */
-  private static final class ListFieldSchemaFull extends ListFieldSchema {
-
-    private static final Class<?> UNMODIFIABLE_LIST_CLASS =
-        Collections.unmodifiableList(Collections.emptyList()).getClass();
-
-    @Override
-    <L> List<L> mutableListAt(Object message, long offset) {
-      return mutableListAt(message, offset, AbstractProtobufList.DEFAULT_CAPACITY);
-    }
-
-    @Override
-    void makeImmutableListAt(Object message, long offset) {
-      List<?> list = (List<?>) UnsafeUtil.getObject(message, offset);
-      Object immutable = null;
-      if (list instanceof LazyStringList) {
-        immutable = ((LazyStringList) list).getUnmodifiableView();
-      } else if (UNMODIFIABLE_LIST_CLASS.isAssignableFrom(list.getClass())) {
-        // already immutable
-        return;
-      } else if (list instanceof PrimitiveNonBoxingCollection && list instanceof ProtobufList) {
-        if (((ProtobufList<?>) list).isModifiable()) {
-          ((ProtobufList<?>) list).makeImmutable();
-        }
-        return;
-      } else {
-        immutable = Collections.unmodifiableList((List<?>) list);
-      }
-      UnsafeUtil.putObject(message, offset, immutable);
-    }
-
-    @SuppressWarnings("unchecked")
-    private static <L> List<L> mutableListAt(Object message, long offset, int additionalCapacity) {
-      List<L> list = getList(message, offset);
-      if (list.isEmpty()) {
-        if (list instanceof LazyStringList) {
-          list = (List<L>) new LazyStringArrayList(additionalCapacity);
-        } else if (list instanceof PrimitiveNonBoxingCollection && list instanceof ProtobufList) {
-          list = ((ProtobufList<L>) list).mutableCopyWithCapacity(additionalCapacity);
-        } else {
-          list = new ArrayList<L>(additionalCapacity);
-        }
-        UnsafeUtil.putObject(message, offset, list);
-      } else if (UNMODIFIABLE_LIST_CLASS.isAssignableFrom(list.getClass())) {
-        ArrayList<L> newList = new ArrayList<L>(list.size() + additionalCapacity);
-        newList.addAll(list);
-        list = newList;
-        UnsafeUtil.putObject(message, offset, list);
-      } else if (list instanceof UnmodifiableLazyStringList) {
-        LazyStringArrayList newList = new LazyStringArrayList(list.size() + additionalCapacity);
-        newList.addAll((UnmodifiableLazyStringList) list);
-        list = (List<L>) newList;
-        UnsafeUtil.putObject(message, offset, list);
-      } else if (list instanceof PrimitiveNonBoxingCollection
-          && list instanceof ProtobufList
-          && !((ProtobufList<L>) list).isModifiable()) {
-        list = ((ProtobufList<L>) list).mutableCopyWithCapacity(list.size() + additionalCapacity);
-        UnsafeUtil.putObject(message, offset, list);
-      }
-      return list;
-    }
-
-    @Override
-    <E> void mergeListsAt(Object msg, Object otherMsg, long offset) {
-      List<E> other = getList(otherMsg, offset);
-      List<E> mine = mutableListAt(msg, offset, other.size());
-
-      int size = mine.size();
-      int otherSize = other.size();
-      if (size > 0 && otherSize > 0) {
-        mine.addAll(other);
-      }
-
-      List<E> merged = size > 0 ? mine : other;
-      UnsafeUtil.putObject(msg, offset, merged);
-    }
-
-    @SuppressWarnings("unchecked")
-    static <E> List<E> getList(Object message, long offset) {
-      return (List<E>) UnsafeUtil.getObject(message, offset);
-    }
-  }
-
-  /** Implementation for the lite runtime. */
-  private static final class ListFieldSchemaLite extends ListFieldSchema {
-
-    @Override
-    <L> List<L> mutableListAt(Object message, long offset) {
-      ProtobufList<L> list = getProtobufList(message, offset);
-      if (!list.isModifiable()) {
-        int size = list.size();
-        list =
-            list.mutableCopyWithCapacity(
-                size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
-        UnsafeUtil.putObject(message, offset, list);
-      }
-      return list;
-    }
-
-    @Override
-    void makeImmutableListAt(Object message, long offset) {
-      ProtobufList<?> list = getProtobufList(message, offset);
-      list.makeImmutable();
-    }
-
-    @Override
-    <E> void mergeListsAt(Object msg, Object otherMsg, long offset) {
-      ProtobufList<E> mine = getProtobufList(msg, offset);
-      ProtobufList<E> other = getProtobufList(otherMsg, offset);
-
-      int size = mine.size();
-      int otherSize = other.size();
-      if (size > 0 && otherSize > 0) {
-        if (!mine.isModifiable()) {
-          mine = mine.mutableCopyWithCapacity(size + otherSize);
-        }
-        mine.addAll(other);
-      }
-
-      ProtobufList<E> merged = size > 0 ? mine : other;
-      UnsafeUtil.putObject(msg, offset, merged);
-    }
-
-    @SuppressWarnings("unchecked")
-    static <E> ProtobufList<E> getProtobufList(Object message, long offset) {
-      return (ProtobufList<E>) UnsafeUtil.getObject(message, offset);
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ListValue.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ListValue.java
deleted file mode 100644
index 96cc770..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ListValue.java
+++ /dev/null
@@ -1,484 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/struct.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * `ListValue` is a wrapper around a repeated field of values.
- * The JSON representation for `ListValue` is JSON array.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.ListValue}
- */
-public  final class ListValue extends
-    com.google.protobuf.GeneratedMessageLite<
-        ListValue, ListValue.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.ListValue)
-    ListValueOrBuilder {
-  private ListValue() {
-    values_ = emptyProtobufList();
-  }
-  public static final int VALUES_FIELD_NUMBER = 1;
-  private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Value> values_;
-  /**
-   * <pre>
-   * Repeated field of dynamically typed values.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Value values = 1;</code>
-   */
-  @java.lang.Override
-  public java.util.List<com.google.protobuf.Value> getValuesList() {
-    return values_;
-  }
-  /**
-   * <pre>
-   * Repeated field of dynamically typed values.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Value values = 1;</code>
-   */
-  public java.util.List<? extends com.google.protobuf.ValueOrBuilder> 
-      getValuesOrBuilderList() {
-    return values_;
-  }
-  /**
-   * <pre>
-   * Repeated field of dynamically typed values.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Value values = 1;</code>
-   */
-  @java.lang.Override
-  public int getValuesCount() {
-    return values_.size();
-  }
-  /**
-   * <pre>
-   * Repeated field of dynamically typed values.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Value values = 1;</code>
-   */
-  @java.lang.Override
-  public com.google.protobuf.Value getValues(int index) {
-    return values_.get(index);
-  }
-  /**
-   * <pre>
-   * Repeated field of dynamically typed values.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Value values = 1;</code>
-   */
-  public com.google.protobuf.ValueOrBuilder getValuesOrBuilder(
-      int index) {
-    return values_.get(index);
-  }
-  private void ensureValuesIsMutable() {
-    com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Value> tmp = values_;
-    if (!tmp.isModifiable()) {
-      values_ =
-          com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-     }
-  }
-
-  /**
-   * <pre>
-   * Repeated field of dynamically typed values.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Value values = 1;</code>
-   */
-  private void setValues(
-      int index, com.google.protobuf.Value value) {
-    value.getClass();
-  ensureValuesIsMutable();
-    values_.set(index, value);
-  }
-  /**
-   * <pre>
-   * Repeated field of dynamically typed values.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Value values = 1;</code>
-   */
-  private void addValues(com.google.protobuf.Value value) {
-    value.getClass();
-  ensureValuesIsMutable();
-    values_.add(value);
-  }
-  /**
-   * <pre>
-   * Repeated field of dynamically typed values.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Value values = 1;</code>
-   */
-  private void addValues(
-      int index, com.google.protobuf.Value value) {
-    value.getClass();
-  ensureValuesIsMutable();
-    values_.add(index, value);
-  }
-  /**
-   * <pre>
-   * Repeated field of dynamically typed values.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Value values = 1;</code>
-   */
-  private void addAllValues(
-      java.lang.Iterable<? extends com.google.protobuf.Value> values) {
-    ensureValuesIsMutable();
-    com.google.protobuf.AbstractMessageLite.addAll(
-        values, values_);
-  }
-  /**
-   * <pre>
-   * Repeated field of dynamically typed values.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Value values = 1;</code>
-   */
-  private void clearValues() {
-    values_ = emptyProtobufList();
-  }
-  /**
-   * <pre>
-   * Repeated field of dynamically typed values.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Value values = 1;</code>
-   */
-  private void removeValues(int index) {
-    ensureValuesIsMutable();
-    values_.remove(index);
-  }
-
-  public static com.google.protobuf.ListValue parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.ListValue parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.ListValue parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.ListValue parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.ListValue parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.ListValue parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.ListValue parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.ListValue parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.ListValue parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.ListValue parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.ListValue parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.ListValue parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.ListValue prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * `ListValue` is a wrapper around a repeated field of values.
-   * The JSON representation for `ListValue` is JSON array.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.ListValue}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.ListValue, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.ListValue)
-      com.google.protobuf.ListValueOrBuilder {
-    // Construct using com.google.protobuf.ListValue.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * Repeated field of dynamically typed values.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Value values = 1;</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.Value> getValuesList() {
-      return java.util.Collections.unmodifiableList(
-          instance.getValuesList());
-    }
-    /**
-     * <pre>
-     * Repeated field of dynamically typed values.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Value values = 1;</code>
-     */
-    @java.lang.Override
-    public int getValuesCount() {
-      return instance.getValuesCount();
-    }/**
-     * <pre>
-     * Repeated field of dynamically typed values.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Value values = 1;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.Value getValues(int index) {
-      return instance.getValues(index);
-    }
-    /**
-     * <pre>
-     * Repeated field of dynamically typed values.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Value values = 1;</code>
-     */
-    public Builder setValues(
-        int index, com.google.protobuf.Value value) {
-      copyOnWrite();
-      instance.setValues(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Repeated field of dynamically typed values.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Value values = 1;</code>
-     */
-    public Builder setValues(
-        int index, com.google.protobuf.Value.Builder builderForValue) {
-      copyOnWrite();
-      instance.setValues(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Repeated field of dynamically typed values.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Value values = 1;</code>
-     */
-    public Builder addValues(com.google.protobuf.Value value) {
-      copyOnWrite();
-      instance.addValues(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Repeated field of dynamically typed values.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Value values = 1;</code>
-     */
-    public Builder addValues(
-        int index, com.google.protobuf.Value value) {
-      copyOnWrite();
-      instance.addValues(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Repeated field of dynamically typed values.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Value values = 1;</code>
-     */
-    public Builder addValues(
-        com.google.protobuf.Value.Builder builderForValue) {
-      copyOnWrite();
-      instance.addValues(builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Repeated field of dynamically typed values.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Value values = 1;</code>
-     */
-    public Builder addValues(
-        int index, com.google.protobuf.Value.Builder builderForValue) {
-      copyOnWrite();
-      instance.addValues(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Repeated field of dynamically typed values.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Value values = 1;</code>
-     */
-    public Builder addAllValues(
-        java.lang.Iterable<? extends com.google.protobuf.Value> values) {
-      copyOnWrite();
-      instance.addAllValues(values);
-      return this;
-    }
-    /**
-     * <pre>
-     * Repeated field of dynamically typed values.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Value values = 1;</code>
-     */
-    public Builder clearValues() {
-      copyOnWrite();
-      instance.clearValues();
-      return this;
-    }
-    /**
-     * <pre>
-     * Repeated field of dynamically typed values.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Value values = 1;</code>
-     */
-    public Builder removeValues(int index) {
-      copyOnWrite();
-      instance.removeValues(index);
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.ListValue)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.ListValue();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "values_",
-            com.google.protobuf.Value.class,
-          };
-          java.lang.String info =
-              "\u0000\u0001\u0000\u0000\u0001\u0001\u0001\u0000\u0001\u0000\u0001\u001b";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.ListValue> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.ListValue.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.ListValue>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.ListValue)
-  private static final com.google.protobuf.ListValue DEFAULT_INSTANCE;
-  static {
-    ListValue defaultInstance = new ListValue();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      ListValue.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.ListValue getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<ListValue> PARSER;
-
-  public static com.google.protobuf.Parser<ListValue> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ListValueOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ListValueOrBuilder.java
deleted file mode 100644
index 273ad2a..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ListValueOrBuilder.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/struct.proto
-
-package com.google.protobuf;
-
-public interface ListValueOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.ListValue)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * Repeated field of dynamically typed values.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Value values = 1;</code>
-   */
-  java.util.List<com.google.protobuf.Value> 
-      getValuesList();
-  /**
-   * <pre>
-   * Repeated field of dynamically typed values.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Value values = 1;</code>
-   */
-  com.google.protobuf.Value getValues(int index);
-  /**
-   * <pre>
-   * Repeated field of dynamically typed values.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Value values = 1;</code>
-   */
-  int getValuesCount();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/LongArrayList.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/LongArrayList.java
deleted file mode 100644
index bda43a4..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/LongArrayList.java
+++ /dev/null
@@ -1,297 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.Internal.checkNotNull;
-
-import com.google.protobuf.Internal.LongList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.RandomAccess;
-
-/**
- * An implementation of {@link LongList} on top of a primitive array.
- *
- * @author dweis@google.com (Daniel Weis)
- */
-final class LongArrayList extends AbstractProtobufList<Long>
-    implements LongList, RandomAccess, PrimitiveNonBoxingCollection {
-
-  private static final LongArrayList EMPTY_LIST = new LongArrayList(new long[0], 0);
-  static {
-    EMPTY_LIST.makeImmutable();
-  }
-
-  public static LongArrayList emptyList() {
-    return EMPTY_LIST;
-  }
-
-  /** The backing store for the list. */
-  private long[] array;
-
-  /**
-   * The size of the list distinct from the length of the array. That is, it is the number of
-   * elements set in the list.
-   */
-  private int size;
-
-  /** Constructs a new mutable {@code LongArrayList} with default capacity. */
-  LongArrayList() {
-    this(new long[DEFAULT_CAPACITY], 0);
-  }
-
-  /**
-   * Constructs a new mutable {@code LongArrayList} containing the same elements as {@code other}.
-   */
-  private LongArrayList(long[] other, int size) {
-    array = other;
-    this.size = size;
-  }
-
-  @Override
-  protected void removeRange(int fromIndex, int toIndex) {
-    ensureIsMutable();
-    if (toIndex < fromIndex) {
-      throw new IndexOutOfBoundsException("toIndex < fromIndex");
-    }
-
-    System.arraycopy(array, toIndex, array, fromIndex, size - toIndex);
-    size -= (toIndex - fromIndex);
-    modCount++;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (!(o instanceof LongArrayList)) {
-      return super.equals(o);
-    }
-    LongArrayList other = (LongArrayList) o;
-    if (size != other.size) {
-      return false;
-    }
-
-    final long[] arr = other.array;
-    for (int i = 0; i < size; i++) {
-      if (array[i] != arr[i]) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = 1;
-    for (int i = 0; i < size; i++) {
-      result = (31 * result) + Internal.hashLong(array[i]);
-    }
-    return result;
-  }
-
-  @Override
-  public LongList mutableCopyWithCapacity(int capacity) {
-    if (capacity < size) {
-      throw new IllegalArgumentException();
-    }
-    return new LongArrayList(Arrays.copyOf(array, capacity), size);
-  }
-
-  @Override
-  public Long get(int index) {
-    return getLong(index);
-  }
-
-  @Override
-  public long getLong(int index) {
-    ensureIndexInRange(index);
-    return array[index];
-  }
-
-  @Override
-  public int indexOf(Object element) {
-    if (!(element instanceof Long)) {
-      return -1;
-    }
-    long unboxedElement = (Long) element;
-    int numElems = size();
-    for (int i = 0; i < numElems; i++) {
-      if (array[i] == unboxedElement) {
-        return i;
-      }
-    }
-    return -1;
-  }
-
-  @Override
-  public boolean contains(Object element) {
-    return indexOf(element) != -1;
-  }
-
-  @Override
-  public int size() {
-    return size;
-  }
-
-  @Override
-  public Long set(int index, Long element) {
-    return setLong(index, element);
-  }
-
-  @Override
-  public long setLong(int index, long element) {
-    ensureIsMutable();
-    ensureIndexInRange(index);
-    long previousValue = array[index];
-    array[index] = element;
-    return previousValue;
-  }
-
-  @Override
-  public boolean add(Long element) {
-    addLong(element);
-    return true;
-  }
-
-  @Override
-  public void add(int index, Long element) {
-    addLong(index, element);
-  }
-
-  /** Like {@link #add(Long)} but more efficient in that it doesn't box the element. */
-  @Override
-  public void addLong(long element) {
-    ensureIsMutable();
-    if (size == array.length) {
-      // Resize to 1.5x the size
-      int length = ((size * 3) / 2) + 1;
-      long[] newArray = new long[length];
-
-      System.arraycopy(array, 0, newArray, 0, size);
-      array = newArray;
-    }
-
-    array[size++] = element;
-  }
-
-  /** Like {@link #add(int, Long)} but more efficient in that it doesn't box the element. */
-  private void addLong(int index, long element) {
-    ensureIsMutable();
-    if (index < 0 || index > size) {
-      throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index));
-    }
-
-    if (size < array.length) {
-      // Shift everything over to make room
-      System.arraycopy(array, index, array, index + 1, size - index);
-    } else {
-      // Resize to 1.5x the size
-      int length = ((size * 3) / 2) + 1;
-      long[] newArray = new long[length];
-
-      // Copy the first part directly
-      System.arraycopy(array, 0, newArray, 0, index);
-
-      // Copy the rest shifted over by one to make room
-      System.arraycopy(array, index, newArray, index + 1, size - index);
-      array = newArray;
-    }
-
-    array[index] = element;
-    size++;
-    modCount++;
-  }
-
-  @Override
-  public boolean addAll(Collection<? extends Long> collection) {
-    ensureIsMutable();
-
-    checkNotNull(collection);
-
-    // We specialize when adding another LongArrayList to avoid boxing elements.
-    if (!(collection instanceof LongArrayList)) {
-      return super.addAll(collection);
-    }
-
-    LongArrayList list = (LongArrayList) collection;
-    if (list.size == 0) {
-      return false;
-    }
-
-    int overflow = Integer.MAX_VALUE - size;
-    if (overflow < list.size) {
-      // We can't actually represent a list this large.
-      throw new OutOfMemoryError();
-    }
-
-    int newSize = size + list.size;
-    if (newSize > array.length) {
-      array = Arrays.copyOf(array, newSize);
-    }
-
-    System.arraycopy(list.array, 0, array, size, list.size);
-    size = newSize;
-    modCount++;
-    return true;
-  }
-
-  @Override
-  public Long remove(int index) {
-    ensureIsMutable();
-    ensureIndexInRange(index);
-    long value = array[index];
-    if (index < size - 1) {
-      System.arraycopy(array, index + 1, array, index, size - index - 1);
-    }
-    size--;
-    modCount++;
-    return value;
-  }
-
-  /**
-   * Ensures that the provided {@code index} is within the range of {@code [0, size]}. Throws an
-   * {@link IndexOutOfBoundsException} if it is not.
-   *
-   * @param index the index to verify is in range
-   */
-  private void ensureIndexInRange(int index) {
-    if (index < 0 || index >= size) {
-      throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index));
-    }
-  }
-
-  private String makeOutOfBoundsExceptionMessage(int index) {
-    return "Index:" + index + ", Size:" + size;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ManifestSchemaFactory.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ManifestSchemaFactory.java
deleted file mode 100644
index 84ca9ae..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ManifestSchemaFactory.java
+++ /dev/null
@@ -1,172 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.Internal.checkNotNull;
-
-/**
- * Dynamically generates a manifest-based (i.e. table-based) schema for a given protobuf message.
- */
-@ExperimentalApi
-final class ManifestSchemaFactory implements SchemaFactory {
-
-  private final MessageInfoFactory messageInfoFactory;
-
-  public ManifestSchemaFactory() {
-    this(getDefaultMessageInfoFactory());
-  }
-
-  private ManifestSchemaFactory(MessageInfoFactory messageInfoFactory) {
-    this.messageInfoFactory = checkNotNull(messageInfoFactory, "messageInfoFactory");
-  }
-
-  @Override
-  public <T> Schema<T> createSchema(Class<T> messageType) {
-    SchemaUtil.requireGeneratedMessage(messageType);
-
-    MessageInfo messageInfo = messageInfoFactory.messageInfoFor(messageType);
-
-    // MessageSet has a special schema.
-    if (messageInfo.isMessageSetWireFormat()) {
-      if (GeneratedMessageLite.class.isAssignableFrom(messageType)) {
-        return MessageSetSchema.newSchema(
-            SchemaUtil.unknownFieldSetLiteSchema(),
-            ExtensionSchemas.lite(),
-            messageInfo.getDefaultInstance());
-      }
-      return MessageSetSchema.newSchema(
-          SchemaUtil.proto2UnknownFieldSetSchema(),
-          ExtensionSchemas.full(),
-          messageInfo.getDefaultInstance());
-    }
-
-    return newSchema(messageType, messageInfo);
-  }
-
-  private static <T> Schema<T> newSchema(Class<T> messageType, MessageInfo messageInfo) {
-    if (GeneratedMessageLite.class.isAssignableFrom(messageType)) {
-      return isProto2(messageInfo)
-          ? MessageSchema.newSchema(
-              messageType,
-              messageInfo,
-              NewInstanceSchemas.lite(),
-              ListFieldSchema.lite(),
-              SchemaUtil.unknownFieldSetLiteSchema(),
-              ExtensionSchemas.lite(),
-              MapFieldSchemas.lite())
-          : MessageSchema.newSchema(
-              messageType,
-              messageInfo,
-              NewInstanceSchemas.lite(),
-              ListFieldSchema.lite(),
-              SchemaUtil.unknownFieldSetLiteSchema(),
-              /* extensionSchema= */ null,
-              MapFieldSchemas.lite());
-    }
-    return isProto2(messageInfo)
-        ? MessageSchema.newSchema(
-            messageType,
-            messageInfo,
-            NewInstanceSchemas.full(),
-            ListFieldSchema.full(),
-            SchemaUtil.proto2UnknownFieldSetSchema(),
-            ExtensionSchemas.full(),
-            MapFieldSchemas.full())
-        : MessageSchema.newSchema(
-            messageType,
-            messageInfo,
-            NewInstanceSchemas.full(),
-            ListFieldSchema.full(),
-            SchemaUtil.proto3UnknownFieldSetSchema(),
-            /* extensionSchema= */ null,
-            MapFieldSchemas.full());
-  }
-
-  private static boolean isProto2(MessageInfo messageInfo) {
-    return messageInfo.getSyntax() == ProtoSyntax.PROTO2;
-  }
-
-  private static MessageInfoFactory getDefaultMessageInfoFactory() {
-    return new CompositeMessageInfoFactory(
-        GeneratedMessageInfoFactory.getInstance(), getDescriptorMessageInfoFactory());
-  }
-
-  private static class CompositeMessageInfoFactory implements MessageInfoFactory {
-    private MessageInfoFactory[] factories;
-
-    CompositeMessageInfoFactory(MessageInfoFactory... factories) {
-      this.factories = factories;
-    }
-
-    @Override
-    public boolean isSupported(Class<?> clazz) {
-      for (MessageInfoFactory factory : factories) {
-        if (factory.isSupported(clazz)) {
-          return true;
-        }
-      }
-      return false;
-    }
-
-    @Override
-    public MessageInfo messageInfoFor(Class<?> clazz) {
-      for (MessageInfoFactory factory : factories) {
-        if (factory.isSupported(clazz)) {
-          return factory.messageInfoFor(clazz);
-        }
-      }
-      throw new UnsupportedOperationException(
-          "No factory is available for message type: " + clazz.getName());
-    }
-  }
-
-  private static final MessageInfoFactory EMPTY_FACTORY =
-      new MessageInfoFactory() {
-        @Override
-        public boolean isSupported(Class<?> clazz) {
-          return false;
-        }
-
-        @Override
-        public MessageInfo messageInfoFor(Class<?> clazz) {
-          throw new IllegalStateException("This should never be called.");
-        }
-      };
-
-  private static MessageInfoFactory getDescriptorMessageInfoFactory() {
-    try {
-      Class<?> clazz = Class.forName("com.google.protobuf.DescriptorMessageInfoFactory");
-      return (MessageInfoFactory) clazz.getDeclaredMethod("getInstance").invoke(null);
-    } catch (Exception e) {
-      return EMPTY_FACTORY;
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MapEntryLite.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/MapEntryLite.java
deleted file mode 100644
index 81bf4c2..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MapEntryLite.java
+++ /dev/null
@@ -1,231 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.io.IOException;
-import java.util.AbstractMap;
-import java.util.Map;
-
-/**
- * Implements the lite version of map entry messages.
- *
- * <p>This class serves as an utility class to help do serialization/parsing of map entries. It's
- * used in generated code and also in the full version MapEntry message.
- *
- * <p>Protobuf internal. Users shouldn't use.
- */
-public class MapEntryLite<K, V> {
-
-  static class Metadata<K, V> {
-    public final WireFormat.FieldType keyType;
-    public final K defaultKey;
-    public final WireFormat.FieldType valueType;
-    public final V defaultValue;
-
-    public Metadata(
-        WireFormat.FieldType keyType,
-        K defaultKey,
-        WireFormat.FieldType valueType,
-        V defaultValue) {
-      this.keyType = keyType;
-      this.defaultKey = defaultKey;
-      this.valueType = valueType;
-      this.defaultValue = defaultValue;
-    }
-  }
-
-  private static final int KEY_FIELD_NUMBER = 1;
-  private static final int VALUE_FIELD_NUMBER = 2;
-
-  private final Metadata<K, V> metadata;
-  private final K key;
-  private final V value;
-
-  /** Creates a default MapEntryLite message instance. */
-  private MapEntryLite(
-      WireFormat.FieldType keyType, K defaultKey, WireFormat.FieldType valueType, V defaultValue) {
-    this.metadata = new Metadata<K, V>(keyType, defaultKey, valueType, defaultValue);
-    this.key = defaultKey;
-    this.value = defaultValue;
-  }
-
-  /** Creates a new MapEntryLite message. */
-  private MapEntryLite(Metadata<K, V> metadata, K key, V value) {
-    this.metadata = metadata;
-    this.key = key;
-    this.value = value;
-  }
-
-  public K getKey() {
-    return key;
-  }
-
-  public V getValue() {
-    return value;
-  }
-
-  /**
-   * Creates a default MapEntryLite message instance.
-   *
-   * <p>This method is used by generated code to create the default instance for a map entry
-   * message. The created default instance should be used to create new map entry messages of the
-   * same type. For each map entry message, only one default instance should be created.
-   */
-  public static <K, V> MapEntryLite<K, V> newDefaultInstance(
-      WireFormat.FieldType keyType, K defaultKey, WireFormat.FieldType valueType, V defaultValue) {
-    return new MapEntryLite<K, V>(keyType, defaultKey, valueType, defaultValue);
-  }
-
-  static <K, V> void writeTo(CodedOutputStream output, Metadata<K, V> metadata, K key, V value)
-      throws IOException {
-    FieldSet.writeElement(output, metadata.keyType, KEY_FIELD_NUMBER, key);
-    FieldSet.writeElement(output, metadata.valueType, VALUE_FIELD_NUMBER, value);
-  }
-
-  static <K, V> int computeSerializedSize(Metadata<K, V> metadata, K key, V value) {
-    return FieldSet.computeElementSize(metadata.keyType, KEY_FIELD_NUMBER, key)
-        + FieldSet.computeElementSize(metadata.valueType, VALUE_FIELD_NUMBER, value);
-  }
-
-  @SuppressWarnings("unchecked")
-  static <T> T parseField(
-      CodedInputStream input,
-      ExtensionRegistryLite extensionRegistry,
-      WireFormat.FieldType type,
-      T value)
-      throws IOException {
-    switch (type) {
-      case MESSAGE:
-        MessageLite.Builder subBuilder = ((MessageLite) value).toBuilder();
-        input.readMessage(subBuilder, extensionRegistry);
-        return (T) subBuilder.buildPartial();
-      case ENUM:
-        return (T) (java.lang.Integer) input.readEnum();
-      case GROUP:
-        throw new RuntimeException("Groups are not allowed in maps.");
-      default:
-        return (T) FieldSet.readPrimitiveField(input, type, true);
-    }
-  }
-
-  /**
-   * Serializes the provided key and value as though they were wrapped by a {@link MapEntryLite} to
-   * the output stream. This helper method avoids allocation of a {@link MapEntryLite} built with a
-   * key and value and is called from generated code directly.
-   */
-  public void serializeTo(CodedOutputStream output, int fieldNumber, K key, V value)
-      throws IOException {
-    output.writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
-    output.writeUInt32NoTag(computeSerializedSize(metadata, key, value));
-    writeTo(output, metadata, key, value);
-  }
-
-  /**
-   * Computes the message size for the provided key and value as though they were wrapped by a
-   * {@link MapEntryLite}. This helper method avoids allocation of a {@link MapEntryLite} built with
-   * a key and value and is called from generated code directly.
-   */
-  public int computeMessageSize(int fieldNumber, K key, V value) {
-    return CodedOutputStream.computeTagSize(fieldNumber)
-        + CodedOutputStream.computeLengthDelimitedFieldSize(
-            computeSerializedSize(metadata, key, value));
-  }
-
-  /**
-   * Parses an entry off of the input as a {@link Map.Entry}. This helper requires an allocation so
-   * using {@link #parseInto} is preferred if possible.
-   */
-  public Map.Entry<K, V> parseEntry(ByteString bytes, ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    return parseEntry(bytes.newCodedInput(), metadata, extensionRegistry);
-  }
-
-  static <K, V> Map.Entry<K, V> parseEntry(
-      CodedInputStream input, Metadata<K, V> metadata, ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    K key = metadata.defaultKey;
-    V value = metadata.defaultValue;
-    while (true) {
-      int tag = input.readTag();
-      if (tag == 0) {
-        break;
-      }
-      if (tag == WireFormat.makeTag(KEY_FIELD_NUMBER, metadata.keyType.getWireType())) {
-        key = parseField(input, extensionRegistry, metadata.keyType, key);
-      } else if (tag == WireFormat.makeTag(VALUE_FIELD_NUMBER, metadata.valueType.getWireType())) {
-        value = parseField(input, extensionRegistry, metadata.valueType, value);
-      } else {
-        if (!input.skipField(tag)) {
-          break;
-        }
-      }
-    }
-    return new AbstractMap.SimpleImmutableEntry<K, V>(key, value);
-  }
-
-  /**
-   * Parses an entry off of the input into the map. This helper avoids allocation of a {@link
-   * MapEntryLite} by parsing directly into the provided {@link MapFieldLite}.
-   */
-  public void parseInto(
-      MapFieldLite<K, V> map, CodedInputStream input, ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    int length = input.readRawVarint32();
-    final int oldLimit = input.pushLimit(length);
-    K key = metadata.defaultKey;
-    V value = metadata.defaultValue;
-
-    while (true) {
-      int tag = input.readTag();
-      if (tag == 0) {
-        break;
-      }
-      if (tag == WireFormat.makeTag(KEY_FIELD_NUMBER, metadata.keyType.getWireType())) {
-        key = parseField(input, extensionRegistry, metadata.keyType, key);
-      } else if (tag == WireFormat.makeTag(VALUE_FIELD_NUMBER, metadata.valueType.getWireType())) {
-        value = parseField(input, extensionRegistry, metadata.valueType, value);
-      } else {
-        if (!input.skipField(tag)) {
-          break;
-        }
-      }
-    }
-
-    input.checkLastTagWas(0);
-    input.popLimit(oldLimit);
-    map.put(key, value);
-  }
-
-  /** For experimental runtime internal use only. */
-  Metadata<K, V> getMetadata() {
-    return metadata;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MapFieldLite.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/MapFieldLite.java
deleted file mode 100644
index a9fec4d..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MapFieldLite.java
+++ /dev/null
@@ -1,235 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.Internal.checkNotNull;
-
-import com.google.protobuf.Internal.EnumLite;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Internal representation of map fields in generated lite-runtime messages.
- *
- * <p>This class is a protobuf implementation detail. Users shouldn't use this class directly.
- */
-public final class MapFieldLite<K, V> extends LinkedHashMap<K, V> {
-
-  private boolean isMutable;
-
-  private MapFieldLite() {
-    this.isMutable = true;
-  }
-
-  private MapFieldLite(Map<K, V> mapData) {
-    super(mapData);
-    this.isMutable = true;
-  }
-
-  @SuppressWarnings({"rawtypes", "unchecked"})
-  private static final MapFieldLite EMPTY_MAP_FIELD = new MapFieldLite<>();
-
-  static {
-    EMPTY_MAP_FIELD.makeImmutable();
-  }
-
-  /** Returns an singleton immutable empty MapFieldLite instance. */
-  @SuppressWarnings({"unchecked", "cast"})
-  public static <K, V> MapFieldLite<K, V> emptyMapField() {
-    return (MapFieldLite<K, V>) EMPTY_MAP_FIELD;
-  }
-
-  public void mergeFrom(MapFieldLite<K, V> other) {
-    ensureMutable();
-    if (!other.isEmpty()) {
-      putAll(other);
-    }
-  }
-
-  @SuppressWarnings({"unchecked", "cast"})
-  @Override
-  public Set<Map.Entry<K, V>> entrySet() {
-    return isEmpty() ? Collections.<Map.Entry<K, V>>emptySet() : super.entrySet();
-  }
-
-  @Override
-  public void clear() {
-    ensureMutable();
-    super.clear();
-  }
-
-  @Override
-  public V put(K key, V value) {
-    ensureMutable();
-    checkNotNull(key);
-
-    checkNotNull(value);
-    return super.put(key, value);
-  }
-
-  public V put(Map.Entry<K, V> entry) {
-    return put(entry.getKey(), entry.getValue());
-  }
-
-  @Override
-  public void putAll(Map<? extends K, ? extends V> m) {
-    ensureMutable();
-    checkForNullKeysAndValues(m);
-    super.putAll(m);
-  }
-
-  @Override
-  public V remove(Object key) {
-    ensureMutable();
-    return super.remove(key);
-  }
-
-  private static void checkForNullKeysAndValues(Map<?, ?> m) {
-    for (Object key : m.keySet()) {
-      checkNotNull(key);
-      checkNotNull(m.get(key));
-    }
-  }
-
-  private static boolean equals(Object a, Object b) {
-    if (a instanceof byte[] && b instanceof byte[]) {
-      return Arrays.equals((byte[]) a, (byte[]) b);
-    }
-    return a.equals(b);
-  }
-
-  /**
-   * Checks whether two {@link Map}s are equal. We don't use the default equals method of {@link
-   * Map} because it compares by identity not by content for byte arrays.
-   */
-  static <K, V> boolean equals(Map<K, V> a, Map<K, V> b) {
-    if (a == b) {
-      return true;
-    }
-    if (a.size() != b.size()) {
-      return false;
-    }
-    for (Map.Entry<K, V> entry : a.entrySet()) {
-      if (!b.containsKey(entry.getKey())) {
-        return false;
-      }
-      if (!equals(entry.getValue(), b.get(entry.getKey()))) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  /** Checks whether two map fields are equal. */
-  @SuppressWarnings("unchecked")
-  @Override
-  public boolean equals(Object object) {
-    return (object instanceof Map) && equals(this, (Map<K, V>) object);
-  }
-
-  private static int calculateHashCodeForObject(Object a) {
-    if (a instanceof byte[]) {
-      return Internal.hashCode((byte[]) a);
-    }
-    // Enums should be stored as integers internally.
-    if (a instanceof EnumLite) {
-      throw new UnsupportedOperationException();
-    }
-    return a.hashCode();
-  }
-
-  /**
-   * Calculates the hash code for a {@link Map}. We don't use the default hash code method of {@link
-   * Map} because for byte arrays and protobuf enums it use {@link Object#hashCode()}.
-   */
-  static <K, V> int calculateHashCodeForMap(Map<K, V> a) {
-    int result = 0;
-    for (Map.Entry<K, V> entry : a.entrySet()) {
-      result +=
-          calculateHashCodeForObject(entry.getKey()) ^ calculateHashCodeForObject(entry.getValue());
-    }
-    return result;
-  }
-
-  @Override
-  public int hashCode() {
-    return calculateHashCodeForMap(this);
-  }
-
-  private static Object copy(Object object) {
-    if (object instanceof byte[]) {
-      byte[] data = (byte[]) object;
-      return Arrays.copyOf(data, data.length);
-    }
-    return object;
-  }
-
-  /**
-   * Makes a deep copy of a {@link Map}. Immutable objects in the map will be shared (e.g.,
-   * integers, strings, immutable messages) and mutable ones will have a copy (e.g., byte arrays,
-   * mutable messages).
-   */
-  @SuppressWarnings("unchecked")
-  static <K, V> Map<K, V> copy(Map<K, V> map) {
-    Map<K, V> result = new LinkedHashMap<K, V>();
-    for (Map.Entry<K, V> entry : map.entrySet()) {
-      result.put(entry.getKey(), (V) copy(entry.getValue()));
-    }
-    return result;
-  }
-
-  /** Returns a deep copy of this map field. */
-  public MapFieldLite<K, V> mutableCopy() {
-    return isEmpty() ? new MapFieldLite<K, V>() : new MapFieldLite<K, V>(this);
-  }
-
-  /**
-   * Makes this field immutable. All subsequent modifications will throw an {@link
-   * UnsupportedOperationException}.
-   */
-  public void makeImmutable() {
-    isMutable = false;
-  }
-
-  /** Returns whether this field can be modified. */
-  public boolean isMutable() {
-    return isMutable;
-  }
-
-  private void ensureMutable() {
-    if (!isMutable()) {
-      throw new UnsupportedOperationException();
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MapFieldSchema.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/MapFieldSchema.java
deleted file mode 100644
index 195126e..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MapFieldSchema.java
+++ /dev/null
@@ -1,63 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.util.Map;
-
-interface MapFieldSchema {
-  /** Returns the map data for mutation. */
-  Map<?, ?> forMutableMapData(Object mapField);
-
-  /** Returns the map data for read. */
-  Map<?, ?> forMapData(Object mapField);
-
-  /** Whether toImmutable() has been called on this map field. */
-  boolean isImmutable(Object mapField);
-
-  /**
-   * Returns an immutable instance of the map field. It may make the parameter immutable and return
-   * the parameter, or create an immutable copy. The status of the parameter after the call is
-   * undefined.
-   */
-  Object toImmutable(Object mapField);
-
-  /** Returns a new instance of the map field given a map default entry. */
-  Object newMapField(Object mapDefaultEntry);
-
-  /** Returns the metadata from a default entry. */
-  MapEntryLite.Metadata<?, ?> forMapMetadata(Object mapDefaultEntry);
-
-  /** Merges {@code srcMapField} into {@code destMapField}, and returns the merged instance. */
-  Object mergeFrom(Object destMapField, Object srcMapField);
-
-  /** Compute the serialized size for the map with a given field number. */
-  int getSerializedSize(int fieldNumber, Object mapField, Object mapDefaultEntry);
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MapFieldSchemaLite.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/MapFieldSchemaLite.java
deleted file mode 100644
index 8a8c78d..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MapFieldSchemaLite.java
+++ /dev/null
@@ -1,107 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import com.google.protobuf.MapEntryLite.Metadata;
-import java.util.Map;
-
-class MapFieldSchemaLite implements MapFieldSchema {
-
-  @Override
-  public Map<?, ?> forMutableMapData(Object mapField) {
-    return (MapFieldLite<?, ?>) mapField;
-  }
-
-  @Override
-  public Metadata<?, ?> forMapMetadata(Object mapDefaultEntry) {
-    return ((MapEntryLite<?, ?>) mapDefaultEntry).getMetadata();
-  }
-
-  @Override
-  public Map<?, ?> forMapData(Object mapField) {
-    return (MapFieldLite<?, ?>) mapField;
-  }
-
-  @Override
-  public boolean isImmutable(Object mapField) {
-    return !((MapFieldLite<?, ?>) mapField).isMutable();
-  }
-
-  @Override
-  public Object toImmutable(Object mapField) {
-    ((MapFieldLite<?, ?>) mapField).makeImmutable();
-    return mapField;
-  }
-
-  @Override
-  public Object newMapField(Object unused) {
-    return MapFieldLite.emptyMapField().mutableCopy();
-  }
-
-  @Override
-  public Object mergeFrom(Object destMapField, Object srcMapField) {
-    return mergeFromLite(destMapField, srcMapField);
-  }
-
-  @SuppressWarnings("unchecked")
-  private static <K, V> MapFieldLite<K, V> mergeFromLite(Object destMapField, Object srcMapField) {
-    MapFieldLite<K, V> mine = (MapFieldLite<K, V>) destMapField;
-    MapFieldLite<K, V> other = (MapFieldLite<K, V>) srcMapField;
-    if (!other.isEmpty()) {
-      if (!mine.isMutable()) {
-        mine = mine.mutableCopy();
-      }
-      mine.mergeFrom(other);
-    }
-    return mine;
-  }
-
-  @Override
-  public int getSerializedSize(int fieldNumber, Object mapField, Object mapDefaultEntry) {
-    return getSerializedSizeLite(fieldNumber, mapField, mapDefaultEntry);
-  }
-
-  @SuppressWarnings("unchecked")
-  private static <K, V> int getSerializedSizeLite(
-      int fieldNumber, Object mapField, Object defaultEntry) {
-    MapFieldLite<K, V> mapFieldLite = (MapFieldLite<K, V>) mapField;
-    MapEntryLite<K, V> defaultEntryLite = (MapEntryLite<K, V>) defaultEntry;
-
-    if (mapFieldLite.isEmpty()) {
-      return 0;
-    }
-    int size = 0;
-    for (Map.Entry<K, V> entry : mapFieldLite.entrySet()) {
-      size += defaultEntryLite.computeMessageSize(fieldNumber, entry.getKey(), entry.getValue());
-    }
-    return size;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MapFieldSchemas.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/MapFieldSchemas.java
deleted file mode 100644
index b398c61..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MapFieldSchemas.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-final class MapFieldSchemas {
-  private static final MapFieldSchema FULL_SCHEMA = loadSchemaForFullRuntime();
-  private static final MapFieldSchema LITE_SCHEMA = new MapFieldSchemaLite();
-
-  static MapFieldSchema full() {
-    return FULL_SCHEMA;
-  }
-
-  static MapFieldSchema lite() {
-    return LITE_SCHEMA;
-  }
-
-  private static MapFieldSchema loadSchemaForFullRuntime() {
-    try {
-      Class<?> clazz = Class.forName("com.google.protobuf.MapFieldSchemaFull");
-      return (MapFieldSchema) clazz.getDeclaredConstructor().newInstance();
-    } catch (Exception e) {
-      return null;
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageInfo.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageInfo.java
deleted file mode 100644
index 69e3186..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageInfo.java
+++ /dev/null
@@ -1,43 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-/** A MesageInfo object describes a proto message type. */
-interface MessageInfo {
-  /** Gets syntax for this type. */
-  ProtoSyntax getSyntax();
-
-  /** Whether this type is MessageSet. */
-  boolean isMessageSetWireFormat();
-
-  /** Gets the default instance of this type. */
-  MessageLite getDefaultInstance();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageInfoFactory.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageInfoFactory.java
deleted file mode 100644
index 005c26d..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageInfoFactory.java
+++ /dev/null
@@ -1,41 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-/** A factory that creates {@link MessageInfo} instances for message types. */
-@ExperimentalApi
-interface MessageInfoFactory {
-  /** Whether the message class is supported by this factory. */
-  boolean isSupported(Class<?> clazz);
-
-  /** Returns a information of the message class. */
-  MessageInfo messageInfoFor(Class<?> clazz);
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageLite.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageLite.java
deleted file mode 100644
index 7d2ef33..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageLite.java
+++ /dev/null
@@ -1,298 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// TODO(kenton):  Use generics?  E.g. Builder<BuilderType extends Builder>, then
-//   mergeFrom*() could return BuilderType for better type-safety.
-
-package com.google.protobuf;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * Abstract interface implemented by Protocol Message objects.
- *
- * <p>This interface is implemented by all protocol message objects. Non-lite messages additionally
- * implement the Message interface, which is a subclass of MessageLite. Use MessageLite instead when
- * you only need the subset of features which it supports -- namely, nothing that uses descriptors
- * or reflection. You can instruct the protocol compiler to generate classes which implement only
- * MessageLite, not the full Message interface, by adding the follow line to the .proto file:
- *
- * <pre>
- *   option optimize_for = LITE_RUNTIME;
- * </pre>
- *
- * <p>This is particularly useful on resource-constrained systems where the full protocol buffers
- * runtime library is too big.
- *
- * <p>Note that on non-constrained systems (e.g. servers) when you need to link in lots of protocol
- * definitions, a better way to reduce total code footprint is to use {@code optimize_for =
- * CODE_SIZE}. This will make the generated code smaller while still supporting all the same
- * features (at the expense of speed). {@code optimize_for = LITE_RUNTIME} is best when you only
- * have a small number of message types linked into your binary, in which case the size of the
- * protocol buffers runtime itself is the biggest problem.
- *
- * @author kenton@google.com Kenton Varda
- */
-public interface MessageLite extends MessageLiteOrBuilder {
-
-  /**
-   * Serializes the message and writes it to {@code output}. This does not flush or close the
-   * stream.
-   */
-  void writeTo(CodedOutputStream output) throws IOException;
-
-  /**
-   * Get the number of bytes required to encode this message. The result is only computed on the
-   * first call and memoized after that.
-   */
-  int getSerializedSize();
-
-  /** Gets the parser for a message of the same type as this message. */
-  Parser<? extends MessageLite> getParserForType();
-
-  // -----------------------------------------------------------------
-  // Convenience methods.
-
-  /**
-   * Serializes the message to a {@code ByteString} and returns it. This is just a trivial wrapper
-   * around {@link #writeTo(CodedOutputStream)}.
-   */
-  ByteString toByteString();
-
-  /**
-   * Serializes the message to a {@code byte} array and returns it. This is just a trivial wrapper
-   * around {@link #writeTo(CodedOutputStream)}.
-   */
-  byte[] toByteArray();
-
-  /**
-   * Serializes the message and writes it to {@code output}. This is just a trivial wrapper around
-   * {@link #writeTo(CodedOutputStream)}. This does not flush or close the stream.
-   *
-   * <p>NOTE: Protocol Buffers are not self-delimiting. Therefore, if you write any more data to the
-   * stream after the message, you must somehow ensure that the parser on the receiving end does not
-   * interpret this as being part of the protocol message. This can be done e.g. by writing the size
-   * of the message before the data, then making sure to limit the input to that size on the
-   * receiving end (e.g. by wrapping the InputStream in one which limits the input). Alternatively,
-   * just use {@link #writeDelimitedTo(OutputStream)}.
-   */
-  void writeTo(OutputStream output) throws IOException;
-
-  /**
-   * Like {@link #writeTo(OutputStream)}, but writes the size of the message as a varint before
-   * writing the data. This allows more data to be written to the stream after the message without
-   * the need to delimit the message data yourself. Use {@link
-   * Builder#mergeDelimitedFrom(InputStream)} (or the static method {@code
-   * YourMessageType.parseDelimitedFrom(InputStream)}) to parse messages written by this method.
-   */
-  void writeDelimitedTo(OutputStream output) throws IOException;
-
-
-  // =================================================================
-  // Builders
-
-  /** Constructs a new builder for a message of the same type as this message. */
-  Builder newBuilderForType();
-
-  /**
-   * Constructs a builder initialized with the current message. Use this to derive a new message
-   * from the current one.
-   */
-  Builder toBuilder();
-
-  /** Abstract interface implemented by Protocol Message builders. */
-  interface Builder extends MessageLiteOrBuilder, Cloneable {
-    /** Resets all fields to their default values. */
-    Builder clear();
-
-    /**
-     * Constructs the message based on the state of the Builder. Subsequent changes to the Builder
-     * will not affect the returned message.
-     *
-     * @throws UninitializedMessageException The message is missing one or more required fields
-     *     (i.e. {@link #isInitialized()} returns false). Use {@link #buildPartial()} to bypass this
-     *     check.
-     */
-    MessageLite build();
-
-    /**
-     * Like {@link #build()}, but does not throw an exception if the message is missing required
-     * fields. Instead, a partial message is returned. Subsequent changes to the Builder will not
-     * affect the returned message.
-     */
-    MessageLite buildPartial();
-
-    /**
-     * Clones the Builder.
-     *
-     * @see Object#clone()
-     */
-    Builder clone();
-
-    /**
-     * Parses a message of this type from the input and merges it with this message.
-     *
-     * <p>Warning: This does not verify that all required fields are present in the input message.
-     * If you call {@link #build()} without setting all required fields, it will throw an {@link
-     * UninitializedMessageException}, which is a {@code RuntimeException} and thus might not be
-     * caught. There are a few good ways to deal with this:
-     *
-     * <ul>
-     *   <li>Call {@link #isInitialized()} to verify that all required fields are set before
-     *       building.
-     *   <li>Use {@code buildPartial()} to build, which ignores missing required fields.
-     * </ul>
-     *
-     * <p>Note: The caller should call {@link CodedInputStream#checkLastTagWas(int)} after calling
-     * this to verify that the last tag seen was the appropriate end-group tag, or zero for EOF.
-     */
-    Builder mergeFrom(CodedInputStream input) throws IOException;
-
-    /**
-     * Like {@link Builder#mergeFrom(CodedInputStream)}, but also parses extensions. The extensions
-     * that you want to be able to parse must be registered in {@code extensionRegistry}. Extensions
-     * not in the registry will be treated as unknown fields.
-     */
-    Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
-        throws IOException;
-
-    // ---------------------------------------------------------------
-    // Convenience methods.
-
-    /**
-     * Parse {@code data} as a message of this type and merge it with the message being built. This
-     * is just a small wrapper around {@link #mergeFrom(CodedInputStream)}.
-     *
-     * @return this
-     */
-    Builder mergeFrom(ByteString data) throws InvalidProtocolBufferException;
-
-    /**
-     * Parse {@code data} as a message of this type and merge it with the message being built. This
-     * is just a small wrapper around {@link #mergeFrom(CodedInputStream,ExtensionRegistryLite)}.
-     *
-     * @return this
-     */
-    Builder mergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
-        throws InvalidProtocolBufferException;
-
-    /**
-     * Parse {@code data} as a message of this type and merge it with the message being built. This
-     * is just a small wrapper around {@link #mergeFrom(CodedInputStream)}.
-     *
-     * @return this
-     */
-    Builder mergeFrom(byte[] data) throws InvalidProtocolBufferException;
-
-    /**
-     * Parse {@code data} as a message of this type and merge it with the message being built. This
-     * is just a small wrapper around {@link #mergeFrom(CodedInputStream)}.
-     *
-     * @return this
-     */
-    Builder mergeFrom(byte[] data, int off, int len) throws InvalidProtocolBufferException;
-
-    /**
-     * Parse {@code data} as a message of this type and merge it with the message being built. This
-     * is just a small wrapper around {@link #mergeFrom(CodedInputStream,ExtensionRegistryLite)}.
-     *
-     * @return this
-     */
-    Builder mergeFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
-        throws InvalidProtocolBufferException;
-
-    /**
-     * Parse {@code data} as a message of this type and merge it with the message being built. This
-     * is just a small wrapper around {@link #mergeFrom(CodedInputStream,ExtensionRegistryLite)}.
-     *
-     * @return this
-     */
-    Builder mergeFrom(byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
-        throws InvalidProtocolBufferException;
-
-    /**
-     * Parse a message of this type from {@code input} and merge it with the message being built.
-     * This is just a small wrapper around {@link #mergeFrom(CodedInputStream)}. Note that this
-     * method always reads the <i>entire</i> input (unless it throws an exception). If you want it
-     * to stop earlier, you will need to wrap your input in some wrapper stream that limits reading.
-     * Or, use {@link MessageLite#writeDelimitedTo(OutputStream)} to write your message and {@link
-     * #mergeDelimitedFrom(InputStream)} to read it.
-     *
-     * <p>Despite usually reading the entire input, this does not close the stream.
-     *
-     * @return this
-     */
-    Builder mergeFrom(InputStream input) throws IOException;
-
-    /**
-     * Parse a message of this type from {@code input} and merge it with the message being built.
-     * This is just a small wrapper around {@link
-     * #mergeFrom(CodedInputStream,ExtensionRegistryLite)}.
-     *
-     * @return this
-     */
-    Builder mergeFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
-        throws IOException;
-
-    /**
-     * Merge {@code other} into the message being built. {@code other} must have the exact same type
-     * as {@code this} (i.e. {@code getClass().equals(getDefaultInstanceForType().getClass())}).
-     *
-     * <p>Merging occurs as follows. For each field:<br>
-     * * For singular primitive fields, if the field is set in {@code other}, then {@code other}'s
-     * value overwrites the value in this message.<br>
-     * * For singular message fields, if the field is set in {@code other}, it is merged into the
-     * corresponding sub-message of this message using the same merging rules.<br>
-     * * For repeated fields, the elements in {@code other} are concatenated with the elements in
-     * this message. * For oneof groups, if the other message has one of the fields set, the group
-     * of this message is cleared and replaced by the field of the other message, so that the oneof
-     * constraint is preserved.
-     *
-     * <p>This is equivalent to the {@code Message::MergeFrom} method in C++.
-     */
-    Builder mergeFrom(MessageLite other);
-
-    /**
-     * Like {@link #mergeFrom(InputStream)}, but does not read until EOF. Instead, the size of the
-     * message (encoded as a varint) is read first, then the message data. Use {@link
-     * MessageLite#writeDelimitedTo(OutputStream)} to write messages in this format.
-     *
-     * @return True if successful, or false if the stream is at EOF when the method starts. Any
-     *     other error (including reaching EOF during parsing) will cause an exception to be thrown.
-     */
-    boolean mergeDelimitedFrom(InputStream input) throws IOException;
-
-    /** Like {@link #mergeDelimitedFrom(InputStream)} but supporting extensions. */
-    boolean mergeDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
-        throws IOException;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageLiteOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageLiteOrBuilder.java
deleted file mode 100644
index 7a5ef3e..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageLiteOrBuilder.java
+++ /dev/null
@@ -1,57 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-/**
- * Base interface for methods common to {@link MessageLite} and {@link MessageLite.Builder} to
- * provide type equivalency.
- *
- * @author jonp@google.com (Jon Perlow)
- */
-public interface MessageLiteOrBuilder {
-  /**
-   * Get an instance of the type with no fields set. Because no fields are set, all getters for
-   * singular fields will return default values and repeated fields will appear empty. This may or
-   * may not be a singleton. This differs from the {@code getDefaultInstance()} method of generated
-   * message classes in that this method is an abstract method of the {@code MessageLite} interface
-   * whereas {@code getDefaultInstance()} is a static method of a specific class. They return the
-   * same thing.
-   */
-  MessageLite getDefaultInstanceForType();
-
-  /**
-   * Returns true if all required fields in the message and all embedded messages are set, false
-   * otherwise.
-   *
-   * <p>See also: {@link MessageOrBuilder#getInitializationErrorString()}
-   */
-  boolean isInitialized();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageLiteToString.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageLiteToString.java
deleted file mode 100644
index 4aea952..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageLiteToString.java
+++ /dev/null
@@ -1,281 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-
-/** Helps generate {@link String} representations of {@link MessageLite} protos. */
-final class MessageLiteToString {
-
-  private static final String LIST_SUFFIX = "List";
-  private static final String BUILDER_LIST_SUFFIX = "OrBuilderList";
-  private static final String MAP_SUFFIX = "Map";
-  private static final String BYTES_SUFFIX = "Bytes";
-
-  /**
-   * Returns a {@link String} representation of the {@link MessageLite} object. The first line of
-   * the {@code String} representation representation includes a comment string to uniquely identify
-   * the object instance. This acts as an indicator that this should not be relied on for
-   * comparisons.
-   *
-   * <p>For use by generated code only.
-   */
-  static String toString(MessageLite messageLite, String commentString) {
-    StringBuilder buffer = new StringBuilder();
-    buffer.append("# ").append(commentString);
-    reflectivePrintWithIndent(messageLite, buffer, 0);
-    return buffer.toString();
-  }
-
-  /**
-   * Reflectively prints the {@link MessageLite} to the buffer at given {@code indent} level.
-   *
-   * @param buffer the buffer to write to
-   * @param indent the number of spaces to indent the proto by
-   */
-  private static void reflectivePrintWithIndent(
-      MessageLite messageLite, StringBuilder buffer, int indent) {
-    // Build a map of method name to method. We're looking for methods like getFoo(), hasFoo(),
-    // getFooList() and getFooMap() which might be useful for building an object's string
-    // representation.
-    Map<String, Method> nameToNoArgMethod = new HashMap<String, Method>();
-    Map<String, Method> nameToMethod = new HashMap<String, Method>();
-    Set<String> getters = new TreeSet<String>();
-    for (Method method : messageLite.getClass().getDeclaredMethods()) {
-      nameToMethod.put(method.getName(), method);
-      if (method.getParameterTypes().length == 0) {
-        nameToNoArgMethod.put(method.getName(), method);
-
-        if (method.getName().startsWith("get")) {
-          getters.add(method.getName());
-        }
-      }
-    }
-
-    for (String getter : getters) {
-      String suffix = getter.startsWith("get") ? getter.substring(3) : getter;
-      if (suffix.endsWith(LIST_SUFFIX)
-          && !suffix.endsWith(BUILDER_LIST_SUFFIX)
-          // Sometimes people have fields named 'list' that aren't repeated.
-          && !suffix.equals(LIST_SUFFIX)) {
-        String camelCase =
-            suffix.substring(0, 1).toLowerCase()
-                + suffix.substring(1, suffix.length() - LIST_SUFFIX.length());
-        // Try to reflectively get the value and toString() the field as if it were repeated. This
-        // only works if the method names have not been proguarded out or renamed.
-        Method listMethod = nameToNoArgMethod.get(getter);
-        if (listMethod != null && listMethod.getReturnType().equals(List.class)) {
-          printField(
-              buffer,
-              indent,
-              camelCaseToSnakeCase(camelCase),
-              GeneratedMessageLite.invokeOrDie(listMethod, messageLite));
-          continue;
-        }
-      }
-      if (suffix.endsWith(MAP_SUFFIX)
-          // Sometimes people have fields named 'map' that aren't maps.
-          && !suffix.equals(MAP_SUFFIX)) {
-        String camelCase =
-            suffix.substring(0, 1).toLowerCase()
-                + suffix.substring(1, suffix.length() - MAP_SUFFIX.length());
-        // Try to reflectively get the value and toString() the field as if it were a map. This only
-        // works if the method names have not been proguarded out or renamed.
-        Method mapMethod = nameToNoArgMethod.get(getter);
-        if (mapMethod != null
-            && mapMethod.getReturnType().equals(Map.class)
-            // Skip the deprecated getter method with no prefix "Map" when the field name ends with
-            // "map".
-            && !mapMethod.isAnnotationPresent(Deprecated.class)
-            // Skip the internal mutable getter method.
-            && Modifier.isPublic(mapMethod.getModifiers())) {
-          printField(
-              buffer,
-              indent,
-              camelCaseToSnakeCase(camelCase),
-              GeneratedMessageLite.invokeOrDie(mapMethod, messageLite));
-          continue;
-        }
-      }
-
-      Method setter = nameToMethod.get("set" + suffix);
-      if (setter == null) {
-        continue;
-      }
-      if (suffix.endsWith(BYTES_SUFFIX)
-          && nameToNoArgMethod.containsKey(
-              "get" + suffix.substring(0, suffix.length() - "Bytes".length()))) {
-        // Heuristic to skip bytes based accessors for string fields.
-        continue;
-      }
-
-      String camelCase = suffix.substring(0, 1).toLowerCase() + suffix.substring(1);
-
-      // Try to reflectively get the value and toString() the field as if it were optional. This
-      // only works if the method names have not been proguarded out or renamed.
-      Method getMethod = nameToNoArgMethod.get("get" + suffix);
-      Method hasMethod = nameToNoArgMethod.get("has" + suffix);
-      // TODO(dweis): Fix proto3 semantics.
-      if (getMethod != null) {
-        Object value = GeneratedMessageLite.invokeOrDie(getMethod, messageLite);
-        final boolean hasValue =
-            hasMethod == null
-                ? !isDefaultValue(value)
-                : (Boolean) GeneratedMessageLite.invokeOrDie(hasMethod, messageLite);
-        // TODO(dweis): This doesn't stop printing oneof case twice: value and enum style.
-        if (hasValue) {
-          printField(buffer, indent, camelCaseToSnakeCase(camelCase), value);
-        }
-        continue;
-      }
-    }
-
-    if (messageLite instanceof GeneratedMessageLite.ExtendableMessage) {
-      Iterator<Map.Entry<GeneratedMessageLite.ExtensionDescriptor, Object>> iter =
-          ((GeneratedMessageLite.ExtendableMessage<?, ?>) messageLite).extensions.iterator();
-      while (iter.hasNext()) {
-        Map.Entry<GeneratedMessageLite.ExtensionDescriptor, Object> entry = iter.next();
-        printField(buffer, indent, "[" + entry.getKey().getNumber() + "]", entry.getValue());
-      }
-    }
-
-    if (((GeneratedMessageLite<?, ?>) messageLite).unknownFields != null) {
-      ((GeneratedMessageLite<?, ?>) messageLite).unknownFields.printWithIndent(buffer, indent);
-    }
-  }
-
-  private static boolean isDefaultValue(Object o) {
-    if (o instanceof Boolean) {
-      return !((Boolean) o);
-    }
-    if (o instanceof Integer) {
-      return ((Integer) o) == 0;
-    }
-    if (o instanceof Float) {
-      return ((Float) o) == 0f;
-    }
-    if (o instanceof Double) {
-      return ((Double) o) == 0d;
-    }
-    if (o instanceof String) {
-      return o.equals("");
-    }
-    if (o instanceof ByteString) {
-      return o.equals(ByteString.EMPTY);
-    }
-    if (o instanceof MessageLite) { // Can happen in oneofs.
-      return o == ((MessageLite) o).getDefaultInstanceForType();
-    }
-    if (o instanceof java.lang.Enum<?>) { // Catches oneof enums.
-      return ((java.lang.Enum<?>) o).ordinal() == 0;
-    }
-
-    return false;
-  }
-
-  /**
-   * Formats a text proto field.
-   *
-   * <p>For use by generated code only.
-   *
-   * @param buffer the buffer to write to
-   * @param indent the number of spaces the proto should be indented by
-   * @param name the field name (in lower underscore case)
-   * @param object the object value of the field
-   */
-  static final void printField(StringBuilder buffer, int indent, String name, Object object) {
-    if (object instanceof List<?>) {
-      List<?> list = (List<?>) object;
-      for (Object entry : list) {
-        printField(buffer, indent, name, entry);
-      }
-      return;
-    }
-    if (object instanceof Map<?, ?>) {
-      Map<?, ?> map = (Map<?, ?>) object;
-      for (Map.Entry<?, ?> entry : map.entrySet()) {
-        printField(buffer, indent, name, entry);
-      }
-      return;
-    }
-
-    buffer.append('\n');
-    for (int i = 0; i < indent; i++) {
-      buffer.append(' ');
-    }
-    buffer.append(name);
-
-    if (object instanceof String) {
-      buffer.append(": \"").append(TextFormatEscaper.escapeText((String) object)).append('"');
-    } else if (object instanceof ByteString) {
-      buffer.append(": \"").append(TextFormatEscaper.escapeBytes((ByteString) object)).append('"');
-    } else if (object instanceof GeneratedMessageLite) {
-      buffer.append(" {");
-      reflectivePrintWithIndent((GeneratedMessageLite<?, ?>) object, buffer, indent + 2);
-      buffer.append("\n");
-      for (int i = 0; i < indent; i++) {
-        buffer.append(' ');
-      }
-      buffer.append("}");
-    } else if (object instanceof Map.Entry<?, ?>) {
-      buffer.append(" {");
-      Map.Entry<?, ?> entry = (Map.Entry<?, ?>) object;
-      printField(buffer, indent + 2, "key", entry.getKey());
-      printField(buffer, indent + 2, "value", entry.getValue());
-      buffer.append("\n");
-      for (int i = 0; i < indent; i++) {
-        buffer.append(' ');
-      }
-      buffer.append("}");
-    } else {
-      buffer.append(": ").append(object.toString());
-    }
-  }
-
-  private static final String camelCaseToSnakeCase(String camelCase) {
-    StringBuilder builder = new StringBuilder();
-    for (int i = 0; i < camelCase.length(); i++) {
-      char ch = camelCase.charAt(i);
-      if (Character.isUpperCase(ch)) {
-        builder.append("_");
-      }
-      builder.append(Character.toLowerCase(ch));
-    }
-    return builder.toString();
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageSchema.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageSchema.java
deleted file mode 100644
index 33c8e91..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageSchema.java
+++ /dev/null
@@ -1,5930 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.ArrayDecoders.decodeBoolList;
-import static com.google.protobuf.ArrayDecoders.decodeBytes;
-import static com.google.protobuf.ArrayDecoders.decodeBytesList;
-import static com.google.protobuf.ArrayDecoders.decodeDouble;
-import static com.google.protobuf.ArrayDecoders.decodeDoubleList;
-import static com.google.protobuf.ArrayDecoders.decodeExtensionOrUnknownField;
-import static com.google.protobuf.ArrayDecoders.decodeFixed32;
-import static com.google.protobuf.ArrayDecoders.decodeFixed32List;
-import static com.google.protobuf.ArrayDecoders.decodeFixed64;
-import static com.google.protobuf.ArrayDecoders.decodeFixed64List;
-import static com.google.protobuf.ArrayDecoders.decodeFloat;
-import static com.google.protobuf.ArrayDecoders.decodeFloatList;
-import static com.google.protobuf.ArrayDecoders.decodeGroupField;
-import static com.google.protobuf.ArrayDecoders.decodeGroupList;
-import static com.google.protobuf.ArrayDecoders.decodeMessageField;
-import static com.google.protobuf.ArrayDecoders.decodeMessageList;
-import static com.google.protobuf.ArrayDecoders.decodePackedBoolList;
-import static com.google.protobuf.ArrayDecoders.decodePackedDoubleList;
-import static com.google.protobuf.ArrayDecoders.decodePackedFixed32List;
-import static com.google.protobuf.ArrayDecoders.decodePackedFixed64List;
-import static com.google.protobuf.ArrayDecoders.decodePackedFloatList;
-import static com.google.protobuf.ArrayDecoders.decodePackedSInt32List;
-import static com.google.protobuf.ArrayDecoders.decodePackedSInt64List;
-import static com.google.protobuf.ArrayDecoders.decodePackedVarint32List;
-import static com.google.protobuf.ArrayDecoders.decodePackedVarint64List;
-import static com.google.protobuf.ArrayDecoders.decodeSInt32List;
-import static com.google.protobuf.ArrayDecoders.decodeSInt64List;
-import static com.google.protobuf.ArrayDecoders.decodeString;
-import static com.google.protobuf.ArrayDecoders.decodeStringList;
-import static com.google.protobuf.ArrayDecoders.decodeStringListRequireUtf8;
-import static com.google.protobuf.ArrayDecoders.decodeStringRequireUtf8;
-import static com.google.protobuf.ArrayDecoders.decodeUnknownField;
-import static com.google.protobuf.ArrayDecoders.decodeVarint32;
-import static com.google.protobuf.ArrayDecoders.decodeVarint32List;
-import static com.google.protobuf.ArrayDecoders.decodeVarint64;
-import static com.google.protobuf.ArrayDecoders.decodeVarint64List;
-import static com.google.protobuf.ArrayDecoders.skipField;
-
-import com.google.protobuf.ArrayDecoders.Registers;
-import com.google.protobuf.ByteString.CodedBuilder;
-import com.google.protobuf.FieldSet.FieldDescriptorLite;
-import com.google.protobuf.Internal.EnumVerifier;
-import com.google.protobuf.Internal.ProtobufList;
-import com.google.protobuf.MapEntryLite.Metadata;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/** Schema used for standard messages. */
-final class MessageSchema<T> implements Schema<T> {
-  private static final int INTS_PER_FIELD = 3;
-  private static final int OFFSET_BITS = 20;
-  private static final int OFFSET_MASK = 0XFFFFF;
-  private static final int FIELD_TYPE_MASK = 0x0FF00000;
-  private static final int REQUIRED_MASK = 0x10000000;
-  private static final int ENFORCE_UTF8_MASK = 0x20000000;
-  private static final int NO_PRESENCE_SENTINEL = -1 & OFFSET_MASK;
-  private static final int[] EMPTY_INT_ARRAY = new int[0];
-
-  /** An offset applied to the field type ID for scalar fields that are a member of a oneof. */
-  static final int ONEOF_TYPE_OFFSET = 51 /* FieldType.MAP + 1 */;
-
-  /**
-   * Keep a direct reference to the unsafe object so we don't need to go through the UnsafeUtil
-   * wrapper for every call.
-   */
-  private static final sun.misc.Unsafe UNSAFE = UnsafeUtil.getUnsafe();
-
-  /**
-   * Holds all information for accessing the message fields. The layout is as follows (field
-   * positions are relative to the offset of the start of the field in the buffer):
-   *
-   * <p>
-   *
-   * <pre>
-   * [ 0 -    3] unused
-   * [ 4 -   31] field number
-   * [32 -   33] unused
-   * [34 -   34] whether UTF-8 enforcement should be applied to a string field.
-   * [35 -   35] whether the field is required
-   * [36 -   43] field type / for oneof: field type + {@link #ONEOF_TYPE_OFFSET}
-   * [44 -   63] field offset / oneof value field offset
-   * [64 -   69] unused
-   * [70 -   75] field presence mask shift (unused for oneof/repeated fields)
-   * [76 -   95] presence field offset / oneof case field offset / cached size field offset
-   * </pre>
-   *
-   * Note that presence field offset can only use 20 bits - 1. All bits set to 1 is the sentinel
-   * value for non-presence. This is not validated at runtime, we simply assume message layouts
-   * will not exceed 1MB (assuming ~10 bytes per field, that implies 100k fields which should hit
-   * other javac limits first).
-   */
-  private final int[] buffer;
-
-  /**
-   * Holds object references for fields. For each field entry in {@code buffer}, there are two
-   * corresponding entries in this array. The content is different from different field types:
-   *
-   * <pre>
-   *   Map fields:
-   *     objects[pos] = map default entry instance
-   *     objects[pos + 1] = EnumVerifier if map value is enum, or message class reference if map
-   *                        value is message.
-   *   Message fields:
-   *     objects[pos] = null or cached message schema
-   *     objects[pos + 1] = message class reference
-   *   Enum fields:
-   *     objects[pos] = null
-   *     objects[pos + 1] = EnumVerifier
-   * </pre>
-   */
-  private final Object[] objects;
-
-  private final int minFieldNumber;
-  private final int maxFieldNumber;
-
-  private final MessageLite defaultInstance;
-  private final boolean hasExtensions;
-  private final boolean lite;
-  private final boolean proto3;
-  // TODO(xiaofeng): Make both full-runtime and lite-runtime support cached field size.
-  private final boolean useCachedSizeField;
-
-  /** Represents [checkInitialized positions, map field positions, repeated field offsets]. */
-  private final int[] intArray;
-
-  /**
-   * Values at indices 0 -> checkInitializedCount in intArray are positions to check for
-   * initialization.
-   */
-  private final int checkInitializedCount;
-
-  /**
-   * Values at indices checkInitializedCount -> repeatedFieldOffsetStart are map positions.
-   * Everything after that are repeated field offsets.
-   */
-  private final int repeatedFieldOffsetStart;
-
-  private final NewInstanceSchema newInstanceSchema;
-  private final ListFieldSchema listFieldSchema;
-  private final UnknownFieldSchema<?, ?> unknownFieldSchema;
-  private final ExtensionSchema<?> extensionSchema;
-  private final MapFieldSchema mapFieldSchema;
-
-  private MessageSchema(
-      int[] buffer,
-      Object[] objects,
-      int minFieldNumber,
-      int maxFieldNumber,
-      MessageLite defaultInstance,
-      boolean proto3,
-      boolean useCachedSizeField,
-      int[] intArray,
-      int checkInitialized,
-      int mapFieldPositions,
-      NewInstanceSchema newInstanceSchema,
-      ListFieldSchema listFieldSchema,
-      UnknownFieldSchema<?, ?> unknownFieldSchema,
-      ExtensionSchema<?> extensionSchema,
-      MapFieldSchema mapFieldSchema) {
-    this.buffer = buffer;
-    this.objects = objects;
-    this.minFieldNumber = minFieldNumber;
-    this.maxFieldNumber = maxFieldNumber;
-
-    this.lite = defaultInstance instanceof GeneratedMessageLite;
-    this.proto3 = proto3;
-    this.hasExtensions = extensionSchema != null && extensionSchema.hasExtensions(defaultInstance);
-    this.useCachedSizeField = useCachedSizeField;
-
-    this.intArray = intArray;
-    this.checkInitializedCount = checkInitialized;
-    this.repeatedFieldOffsetStart = mapFieldPositions;
-
-    this.newInstanceSchema = newInstanceSchema;
-    this.listFieldSchema = listFieldSchema;
-    this.unknownFieldSchema = unknownFieldSchema;
-    this.extensionSchema = extensionSchema;
-    this.defaultInstance = defaultInstance;
-    this.mapFieldSchema = mapFieldSchema;
-  }
-
-  static <T> MessageSchema<T> newSchema(
-      Class<T> messageClass,
-      MessageInfo messageInfo,
-      NewInstanceSchema newInstanceSchema,
-      ListFieldSchema listFieldSchema,
-      UnknownFieldSchema<?, ?> unknownFieldSchema,
-      ExtensionSchema<?> extensionSchema,
-      MapFieldSchema mapFieldSchema) {
-    if (messageInfo instanceof RawMessageInfo) {
-      return newSchemaForRawMessageInfo(
-          (RawMessageInfo) messageInfo,
-          newInstanceSchema,
-          listFieldSchema,
-          unknownFieldSchema,
-          extensionSchema,
-          mapFieldSchema);
-
-    } else {
-      return newSchemaForMessageInfo(
-          (StructuralMessageInfo) messageInfo,
-          newInstanceSchema,
-          listFieldSchema,
-          unknownFieldSchema,
-          extensionSchema,
-          mapFieldSchema);
-    }
-  }
-
-  static <T> MessageSchema<T> newSchemaForRawMessageInfo(
-      RawMessageInfo messageInfo,
-      NewInstanceSchema newInstanceSchema,
-      ListFieldSchema listFieldSchema,
-      UnknownFieldSchema<?, ?> unknownFieldSchema,
-      ExtensionSchema<?> extensionSchema,
-      MapFieldSchema mapFieldSchema) {
-    final boolean isProto3 = messageInfo.getSyntax() == ProtoSyntax.PROTO3;
-
-    String info = messageInfo.getStringInfo();
-    final int length = info.length();
-    int i = 0;
-
-    int next = info.charAt(i++);
-    if (next >= 0xD800) {
-      int result = next & 0x1FFF;
-      int shift = 13;
-      while ((next = info.charAt(i++)) >= 0xD800) {
-        result |= (next & 0x1FFF) << shift;
-        shift += 13;
-      }
-      next = result | (next << shift);
-    }
-    final int unusedFlags = next;
-
-    next = info.charAt(i++);
-    if (next >= 0xD800) {
-      int result = next & 0x1FFF;
-      int shift = 13;
-      while ((next = info.charAt(i++)) >= 0xD800) {
-        result |= (next & 0x1FFF) << shift;
-        shift += 13;
-      }
-      next = result | (next << shift);
-    }
-    final int fieldCount = next;
-
-    final int oneofCount;
-    final int hasBitsCount;
-    final int minFieldNumber;
-    final int maxFieldNumber;
-    final int numEntries;
-    final int mapFieldCount;
-    final int repeatedFieldCount;
-    final int checkInitialized;
-    final int[] intArray;
-    int objectsPosition;
-    if (fieldCount == 0) {
-      oneofCount = 0;
-      hasBitsCount = 0;
-      minFieldNumber = 0;
-      maxFieldNumber = 0;
-      numEntries = 0;
-      mapFieldCount = 0;
-      repeatedFieldCount = 0;
-      checkInitialized = 0;
-      intArray = EMPTY_INT_ARRAY;
-      objectsPosition = 0;
-    } else {
-      next = info.charAt(i++);
-      if (next >= 0xD800) {
-        int result = next & 0x1FFF;
-        int shift = 13;
-        while ((next = info.charAt(i++)) >= 0xD800) {
-          result |= (next & 0x1FFF) << shift;
-          shift += 13;
-        }
-        next = result | (next << shift);
-      }
-      oneofCount = next;
-
-      next = info.charAt(i++);
-      if (next >= 0xD800) {
-        int result = next & 0x1FFF;
-        int shift = 13;
-        while ((next = info.charAt(i++)) >= 0xD800) {
-          result |= (next & 0x1FFF) << shift;
-          shift += 13;
-        }
-        next = result | (next << shift);
-      }
-      hasBitsCount = next;
-
-      next = info.charAt(i++);
-      if (next >= 0xD800) {
-        int result = next & 0x1FFF;
-        int shift = 13;
-        while ((next = info.charAt(i++)) >= 0xD800) {
-          result |= (next & 0x1FFF) << shift;
-          shift += 13;
-        }
-        next = result | (next << shift);
-      }
-      minFieldNumber = next;
-
-      next = info.charAt(i++);
-      if (next >= 0xD800) {
-        int result = next & 0x1FFF;
-        int shift = 13;
-        while ((next = info.charAt(i++)) >= 0xD800) {
-          result |= (next & 0x1FFF) << shift;
-          shift += 13;
-        }
-        next = result | (next << shift);
-      }
-      maxFieldNumber = next;
-
-      next = info.charAt(i++);
-      if (next >= 0xD800) {
-        int result = next & 0x1FFF;
-        int shift = 13;
-        while ((next = info.charAt(i++)) >= 0xD800) {
-          result |= (next & 0x1FFF) << shift;
-          shift += 13;
-        }
-        next = result | (next << shift);
-      }
-      numEntries = next;
-
-      next = info.charAt(i++);
-      if (next >= 0xD800) {
-        int result = next & 0x1FFF;
-        int shift = 13;
-        while ((next = info.charAt(i++)) >= 0xD800) {
-          result |= (next & 0x1FFF) << shift;
-          shift += 13;
-        }
-        next = result | (next << shift);
-      }
-      mapFieldCount = next;
-
-      next = info.charAt(i++);
-      if (next >= 0xD800) {
-        int result = next & 0x1FFF;
-        int shift = 13;
-        while ((next = info.charAt(i++)) >= 0xD800) {
-          result |= (next & 0x1FFF) << shift;
-          shift += 13;
-        }
-        next = result | (next << shift);
-      }
-      repeatedFieldCount = next;
-
-      next = info.charAt(i++);
-      if (next >= 0xD800) {
-        int result = next & 0x1FFF;
-        int shift = 13;
-        while ((next = info.charAt(i++)) >= 0xD800) {
-          result |= (next & 0x1FFF) << shift;
-          shift += 13;
-        }
-        next = result | (next << shift);
-      }
-      checkInitialized = next;
-      intArray = new int[checkInitialized + mapFieldCount + repeatedFieldCount];
-      // Field objects are after a list of (oneof, oneofCase) pairs  + a list of hasbits fields.
-      objectsPosition = oneofCount * 2 + hasBitsCount;
-    }
-
-    final sun.misc.Unsafe unsafe = UNSAFE;
-    final Object[] messageInfoObjects = messageInfo.getObjects();
-    int checkInitializedPosition = 0;
-    final Class<?> messageClass = messageInfo.getDefaultInstance().getClass();
-    int[] buffer = new int[numEntries * INTS_PER_FIELD];
-    Object[] objects = new Object[numEntries * 2];
-
-    int mapFieldIndex = checkInitialized;
-    int repeatedFieldIndex = checkInitialized + mapFieldCount;
-
-    int bufferIndex = 0;
-    while (i < length) {
-      final int fieldNumber;
-      final int fieldTypeWithExtraBits;
-      final int fieldType;
-
-      next = info.charAt(i++);
-      if (next >= 0xD800) {
-        int result = next & 0x1FFF;
-        int shift = 13;
-        while ((next = info.charAt(i++)) >= 0xD800) {
-          result |= (next & 0x1FFF) << shift;
-          shift += 13;
-        }
-        next = result | (next << shift);
-      }
-      fieldNumber = next;
-
-      next = info.charAt(i++);
-      if (next >= 0xD800) {
-        int result = next & 0x1FFF;
-        int shift = 13;
-        while ((next = info.charAt(i++)) >= 0xD800) {
-          result |= (next & 0x1FFF) << shift;
-          shift += 13;
-        }
-        next = result | (next << shift);
-      }
-      fieldTypeWithExtraBits = next;
-      fieldType = fieldTypeWithExtraBits & 0xFF;
-
-      if ((fieldTypeWithExtraBits & 0x400) != 0) {
-        intArray[checkInitializedPosition++] = bufferIndex;
-      }
-
-      final int fieldOffset;
-      final int presenceMaskShift;
-      final int presenceFieldOffset;
-
-      // Oneof
-      if (fieldType >= ONEOF_TYPE_OFFSET) {
-        next = info.charAt(i++);
-        if (next >= 0xD800) {
-          int result = next & 0x1FFF;
-          int shift = 13;
-          while ((next = info.charAt(i++)) >= 0xD800) {
-            result |= (next & 0x1FFF) << shift;
-            shift += 13;
-          }
-          next = result | (next << shift);
-        }
-        int oneofIndex = next;
-
-        final int oneofFieldType = fieldType - ONEOF_TYPE_OFFSET;
-        if (oneofFieldType == 9 /* FieldType.MESSAGE */
-            || oneofFieldType == 17 /* FieldType.GROUP */) {
-          objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageInfoObjects[objectsPosition++];
-        } else if (oneofFieldType == 12 /* FieldType.ENUM */) {
-          if (!isProto3) {
-            objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageInfoObjects[objectsPosition++];
-          }
-        }
-
-        final java.lang.reflect.Field oneofField;
-        int index = oneofIndex * 2;
-        Object o = messageInfoObjects[index];
-        if (o instanceof java.lang.reflect.Field) {
-          oneofField = (java.lang.reflect.Field) o;
-        } else {
-          oneofField = reflectField(messageClass, (String) o);
-          // Memoize java.lang.reflect.Field instances for oneof/hasbits fields, since they're
-          // potentially used for many Protobuf fields.  Since there's a 1-1 mapping from the
-          // Protobuf field to the Java Field for non-oneofs, there's no benefit for memoizing
-          // those.
-          messageInfoObjects[index] = oneofField;
-        }
-
-        fieldOffset = (int) unsafe.objectFieldOffset(oneofField);
-
-        final java.lang.reflect.Field oneofCaseField;
-        index++;
-        o = messageInfoObjects[index];
-        if (o instanceof java.lang.reflect.Field) {
-          oneofCaseField = (java.lang.reflect.Field) o;
-        } else {
-          oneofCaseField = reflectField(messageClass, (String) o);
-          messageInfoObjects[index] = oneofCaseField;
-        }
-
-        presenceFieldOffset = (int) unsafe.objectFieldOffset(oneofCaseField);
-        presenceMaskShift = 0;
-      } else {
-        Field field = reflectField(messageClass, (String) messageInfoObjects[objectsPosition++]);
-        if (fieldType == 9 /* FieldType.MESSAGE */ || fieldType == 17 /* FieldType.GROUP */) {
-          objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = field.getType();
-        } else if (fieldType == 27 /* FieldType.MESSAGE_LIST */
-            || fieldType == 49 /* FieldType.GROUP_LIST */) {
-          objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageInfoObjects[objectsPosition++];
-        } else if (fieldType == 12 /* FieldType.ENUM */
-            || fieldType == 30 /* FieldType.ENUM_LIST */
-            || fieldType == 44 /* FieldType.ENUM_LIST_PACKED */) {
-          if (!isProto3) {
-            objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageInfoObjects[objectsPosition++];
-          }
-        } else if (fieldType == 50 /* FieldType.MAP */) {
-          intArray[mapFieldIndex++] = bufferIndex;
-          objects[bufferIndex / INTS_PER_FIELD * 2] = messageInfoObjects[objectsPosition++];
-          if ((fieldTypeWithExtraBits & 0x800) != 0) {
-            objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageInfoObjects[objectsPosition++];
-          }
-        }
-
-        fieldOffset = (int) unsafe.objectFieldOffset(field);
-        boolean hasHasBit = (fieldTypeWithExtraBits & 0x1000) == 0x1000;
-        if (hasHasBit && fieldType <= 17 /* FieldType.GROUP */) {
-          next = info.charAt(i++);
-          if (next >= 0xD800) {
-            int result = next & 0x1FFF;
-            int shift = 13;
-            while ((next = info.charAt(i++)) >= 0xD800) {
-              result |= (next & 0x1FFF) << shift;
-              shift += 13;
-            }
-            next = result | (next << shift);
-          }
-          int hasBitsIndex = next;
-
-          final java.lang.reflect.Field hasBitsField;
-          int index = oneofCount * 2 + hasBitsIndex / 32;
-          Object o = messageInfoObjects[index];
-          if (o instanceof java.lang.reflect.Field) {
-            hasBitsField = (java.lang.reflect.Field) o;
-          } else {
-            hasBitsField = reflectField(messageClass, (String) o);
-            messageInfoObjects[index] = hasBitsField;
-          }
-
-          presenceFieldOffset = (int) unsafe.objectFieldOffset(hasBitsField);
-          presenceMaskShift = hasBitsIndex % 32;
-        } else {
-          presenceFieldOffset = NO_PRESENCE_SENTINEL;
-          presenceMaskShift = 0;
-        }
-
-        if (fieldType >= 18 && fieldType <= 49) {
-          // Field types of repeated fields are in a consecutive range from 18 (DOUBLE_LIST) to
-          // 49 (GROUP_LIST).
-          intArray[repeatedFieldIndex++] = fieldOffset;
-        }
-      }
-
-      buffer[bufferIndex++] = fieldNumber;
-      buffer[bufferIndex++] =
-          ((fieldTypeWithExtraBits & 0x200) != 0 ? ENFORCE_UTF8_MASK : 0)
-              | ((fieldTypeWithExtraBits & 0x100) != 0 ? REQUIRED_MASK : 0)
-              | (fieldType << OFFSET_BITS)
-              | fieldOffset;
-      buffer[bufferIndex++] = (presenceMaskShift << OFFSET_BITS) | presenceFieldOffset;
-    }
-
-    return new MessageSchema<T>(
-        buffer,
-        objects,
-        minFieldNumber,
-        maxFieldNumber,
-        messageInfo.getDefaultInstance(),
-        isProto3,
-        /* useCachedSizeField= */ false,
-        intArray,
-        checkInitialized,
-        checkInitialized + mapFieldCount,
-        newInstanceSchema,
-        listFieldSchema,
-        unknownFieldSchema,
-        extensionSchema,
-        mapFieldSchema);
-  }
-
-  private static java.lang.reflect.Field reflectField(Class<?> messageClass, String fieldName) {
-    try {
-      return messageClass.getDeclaredField(fieldName);
-    } catch (NoSuchFieldException e) {
-      // Some Samsung devices lie about what fields are present via the getDeclaredField API so
-      // we do the for loop properly that they seem to have messed up...
-      java.lang.reflect.Field[] fields = messageClass.getDeclaredFields();
-      for (java.lang.reflect.Field field : fields) {
-        if (fieldName.equals(field.getName())) {
-          return field;
-        }
-      }
-
-      // If we make it here, the runtime still lies about what we know to be true at compile
-      // time. We throw to alert server monitoring for further remediation.
-      throw new RuntimeException(
-          "Field "
-              + fieldName
-              + " for "
-              + messageClass.getName()
-              + " not found. Known fields are "
-              + Arrays.toString(fields));
-    }
-  }
-
-  static <T> MessageSchema<T> newSchemaForMessageInfo(
-      StructuralMessageInfo messageInfo,
-      NewInstanceSchema newInstanceSchema,
-      ListFieldSchema listFieldSchema,
-      UnknownFieldSchema<?, ?> unknownFieldSchema,
-      ExtensionSchema<?> extensionSchema,
-      MapFieldSchema mapFieldSchema) {
-    final boolean isProto3 = messageInfo.getSyntax() == ProtoSyntax.PROTO3;
-    FieldInfo[] fis = messageInfo.getFields();
-    final int minFieldNumber;
-    final int maxFieldNumber;
-    if (fis.length == 0) {
-      minFieldNumber = 0;
-      maxFieldNumber = 0;
-    } else {
-      minFieldNumber = fis[0].getFieldNumber();
-      maxFieldNumber = fis[fis.length - 1].getFieldNumber();
-    }
-
-    final int numEntries = fis.length;
-
-    int[] buffer = new int[numEntries * INTS_PER_FIELD];
-    Object[] objects = new Object[numEntries * 2];
-
-    int mapFieldCount = 0;
-    int repeatedFieldCount = 0;
-    for (FieldInfo fi : fis) {
-      if (fi.getType() == FieldType.MAP) {
-        mapFieldCount++;
-      } else if (fi.getType().id() >= 18 && fi.getType().id() <= 49) {
-        // Field types of repeated fields are in a consecutive range from 18 (DOUBLE_LIST) to
-        // 49 (GROUP_LIST).
-        repeatedFieldCount++;
-      }
-    }
-    int[] mapFieldPositions = mapFieldCount > 0 ? new int[mapFieldCount] : null;
-    int[] repeatedFieldOffsets = repeatedFieldCount > 0 ? new int[repeatedFieldCount] : null;
-    mapFieldCount = 0;
-    repeatedFieldCount = 0;
-
-    int[] checkInitialized = messageInfo.getCheckInitialized();
-    if (checkInitialized == null) {
-      checkInitialized = EMPTY_INT_ARRAY;
-    }
-    int checkInitializedIndex = 0;
-    // Fill in the manifest data from the descriptors.
-    int fieldIndex = 0;
-    for (int bufferIndex = 0; fieldIndex < fis.length; bufferIndex += INTS_PER_FIELD) {
-      final FieldInfo fi = fis[fieldIndex];
-      final int fieldNumber = fi.getFieldNumber();
-
-      // We found the entry for the next field. Store the entry in the manifest for
-      // this field and increment the field index.
-      storeFieldData(fi, buffer, bufferIndex, objects);
-
-      // Convert field number to index
-      if (checkInitializedIndex < checkInitialized.length
-          && checkInitialized[checkInitializedIndex] == fieldNumber) {
-        checkInitialized[checkInitializedIndex++] = bufferIndex;
-      }
-
-      if (fi.getType() == FieldType.MAP) {
-        mapFieldPositions[mapFieldCount++] = bufferIndex;
-      } else if (fi.getType().id() >= 18 && fi.getType().id() <= 49) {
-        // Field types of repeated fields are in a consecutive range from 18 (DOUBLE_LIST) to
-        // 49 (GROUP_LIST).
-        repeatedFieldOffsets[repeatedFieldCount++] =
-            (int) UnsafeUtil.objectFieldOffset(fi.getField());
-      }
-
-      fieldIndex++;
-    }
-
-    if (mapFieldPositions == null) {
-      mapFieldPositions = EMPTY_INT_ARRAY;
-    }
-    if (repeatedFieldOffsets == null) {
-      repeatedFieldOffsets = EMPTY_INT_ARRAY;
-    }
-    int[] combined =
-        new int[checkInitialized.length + mapFieldPositions.length + repeatedFieldOffsets.length];
-    System.arraycopy(checkInitialized, 0, combined, 0, checkInitialized.length);
-    System.arraycopy(
-        mapFieldPositions, 0, combined, checkInitialized.length, mapFieldPositions.length);
-    System.arraycopy(
-        repeatedFieldOffsets,
-        0,
-        combined,
-        checkInitialized.length + mapFieldPositions.length,
-        repeatedFieldOffsets.length);
-
-    return new MessageSchema<T>(
-        buffer,
-        objects,
-        minFieldNumber,
-        maxFieldNumber,
-        messageInfo.getDefaultInstance(),
-        isProto3,
-        /* useCachedSizeField= */ true,
-        combined,
-        checkInitialized.length,
-        checkInitialized.length + mapFieldPositions.length,
-        newInstanceSchema,
-        listFieldSchema,
-        unknownFieldSchema,
-        extensionSchema,
-        mapFieldSchema);
-  }
-
-  private static void storeFieldData(
-      FieldInfo fi, int[] buffer, int bufferIndex, Object[] objects) {
-    final int fieldOffset;
-    final int typeId;
-    final int presenceMaskShift;
-    final int presenceFieldOffset;
-
-    OneofInfo oneof = fi.getOneof();
-    if (oneof != null) {
-      typeId = fi.getType().id() + ONEOF_TYPE_OFFSET;
-      fieldOffset = (int) UnsafeUtil.objectFieldOffset(oneof.getValueField());
-      presenceFieldOffset = (int) UnsafeUtil.objectFieldOffset(oneof.getCaseField());
-      presenceMaskShift = 0;
-    } else {
-      FieldType type = fi.getType();
-      fieldOffset = (int) UnsafeUtil.objectFieldOffset(fi.getField());
-      typeId = type.id();
-      if (!type.isList() && !type.isMap()) {
-        Field presenceField = fi.getPresenceField();
-        if (presenceField == null) {
-          presenceFieldOffset = NO_PRESENCE_SENTINEL;
-        } else {
-          presenceFieldOffset = (int) UnsafeUtil.objectFieldOffset(presenceField);
-        }
-        presenceMaskShift = Integer.numberOfTrailingZeros(fi.getPresenceMask());
-      } else {
-        if (fi.getCachedSizeField() == null) {
-          presenceFieldOffset = 0;
-          presenceMaskShift = 0;
-        } else {
-          presenceFieldOffset = (int) UnsafeUtil.objectFieldOffset(fi.getCachedSizeField());
-          presenceMaskShift = 0;
-        }
-      }
-    }
-
-    buffer[bufferIndex] = fi.getFieldNumber();
-    buffer[bufferIndex + 1] =
-        (fi.isEnforceUtf8() ? ENFORCE_UTF8_MASK : 0)
-            | (fi.isRequired() ? REQUIRED_MASK : 0)
-            | (typeId << OFFSET_BITS)
-            | fieldOffset;
-    buffer[bufferIndex + 2] = (presenceMaskShift << OFFSET_BITS) | presenceFieldOffset;
-
-    Object messageFieldClass = fi.getMessageFieldClass();
-    if (fi.getMapDefaultEntry() != null) {
-      objects[bufferIndex / INTS_PER_FIELD * 2] = fi.getMapDefaultEntry();
-      if (messageFieldClass != null) {
-        objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageFieldClass;
-      } else if (fi.getEnumVerifier() != null) {
-        objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = fi.getEnumVerifier();
-      }
-    } else {
-      if (messageFieldClass != null) {
-        objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageFieldClass;
-      } else if (fi.getEnumVerifier() != null) {
-        objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = fi.getEnumVerifier();
-      }
-    }
-  }
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public T newInstance() {
-    return (T) newInstanceSchema.newInstance(defaultInstance);
-  }
-
-  @Override
-  public boolean equals(T message, T other) {
-    final int bufferLength = buffer.length;
-    for (int pos = 0; pos < bufferLength; pos += INTS_PER_FIELD) {
-      if (!equals(message, other, pos)) {
-        return false;
-      }
-    }
-
-    Object messageUnknown = unknownFieldSchema.getFromMessage(message);
-    Object otherUnknown = unknownFieldSchema.getFromMessage(other);
-    if (!messageUnknown.equals(otherUnknown)) {
-      return false;
-    }
-
-    if (hasExtensions) {
-      FieldSet<?> messageExtensions = extensionSchema.getExtensions(message);
-      FieldSet<?> otherExtensions = extensionSchema.getExtensions(other);
-      return messageExtensions.equals(otherExtensions);
-    }
-    return true;
-  }
-
-  private boolean equals(T message, T other, int pos) {
-    final int typeAndOffset = typeAndOffsetAt(pos);
-    final long offset = offset(typeAndOffset);
-
-    switch (type(typeAndOffset)) {
-      case 0: // DOUBLE:
-        return arePresentForEquals(message, other, pos)
-            && Double.doubleToLongBits(UnsafeUtil.getDouble(message, offset))
-                == Double.doubleToLongBits(UnsafeUtil.getDouble(other, offset));
-      case 1: // FLOAT:
-        return arePresentForEquals(message, other, pos)
-            && Float.floatToIntBits(UnsafeUtil.getFloat(message, offset))
-                == Float.floatToIntBits(UnsafeUtil.getFloat(other, offset));
-      case 2: // INT64:
-        return arePresentForEquals(message, other, pos)
-            && UnsafeUtil.getLong(message, offset) == UnsafeUtil.getLong(other, offset);
-      case 3: // UINT64:
-        return arePresentForEquals(message, other, pos)
-            && UnsafeUtil.getLong(message, offset) == UnsafeUtil.getLong(other, offset);
-      case 4: // INT32:
-        return arePresentForEquals(message, other, pos)
-            && UnsafeUtil.getInt(message, offset) == UnsafeUtil.getInt(other, offset);
-      case 5: // FIXED64:
-        return arePresentForEquals(message, other, pos)
-            && UnsafeUtil.getLong(message, offset) == UnsafeUtil.getLong(other, offset);
-      case 6: // FIXED32:
-        return arePresentForEquals(message, other, pos)
-            && UnsafeUtil.getInt(message, offset) == UnsafeUtil.getInt(other, offset);
-      case 7: // BOOL:
-        return arePresentForEquals(message, other, pos)
-            && UnsafeUtil.getBoolean(message, offset) == UnsafeUtil.getBoolean(other, offset);
-      case 8: // STRING:
-        return arePresentForEquals(message, other, pos)
-            && SchemaUtil.safeEquals(
-                UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset));
-      case 9: // MESSAGE:
-        return arePresentForEquals(message, other, pos)
-            && SchemaUtil.safeEquals(
-                UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset));
-      case 10: // BYTES:
-        return arePresentForEquals(message, other, pos)
-            && SchemaUtil.safeEquals(
-                UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset));
-      case 11: // UINT32:
-        return arePresentForEquals(message, other, pos)
-            && UnsafeUtil.getInt(message, offset) == UnsafeUtil.getInt(other, offset);
-      case 12: // ENUM:
-        return arePresentForEquals(message, other, pos)
-            && UnsafeUtil.getInt(message, offset) == UnsafeUtil.getInt(other, offset);
-      case 13: // SFIXED32:
-        return arePresentForEquals(message, other, pos)
-            && UnsafeUtil.getInt(message, offset) == UnsafeUtil.getInt(other, offset);
-      case 14: // SFIXED64:
-        return arePresentForEquals(message, other, pos)
-            && UnsafeUtil.getLong(message, offset) == UnsafeUtil.getLong(other, offset);
-      case 15: // SINT32:
-        return arePresentForEquals(message, other, pos)
-            && UnsafeUtil.getInt(message, offset) == UnsafeUtil.getInt(other, offset);
-      case 16: // SINT64:
-        return arePresentForEquals(message, other, pos)
-            && UnsafeUtil.getLong(message, offset) == UnsafeUtil.getLong(other, offset);
-      case 17: // GROUP:
-        return arePresentForEquals(message, other, pos)
-            && SchemaUtil.safeEquals(
-                UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset));
-
-      case 18: // DOUBLE_LIST:
-      case 19: // FLOAT_LIST:
-      case 20: // INT64_LIST:
-      case 21: // UINT64_LIST:
-      case 22: // INT32_LIST:
-      case 23: // FIXED64_LIST:
-      case 24: // FIXED32_LIST:
-      case 25: // BOOL_LIST:
-      case 26: // STRING_LIST:
-      case 27: // MESSAGE_LIST:
-      case 28: // BYTES_LIST:
-      case 29: // UINT32_LIST:
-      case 30: // ENUM_LIST:
-      case 31: // SFIXED32_LIST:
-      case 32: // SFIXED64_LIST:
-      case 33: // SINT32_LIST:
-      case 34: // SINT64_LIST:
-      case 35: // DOUBLE_LIST_PACKED:
-      case 36: // FLOAT_LIST_PACKED:
-      case 37: // INT64_LIST_PACKED:
-      case 38: // UINT64_LIST_PACKED:
-      case 39: // INT32_LIST_PACKED:
-      case 40: // FIXED64_LIST_PACKED:
-      case 41: // FIXED32_LIST_PACKED:
-      case 42: // BOOL_LIST_PACKED:
-      case 43: // UINT32_LIST_PACKED:
-      case 44: // ENUM_LIST_PACKED:
-      case 45: // SFIXED32_LIST_PACKED:
-      case 46: // SFIXED64_LIST_PACKED:
-      case 47: // SINT32_LIST_PACKED:
-      case 48: // SINT64_LIST_PACKED:
-      case 49: // GROUP_LIST:
-        return SchemaUtil.safeEquals(
-            UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset));
-      case 50: // MAP:
-        return SchemaUtil.safeEquals(
-            UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset));
-      case 51: // ONEOF_DOUBLE:
-      case 52: // ONEOF_FLOAT:
-      case 53: // ONEOF_INT64:
-      case 54: // ONEOF_UINT64:
-      case 55: // ONEOF_INT32:
-      case 56: // ONEOF_FIXED64:
-      case 57: // ONEOF_FIXED32:
-      case 58: // ONEOF_BOOL:
-      case 59: // ONEOF_STRING:
-      case 60: // ONEOF_MESSAGE:
-      case 61: // ONEOF_BYTES:
-      case 62: // ONEOF_UINT32:
-      case 63: // ONEOF_ENUM:
-      case 64: // ONEOF_SFIXED32:
-      case 65: // ONEOF_SFIXED64:
-      case 66: // ONEOF_SINT32:
-      case 67: // ONEOF_SINT64:
-      case 68: // ONEOF_GROUP:
-        return isOneofCaseEqual(message, other, pos)
-            && SchemaUtil.safeEquals(
-                UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset));
-      default:
-        // Assume it's an empty entry - just go to the next entry.
-        return true;
-    }
-  }
-
-  @Override
-  public int hashCode(T message) {
-    int hashCode = 0;
-    final int bufferLength = buffer.length;
-    for (int pos = 0; pos < bufferLength; pos += INTS_PER_FIELD) {
-      final int typeAndOffset = typeAndOffsetAt(pos);
-      final int entryNumber = numberAt(pos);
-
-      final long offset = offset(typeAndOffset);
-
-      switch (type(typeAndOffset)) {
-        case 0: // DOUBLE:
-          hashCode =
-              (hashCode * 53)
-                  + Internal.hashLong(
-                      Double.doubleToLongBits(UnsafeUtil.getDouble(message, offset)));
-          break;
-        case 1: // FLOAT:
-          hashCode = (hashCode * 53) + Float.floatToIntBits(UnsafeUtil.getFloat(message, offset));
-          break;
-        case 2: // INT64:
-          hashCode = (hashCode * 53) + Internal.hashLong(UnsafeUtil.getLong(message, offset));
-          break;
-        case 3: // UINT64:
-          hashCode = (hashCode * 53) + Internal.hashLong(UnsafeUtil.getLong(message, offset));
-          break;
-        case 4: // INT32:
-          hashCode = (hashCode * 53) + (UnsafeUtil.getInt(message, offset));
-          break;
-        case 5: // FIXED64:
-          hashCode = (hashCode * 53) + Internal.hashLong(UnsafeUtil.getLong(message, offset));
-          break;
-        case 6: // FIXED32:
-          hashCode = (hashCode * 53) + (UnsafeUtil.getInt(message, offset));
-          break;
-        case 7: // BOOL:
-          hashCode = (hashCode * 53) + Internal.hashBoolean(UnsafeUtil.getBoolean(message, offset));
-          break;
-        case 8: // STRING:
-          hashCode = (hashCode * 53) + ((String) UnsafeUtil.getObject(message, offset)).hashCode();
-          break;
-        case 9: // MESSAGE:
-          {
-            int protoHash = 37;
-            Object submessage = UnsafeUtil.getObject(message, offset);
-            if (submessage != null) {
-              protoHash = submessage.hashCode();
-            }
-            hashCode = (53 * hashCode) + protoHash;
-            break;
-          }
-        case 10: // BYTES:
-          hashCode = (hashCode * 53) + UnsafeUtil.getObject(message, offset).hashCode();
-          break;
-        case 11: // UINT32:
-          hashCode = (hashCode * 53) + (UnsafeUtil.getInt(message, offset));
-          break;
-        case 12: // ENUM:
-          hashCode = (hashCode * 53) + (UnsafeUtil.getInt(message, offset));
-          break;
-        case 13: // SFIXED32:
-          hashCode = (hashCode * 53) + (UnsafeUtil.getInt(message, offset));
-          break;
-        case 14: // SFIXED64:
-          hashCode = (hashCode * 53) + Internal.hashLong(UnsafeUtil.getLong(message, offset));
-          break;
-        case 15: // SINT32:
-          hashCode = (hashCode * 53) + (UnsafeUtil.getInt(message, offset));
-          break;
-        case 16: // SINT64:
-          hashCode = (hashCode * 53) + Internal.hashLong(UnsafeUtil.getLong(message, offset));
-          break;
-
-        case 17: // GROUP:
-          {
-            int protoHash = 37;
-            Object submessage = UnsafeUtil.getObject(message, offset);
-            if (submessage != null) {
-              protoHash = submessage.hashCode();
-            }
-            hashCode = (53 * hashCode) + protoHash;
-            break;
-          }
-        case 18: // DOUBLE_LIST:
-        case 19: // FLOAT_LIST:
-        case 20: // INT64_LIST:
-        case 21: // UINT64_LIST:
-        case 22: // INT32_LIST:
-        case 23: // FIXED64_LIST:
-        case 24: // FIXED32_LIST:
-        case 25: // BOOL_LIST:
-        case 26: // STRING_LIST:
-        case 27: // MESSAGE_LIST:
-        case 28: // BYTES_LIST:
-        case 29: // UINT32_LIST:
-        case 30: // ENUM_LIST:
-        case 31: // SFIXED32_LIST:
-        case 32: // SFIXED64_LIST:
-        case 33: // SINT32_LIST:
-        case 34: // SINT64_LIST:
-        case 35: // DOUBLE_LIST_PACKED:
-        case 36: // FLOAT_LIST_PACKED:
-        case 37: // INT64_LIST_PACKED:
-        case 38: // UINT64_LIST_PACKED:
-        case 39: // INT32_LIST_PACKED:
-        case 40: // FIXED64_LIST_PACKED:
-        case 41: // FIXED32_LIST_PACKED:
-        case 42: // BOOL_LIST_PACKED:
-        case 43: // UINT32_LIST_PACKED:
-        case 44: // ENUM_LIST_PACKED:
-        case 45: // SFIXED32_LIST_PACKED:
-        case 46: // SFIXED64_LIST_PACKED:
-        case 47: // SINT32_LIST_PACKED:
-        case 48: // SINT64_LIST_PACKED:
-        case 49: // GROUP_LIST:
-          hashCode = (hashCode * 53) + UnsafeUtil.getObject(message, offset).hashCode();
-          break;
-        case 50: // MAP:
-          hashCode = (hashCode * 53) + UnsafeUtil.getObject(message, offset).hashCode();
-          break;
-        case 51: // ONEOF_DOUBLE:
-          if (isOneofPresent(message, entryNumber, pos)) {
-            hashCode =
-                (hashCode * 53)
-                    + Internal.hashLong(Double.doubleToLongBits(oneofDoubleAt(message, offset)));
-          }
-          break;
-        case 52: // ONEOF_FLOAT:
-          if (isOneofPresent(message, entryNumber, pos)) {
-            hashCode = (hashCode * 53) + Float.floatToIntBits(oneofFloatAt(message, offset));
-          }
-          break;
-        case 53: // ONEOF_INT64:
-          if (isOneofPresent(message, entryNumber, pos)) {
-            hashCode = (hashCode * 53) + Internal.hashLong(oneofLongAt(message, offset));
-          }
-          break;
-        case 54: // ONEOF_UINT64:
-          if (isOneofPresent(message, entryNumber, pos)) {
-            hashCode = (hashCode * 53) + Internal.hashLong(oneofLongAt(message, offset));
-          }
-          break;
-        case 55: // ONEOF_INT32:
-          if (isOneofPresent(message, entryNumber, pos)) {
-            hashCode = (hashCode * 53) + (oneofIntAt(message, offset));
-          }
-          break;
-        case 56: // ONEOF_FIXED64:
-          if (isOneofPresent(message, entryNumber, pos)) {
-            hashCode = (hashCode * 53) + Internal.hashLong(oneofLongAt(message, offset));
-          }
-          break;
-        case 57: // ONEOF_FIXED32:
-          if (isOneofPresent(message, entryNumber, pos)) {
-            hashCode = (hashCode * 53) + (oneofIntAt(message, offset));
-          }
-          break;
-        case 58: // ONEOF_BOOL:
-          if (isOneofPresent(message, entryNumber, pos)) {
-            hashCode = (hashCode * 53) + Internal.hashBoolean(oneofBooleanAt(message, offset));
-          }
-          break;
-        case 59: // ONEOF_STRING:
-          if (isOneofPresent(message, entryNumber, pos)) {
-            hashCode =
-                (hashCode * 53) + ((String) UnsafeUtil.getObject(message, offset)).hashCode();
-          }
-          break;
-        case 60: // ONEOF_MESSAGE:
-          if (isOneofPresent(message, entryNumber, pos)) {
-            Object submessage = UnsafeUtil.getObject(message, offset);
-            hashCode = (53 * hashCode) + submessage.hashCode();
-          }
-          break;
-        case 61: // ONEOF_BYTES:
-          if (isOneofPresent(message, entryNumber, pos)) {
-            hashCode = (hashCode * 53) + UnsafeUtil.getObject(message, offset).hashCode();
-          }
-          break;
-        case 62: // ONEOF_UINT32:
-          if (isOneofPresent(message, entryNumber, pos)) {
-            hashCode = (hashCode * 53) + (oneofIntAt(message, offset));
-          }
-          break;
-        case 63: // ONEOF_ENUM:
-          if (isOneofPresent(message, entryNumber, pos)) {
-            hashCode = (hashCode * 53) + (oneofIntAt(message, offset));
-          }
-          break;
-        case 64: // ONEOF_SFIXED32:
-          if (isOneofPresent(message, entryNumber, pos)) {
-            hashCode = (hashCode * 53) + (oneofIntAt(message, offset));
-          }
-          break;
-        case 65: // ONEOF_SFIXED64:
-          if (isOneofPresent(message, entryNumber, pos)) {
-            hashCode = (hashCode * 53) + Internal.hashLong(oneofLongAt(message, offset));
-          }
-          break;
-        case 66: // ONEOF_SINT32:
-          if (isOneofPresent(message, entryNumber, pos)) {
-            hashCode = (hashCode * 53) + (oneofIntAt(message, offset));
-          }
-          break;
-        case 67: // ONEOF_SINT64:
-          if (isOneofPresent(message, entryNumber, pos)) {
-            hashCode = (hashCode * 53) + Internal.hashLong(oneofLongAt(message, offset));
-          }
-          break;
-        case 68: // ONEOF_GROUP:
-          if (isOneofPresent(message, entryNumber, pos)) {
-            Object submessage = UnsafeUtil.getObject(message, offset);
-            hashCode = (53 * hashCode) + submessage.hashCode();
-          }
-          break;
-        default:
-          // Assume it's an empty entry - just go to the next entry.
-          break;
-      }
-    }
-
-    hashCode = (hashCode * 53) + unknownFieldSchema.getFromMessage(message).hashCode();
-
-    if (hasExtensions) {
-      hashCode = (hashCode * 53) + extensionSchema.getExtensions(message).hashCode();
-    }
-
-    return hashCode;
-  }
-
-  @Override
-  public void mergeFrom(T message, T other) {
-    if (other == null) {
-      throw new NullPointerException();
-    }
-    for (int i = 0; i < buffer.length; i += INTS_PER_FIELD) {
-      // A separate method allows for better JIT optimizations
-      mergeSingleField(message, other, i);
-    }
-
-    SchemaUtil.mergeUnknownFields(unknownFieldSchema, message, other);
-
-    if (hasExtensions) {
-      SchemaUtil.mergeExtensions(extensionSchema, message, other);
-    }
-  }
-
-  private void mergeSingleField(T message, T other, int pos) {
-    final int typeAndOffset = typeAndOffsetAt(pos);
-    final long offset = offset(typeAndOffset);
-    final int number = numberAt(pos);
-
-    switch (type(typeAndOffset)) {
-      case 0: // DOUBLE:
-        if (isFieldPresent(other, pos)) {
-          UnsafeUtil.putDouble(message, offset, UnsafeUtil.getDouble(other, offset));
-          setFieldPresent(message, pos);
-        }
-        break;
-      case 1: // FLOAT:
-        if (isFieldPresent(other, pos)) {
-          UnsafeUtil.putFloat(message, offset, UnsafeUtil.getFloat(other, offset));
-          setFieldPresent(message, pos);
-        }
-        break;
-      case 2: // INT64:
-        if (isFieldPresent(other, pos)) {
-          UnsafeUtil.putLong(message, offset, UnsafeUtil.getLong(other, offset));
-          setFieldPresent(message, pos);
-        }
-        break;
-      case 3: // UINT64:
-        if (isFieldPresent(other, pos)) {
-          UnsafeUtil.putLong(message, offset, UnsafeUtil.getLong(other, offset));
-          setFieldPresent(message, pos);
-        }
-        break;
-      case 4: // INT32:
-        if (isFieldPresent(other, pos)) {
-          UnsafeUtil.putInt(message, offset, UnsafeUtil.getInt(other, offset));
-          setFieldPresent(message, pos);
-        }
-        break;
-      case 5: // FIXED64:
-        if (isFieldPresent(other, pos)) {
-          UnsafeUtil.putLong(message, offset, UnsafeUtil.getLong(other, offset));
-          setFieldPresent(message, pos);
-        }
-        break;
-      case 6: // FIXED32:
-        if (isFieldPresent(other, pos)) {
-          UnsafeUtil.putInt(message, offset, UnsafeUtil.getInt(other, offset));
-          setFieldPresent(message, pos);
-        }
-        break;
-      case 7: // BOOL:
-        if (isFieldPresent(other, pos)) {
-          UnsafeUtil.putBoolean(message, offset, UnsafeUtil.getBoolean(other, offset));
-          setFieldPresent(message, pos);
-        }
-        break;
-      case 8: // STRING:
-        if (isFieldPresent(other, pos)) {
-          UnsafeUtil.putObject(message, offset, UnsafeUtil.getObject(other, offset));
-          setFieldPresent(message, pos);
-        }
-        break;
-      case 9: // MESSAGE:
-        mergeMessage(message, other, pos);
-        break;
-      case 10: // BYTES:
-        if (isFieldPresent(other, pos)) {
-          UnsafeUtil.putObject(message, offset, UnsafeUtil.getObject(other, offset));
-          setFieldPresent(message, pos);
-        }
-        break;
-      case 11: // UINT32:
-        if (isFieldPresent(other, pos)) {
-          UnsafeUtil.putInt(message, offset, UnsafeUtil.getInt(other, offset));
-          setFieldPresent(message, pos);
-        }
-        break;
-      case 12: // ENUM:
-        if (isFieldPresent(other, pos)) {
-          UnsafeUtil.putInt(message, offset, UnsafeUtil.getInt(other, offset));
-          setFieldPresent(message, pos);
-        }
-        break;
-      case 13: // SFIXED32:
-        if (isFieldPresent(other, pos)) {
-          UnsafeUtil.putInt(message, offset, UnsafeUtil.getInt(other, offset));
-          setFieldPresent(message, pos);
-        }
-        break;
-      case 14: // SFIXED64:
-        if (isFieldPresent(other, pos)) {
-          UnsafeUtil.putLong(message, offset, UnsafeUtil.getLong(other, offset));
-          setFieldPresent(message, pos);
-        }
-        break;
-      case 15: // SINT32:
-        if (isFieldPresent(other, pos)) {
-          UnsafeUtil.putInt(message, offset, UnsafeUtil.getInt(other, offset));
-          setFieldPresent(message, pos);
-        }
-        break;
-      case 16: // SINT64:
-        if (isFieldPresent(other, pos)) {
-          UnsafeUtil.putLong(message, offset, UnsafeUtil.getLong(other, offset));
-          setFieldPresent(message, pos);
-        }
-        break;
-      case 17: // GROUP:
-        mergeMessage(message, other, pos);
-        break;
-      case 18: // DOUBLE_LIST:
-      case 19: // FLOAT_LIST:
-      case 20: // INT64_LIST:
-      case 21: // UINT64_LIST:
-      case 22: // INT32_LIST:
-      case 23: // FIXED64_LIST:
-      case 24: // FIXED32_LIST:
-      case 25: // BOOL_LIST:
-      case 26: // STRING_LIST:
-      case 27: // MESSAGE_LIST:
-      case 28: // BYTES_LIST:
-      case 29: // UINT32_LIST:
-      case 30: // ENUM_LIST:
-      case 31: // SFIXED32_LIST:
-      case 32: // SFIXED64_LIST:
-      case 33: // SINT32_LIST:
-      case 34: // SINT64_LIST:
-      case 35: // DOUBLE_LIST_PACKED:
-      case 36: // FLOAT_LIST_PACKED:
-      case 37: // INT64_LIST_PACKED:
-      case 38: // UINT64_LIST_PACKED:
-      case 39: // INT32_LIST_PACKED:
-      case 40: // FIXED64_LIST_PACKED:
-      case 41: // FIXED32_LIST_PACKED:
-      case 42: // BOOL_LIST_PACKED:
-      case 43: // UINT32_LIST_PACKED:
-      case 44: // ENUM_LIST_PACKED:
-      case 45: // SFIXED32_LIST_PACKED:
-      case 46: // SFIXED64_LIST_PACKED:
-      case 47: // SINT32_LIST_PACKED:
-      case 48: // SINT64_LIST_PACKED:
-      case 49: // GROUP_LIST:
-        listFieldSchema.mergeListsAt(message, other, offset);
-        break;
-      case 50: // MAP:
-        SchemaUtil.mergeMap(mapFieldSchema, message, other, offset);
-        break;
-      case 51: // ONEOF_DOUBLE:
-      case 52: // ONEOF_FLOAT:
-      case 53: // ONEOF_INT64:
-      case 54: // ONEOF_UINT64:
-      case 55: // ONEOF_INT32:
-      case 56: // ONEOF_FIXED64:
-      case 57: // ONEOF_FIXED32:
-      case 58: // ONEOF_BOOL:
-      case 59: // ONEOF_STRING:
-        if (isOneofPresent(other, number, pos)) {
-          UnsafeUtil.putObject(message, offset, UnsafeUtil.getObject(other, offset));
-          setOneofPresent(message, number, pos);
-        }
-        break;
-
-      case 60: // ONEOF_MESSAGE:
-        mergeOneofMessage(message, other, pos);
-        break;
-      case 61: // ONEOF_BYTES:
-      case 62: // ONEOF_UINT32:
-      case 63: // ONEOF_ENUM:
-      case 64: // ONEOF_SFIXED32:
-      case 65: // ONEOF_SFIXED64:
-      case 66: // ONEOF_SINT32:
-      case 67: // ONEOF_SINT64:
-        if (isOneofPresent(other, number, pos)) {
-          UnsafeUtil.putObject(message, offset, UnsafeUtil.getObject(other, offset));
-          setOneofPresent(message, number, pos);
-        }
-        break;
-      case 68: // ONEOF_GROUP:
-        mergeOneofMessage(message, other, pos);
-        break;
-      default:
-        break;
-    }
-  }
-
-  private void mergeMessage(T message, T other, int pos) {
-    final int typeAndOffset = typeAndOffsetAt(pos);
-    final long offset = offset(typeAndOffset);
-
-    if (!isFieldPresent(other, pos)) {
-      return;
-    }
-
-    Object mine = UnsafeUtil.getObject(message, offset);
-    Object theirs = UnsafeUtil.getObject(other, offset);
-    if (mine != null && theirs != null) {
-      Object merged = Internal.mergeMessage(mine, theirs);
-      UnsafeUtil.putObject(message, offset, merged);
-      setFieldPresent(message, pos);
-    } else if (theirs != null) {
-      UnsafeUtil.putObject(message, offset, theirs);
-      setFieldPresent(message, pos);
-    }
-  }
-
-  private void mergeOneofMessage(T message, T other, int pos) {
-    int typeAndOffset = typeAndOffsetAt(pos);
-    int number = numberAt(pos);
-    long offset = offset(typeAndOffset);
-
-    if (!isOneofPresent(other, number, pos)) {
-      return;
-    }
-    Object mine = null;
-    if (isOneofPresent(message, number, pos)) {
-      mine = UnsafeUtil.getObject(message, offset);
-    }
-    Object theirs = UnsafeUtil.getObject(other, offset);
-    if (mine != null && theirs != null) {
-      Object merged = Internal.mergeMessage(mine, theirs);
-      UnsafeUtil.putObject(message, offset, merged);
-      setOneofPresent(message, number, pos);
-    } else if (theirs != null) {
-      UnsafeUtil.putObject(message, offset, theirs);
-      setOneofPresent(message, number, pos);
-    }
-  }
-
-  @Override
-  public int getSerializedSize(T message) {
-    return proto3 ? getSerializedSizeProto3(message) : getSerializedSizeProto2(message);
-  }
-
-  @SuppressWarnings("unchecked")
-  private int getSerializedSizeProto2(T message) {
-    int size = 0;
-
-    final sun.misc.Unsafe unsafe = UNSAFE;
-    int currentPresenceFieldOffset = NO_PRESENCE_SENTINEL;
-    int currentPresenceField = 0;
-    for (int i = 0; i < buffer.length; i += INTS_PER_FIELD) {
-      final int typeAndOffset = typeAndOffsetAt(i);
-      final int number = numberAt(i);
-
-      int fieldType = type(typeAndOffset);
-      int presenceMaskAndOffset = 0;
-      int presenceMask = 0;
-      if (fieldType <= 17) {
-        presenceMaskAndOffset = buffer[i + 2];
-        final int presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK;
-        presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS);
-        if (presenceFieldOffset != currentPresenceFieldOffset) {
-          currentPresenceFieldOffset = presenceFieldOffset;
-          currentPresenceField = unsafe.getInt(message, (long) presenceFieldOffset);
-        }
-      } else if (useCachedSizeField
-          && fieldType >= FieldType.DOUBLE_LIST_PACKED.id()
-          && fieldType <= FieldType.SINT64_LIST_PACKED.id()) {
-        presenceMaskAndOffset = buffer[i + 2] & OFFSET_MASK;
-      }
-
-      final long offset = offset(typeAndOffset);
-
-      switch (fieldType) {
-        case 0: // DOUBLE:
-          if ((currentPresenceField & presenceMask) != 0) {
-            size += CodedOutputStream.computeDoubleSize(number, 0);
-          }
-          break;
-        case 1: // FLOAT:
-          if ((currentPresenceField & presenceMask) != 0) {
-            size += CodedOutputStream.computeFloatSize(number, 0);
-          }
-          break;
-        case 2: // INT64:
-          if ((currentPresenceField & presenceMask) != 0) {
-            size += CodedOutputStream.computeInt64Size(number, unsafe.getLong(message, offset));
-          }
-          break;
-        case 3: // UINT64:
-          if ((currentPresenceField & presenceMask) != 0) {
-            size += CodedOutputStream.computeUInt64Size(number, unsafe.getLong(message, offset));
-          }
-          break;
-        case 4: // INT32:
-          if ((currentPresenceField & presenceMask) != 0) {
-            size += CodedOutputStream.computeInt32Size(number, unsafe.getInt(message, offset));
-          }
-          break;
-        case 5: // FIXED64:
-          if ((currentPresenceField & presenceMask) != 0) {
-            size += CodedOutputStream.computeFixed64Size(number, 0);
-          }
-          break;
-        case 6: // FIXED32:
-          if ((currentPresenceField & presenceMask) != 0) {
-            size += CodedOutputStream.computeFixed32Size(number, 0);
-          }
-          break;
-        case 7: // BOOL:
-          if ((currentPresenceField & presenceMask) != 0) {
-            size += CodedOutputStream.computeBoolSize(number, true);
-          }
-          break;
-        case 8: // STRING:
-          if ((currentPresenceField & presenceMask) != 0) {
-            Object value = unsafe.getObject(message, offset);
-            if (value instanceof ByteString) {
-              size += CodedOutputStream.computeBytesSize(number, (ByteString) value);
-            } else {
-              size += CodedOutputStream.computeStringSize(number, (String) value);
-            }
-          }
-          break;
-        case 9: // MESSAGE:
-          if ((currentPresenceField & presenceMask) != 0) {
-            Object value = unsafe.getObject(message, offset);
-            size += SchemaUtil.computeSizeMessage(number, value, getMessageFieldSchema(i));
-          }
-          break;
-        case 10: // BYTES:
-          if ((currentPresenceField & presenceMask) != 0) {
-            ByteString value = (ByteString) unsafe.getObject(message, offset);
-            size += CodedOutputStream.computeBytesSize(number, value);
-          }
-          break;
-        case 11: // UINT32:
-          if ((currentPresenceField & presenceMask) != 0) {
-            size += CodedOutputStream.computeUInt32Size(number, unsafe.getInt(message, offset));
-          }
-          break;
-        case 12: // ENUM:
-          if ((currentPresenceField & presenceMask) != 0) {
-            size += CodedOutputStream.computeEnumSize(number, unsafe.getInt(message, offset));
-          }
-          break;
-        case 13: // SFIXED32:
-          if ((currentPresenceField & presenceMask) != 0) {
-            size += CodedOutputStream.computeSFixed32Size(number, 0);
-          }
-          break;
-        case 14: // SFIXED64:
-          if ((currentPresenceField & presenceMask) != 0) {
-            size += CodedOutputStream.computeSFixed64Size(number, 0);
-          }
-          break;
-        case 15: // SINT32:
-          if ((currentPresenceField & presenceMask) != 0) {
-            size += CodedOutputStream.computeSInt32Size(number, unsafe.getInt(message, offset));
-          }
-          break;
-        case 16: // SINT64:
-          if ((currentPresenceField & presenceMask) != 0) {
-            size += CodedOutputStream.computeSInt64Size(number, unsafe.getLong(message, offset));
-          }
-          break;
-        case 17: // GROUP:
-          if ((currentPresenceField & presenceMask) != 0) {
-            size +=
-                CodedOutputStream.computeGroupSize(
-                    number,
-                    (MessageLite) unsafe.getObject(message, offset),
-                    getMessageFieldSchema(i));
-          }
-          break;
-        case 18: // DOUBLE_LIST:
-          size +=
-              SchemaUtil.computeSizeFixed64List(
-                  number, (List<?>) unsafe.getObject(message, offset), false);
-          break;
-        case 19: // FLOAT_LIST:
-          size +=
-              SchemaUtil.computeSizeFixed32List(
-                  number, (List<?>) unsafe.getObject(message, offset), false);
-          break;
-        case 20: // INT64_LIST:
-          size +=
-              SchemaUtil.computeSizeInt64List(
-                  number, (List<Long>) unsafe.getObject(message, offset), false);
-          break;
-        case 21: // UINT64_LIST:
-          size +=
-              SchemaUtil.computeSizeUInt64List(
-                  number, (List<Long>) unsafe.getObject(message, offset), false);
-          break;
-        case 22: // INT32_LIST:
-          size +=
-              SchemaUtil.computeSizeInt32List(
-                  number, (List<Integer>) unsafe.getObject(message, offset), false);
-          break;
-        case 23: // FIXED64_LIST:
-          size +=
-              SchemaUtil.computeSizeFixed64List(
-                  number, (List<?>) unsafe.getObject(message, offset), false);
-          break;
-        case 24: // FIXED32_LIST:
-          size +=
-              SchemaUtil.computeSizeFixed32List(
-                  number, (List<?>) unsafe.getObject(message, offset), false);
-          break;
-        case 25: // BOOL_LIST:
-          size +=
-              SchemaUtil.computeSizeBoolList(
-                  number, (List<?>) unsafe.getObject(message, offset), false);
-          break;
-        case 26: // STRING_LIST:
-          size +=
-              SchemaUtil.computeSizeStringList(number, (List<?>) unsafe.getObject(message, offset));
-          break;
-        case 27: // MESSAGE_LIST:
-          size +=
-              SchemaUtil.computeSizeMessageList(
-                  number, (List<?>) unsafe.getObject(message, offset), getMessageFieldSchema(i));
-          break;
-        case 28: // BYTES_LIST:
-          size +=
-              SchemaUtil.computeSizeByteStringList(
-                  number, (List<ByteString>) unsafe.getObject(message, offset));
-          break;
-        case 29: // UINT32_LIST:
-          size +=
-              SchemaUtil.computeSizeUInt32List(
-                  number, (List<Integer>) unsafe.getObject(message, offset), false);
-          break;
-        case 30: // ENUM_LIST:
-          size +=
-              SchemaUtil.computeSizeEnumList(
-                  number, (List<Integer>) unsafe.getObject(message, offset), false);
-          break;
-        case 31: // SFIXED32_LIST:
-          size +=
-              SchemaUtil.computeSizeFixed32List(
-                  number, (List<Integer>) unsafe.getObject(message, offset), false);
-          break;
-        case 32: // SFIXED64_LIST:
-          size +=
-              SchemaUtil.computeSizeFixed64List(
-                  number, (List<Long>) unsafe.getObject(message, offset), false);
-          break;
-        case 33: // SINT32_LIST:
-          size +=
-              SchemaUtil.computeSizeSInt32List(
-                  number, (List<Integer>) unsafe.getObject(message, offset), false);
-          break;
-        case 34: // SINT64_LIST:
-          size +=
-              SchemaUtil.computeSizeSInt64List(
-                  number, (List<Long>) unsafe.getObject(message, offset), false);
-          break;
-        case 35:
-          { // DOUBLE_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeFixed64ListNoTag(
-                    (List<Double>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 36:
-          { // FLOAT_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeFixed32ListNoTag(
-                    (List<Float>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 37:
-          { // INT64_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeInt64ListNoTag(
-                    (List<Long>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 38:
-          { // UINT64_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeUInt64ListNoTag(
-                    (List<Long>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 39:
-          { // INT32_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeInt32ListNoTag(
-                    (List<Integer>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 40:
-          { // FIXED64_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeFixed64ListNoTag(
-                    (List<Long>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 41:
-          { // FIXED32_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeFixed32ListNoTag(
-                    (List<Integer>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 42:
-          { // BOOL_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeBoolListNoTag(
-                    (List<Boolean>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 43:
-          { // UINT32_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeUInt32ListNoTag(
-                    (List<Integer>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 44:
-          { // ENUM_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeEnumListNoTag(
-                    (List<Integer>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 45:
-          { // SFIXED32_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeFixed32ListNoTag(
-                    (List<Integer>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 46:
-          { // SFIXED64_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeFixed64ListNoTag(
-                    (List<Long>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 47:
-          { // SINT32_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeSInt32ListNoTag(
-                    (List<Integer>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 48:
-          { // SINT64_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeSInt64ListNoTag(
-                    (List<Long>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 49: // GROUP_LIST:
-          size +=
-              SchemaUtil.computeSizeGroupList(
-                  number,
-                  (List<MessageLite>) unsafe.getObject(message, offset),
-                  getMessageFieldSchema(i));
-          break;
-        case 50: // MAP:
-          // TODO(dweis): Use schema cache.
-          size +=
-              mapFieldSchema.getSerializedSize(
-                  number, unsafe.getObject(message, offset), getMapFieldDefaultEntry(i));
-          break;
-        case 51: // ONEOF_DOUBLE:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeDoubleSize(number, 0);
-          }
-          break;
-        case 52: // ONEOF_FLOAT:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeFloatSize(number, 0);
-          }
-          break;
-        case 53: // ONEOF_INT64:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeInt64Size(number, oneofLongAt(message, offset));
-          }
-          break;
-        case 54: // ONEOF_UINT64:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeUInt64Size(number, oneofLongAt(message, offset));
-          }
-          break;
-        case 55: // ONEOF_INT32:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeInt32Size(number, oneofIntAt(message, offset));
-          }
-          break;
-        case 56: // ONEOF_FIXED64:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeFixed64Size(number, 0);
-          }
-          break;
-        case 57: // ONEOF_FIXED32:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeFixed32Size(number, 0);
-          }
-          break;
-        case 58: // ONEOF_BOOL:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeBoolSize(number, true);
-          }
-          break;
-        case 59: // ONEOF_STRING:
-          if (isOneofPresent(message, number, i)) {
-            Object value = unsafe.getObject(message, offset);
-            if (value instanceof ByteString) {
-              size += CodedOutputStream.computeBytesSize(number, (ByteString) value);
-            } else {
-              size += CodedOutputStream.computeStringSize(number, (String) value);
-            }
-          }
-          break;
-        case 60: // ONEOF_MESSAGE:
-          if (isOneofPresent(message, number, i)) {
-            Object value = unsafe.getObject(message, offset);
-            size += SchemaUtil.computeSizeMessage(number, value, getMessageFieldSchema(i));
-          }
-          break;
-        case 61: // ONEOF_BYTES:
-          if (isOneofPresent(message, number, i)) {
-            size +=
-                CodedOutputStream.computeBytesSize(
-                    number, (ByteString) unsafe.getObject(message, offset));
-          }
-          break;
-        case 62: // ONEOF_UINT32:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeUInt32Size(number, oneofIntAt(message, offset));
-          }
-          break;
-        case 63: // ONEOF_ENUM:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeEnumSize(number, oneofIntAt(message, offset));
-          }
-          break;
-        case 64: // ONEOF_SFIXED32:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeSFixed32Size(number, 0);
-          }
-          break;
-        case 65: // ONEOF_SFIXED64:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeSFixed64Size(number, 0);
-          }
-          break;
-        case 66: // ONEOF_SINT32:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeSInt32Size(number, oneofIntAt(message, offset));
-          }
-          break;
-        case 67: // ONEOF_SINT64:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeSInt64Size(number, oneofLongAt(message, offset));
-          }
-          break;
-        case 68: // ONEOF_GROUP:
-          if (isOneofPresent(message, number, i)) {
-            size +=
-                CodedOutputStream.computeGroupSize(
-                    number,
-                    (MessageLite) unsafe.getObject(message, offset),
-                    getMessageFieldSchema(i));
-          }
-          break;
-        default:
-          // Assume it's an empty entry.
-      }
-    }
-
-    size += getUnknownFieldsSerializedSize(unknownFieldSchema, message);
-
-    if (hasExtensions) {
-      size += extensionSchema.getExtensions(message).getSerializedSize();
-    }
-
-    return size;
-  }
-
-  private int getSerializedSizeProto3(T message) {
-    final sun.misc.Unsafe unsafe = UNSAFE;
-    int size = 0;
-    for (int i = 0; i < buffer.length; i += INTS_PER_FIELD) {
-      final int typeAndOffset = typeAndOffsetAt(i);
-      final int fieldType = type(typeAndOffset);
-      final int number = numberAt(i);
-
-      final long offset = offset(typeAndOffset);
-      final int cachedSizeOffset =
-          fieldType >= FieldType.DOUBLE_LIST_PACKED.id()
-                  && fieldType <= FieldType.SINT64_LIST_PACKED.id()
-              ? buffer[i + 2] & OFFSET_MASK
-              : 0;
-
-      switch (fieldType) {
-        case 0: // DOUBLE:
-          if (isFieldPresent(message, i)) {
-            size += CodedOutputStream.computeDoubleSize(number, 0);
-          }
-          break;
-        case 1: // FLOAT:
-          if (isFieldPresent(message, i)) {
-            size += CodedOutputStream.computeFloatSize(number, 0);
-          }
-          break;
-        case 2: // INT64:
-          if (isFieldPresent(message, i)) {
-            size += CodedOutputStream.computeInt64Size(number, UnsafeUtil.getLong(message, offset));
-          }
-          break;
-        case 3: // UINT64:
-          if (isFieldPresent(message, i)) {
-            size +=
-                CodedOutputStream.computeUInt64Size(number, UnsafeUtil.getLong(message, offset));
-          }
-          break;
-        case 4: // INT32:
-          if (isFieldPresent(message, i)) {
-            size += CodedOutputStream.computeInt32Size(number, UnsafeUtil.getInt(message, offset));
-          }
-          break;
-        case 5: // FIXED64:
-          if (isFieldPresent(message, i)) {
-            size += CodedOutputStream.computeFixed64Size(number, 0);
-          }
-          break;
-        case 6: // FIXED32:
-          if (isFieldPresent(message, i)) {
-            size += CodedOutputStream.computeFixed32Size(number, 0);
-          }
-          break;
-        case 7: // BOOL:
-          if (isFieldPresent(message, i)) {
-            size += CodedOutputStream.computeBoolSize(number, true);
-          }
-          break;
-        case 8: // STRING:
-          if (isFieldPresent(message, i)) {
-            Object value = UnsafeUtil.getObject(message, offset);
-            if (value instanceof ByteString) {
-              size += CodedOutputStream.computeBytesSize(number, (ByteString) value);
-            } else {
-              size += CodedOutputStream.computeStringSize(number, (String) value);
-            }
-          }
-          break;
-        case 9: // MESSAGE:
-          if (isFieldPresent(message, i)) {
-            Object value = UnsafeUtil.getObject(message, offset);
-            size += SchemaUtil.computeSizeMessage(number, value, getMessageFieldSchema(i));
-          }
-          break;
-        case 10: // BYTES:
-          if (isFieldPresent(message, i)) {
-            ByteString value = (ByteString) UnsafeUtil.getObject(message, offset);
-            size += CodedOutputStream.computeBytesSize(number, value);
-          }
-          break;
-        case 11: // UINT32:
-          if (isFieldPresent(message, i)) {
-            size += CodedOutputStream.computeUInt32Size(number, UnsafeUtil.getInt(message, offset));
-          }
-          break;
-        case 12: // ENUM:
-          if (isFieldPresent(message, i)) {
-            size += CodedOutputStream.computeEnumSize(number, UnsafeUtil.getInt(message, offset));
-          }
-          break;
-        case 13: // SFIXED32:
-          if (isFieldPresent(message, i)) {
-            size += CodedOutputStream.computeSFixed32Size(number, 0);
-          }
-          break;
-        case 14: // SFIXED64:
-          if (isFieldPresent(message, i)) {
-            size += CodedOutputStream.computeSFixed64Size(number, 0);
-          }
-          break;
-        case 15: // SINT32:
-          if (isFieldPresent(message, i)) {
-            size += CodedOutputStream.computeSInt32Size(number, UnsafeUtil.getInt(message, offset));
-          }
-          break;
-        case 16: // SINT64:
-          if (isFieldPresent(message, i)) {
-            size +=
-                CodedOutputStream.computeSInt64Size(number, UnsafeUtil.getLong(message, offset));
-          }
-          break;
-        case 17: // GROUP:
-          if (isFieldPresent(message, i)) {
-            size +=
-                CodedOutputStream.computeGroupSize(
-                    number,
-                    (MessageLite) UnsafeUtil.getObject(message, offset),
-                    getMessageFieldSchema(i));
-          }
-          break;
-        case 18: // DOUBLE_LIST:
-          size += SchemaUtil.computeSizeFixed64List(number, listAt(message, offset), false);
-          break;
-        case 19: // FLOAT_LIST:
-          size += SchemaUtil.computeSizeFixed32List(number, listAt(message, offset), false);
-          break;
-        case 20: // INT64_LIST:
-          size +=
-              SchemaUtil.computeSizeInt64List(number, (List<Long>) listAt(message, offset), false);
-          break;
-        case 21: // UINT64_LIST:
-          size +=
-              SchemaUtil.computeSizeUInt64List(number, (List<Long>) listAt(message, offset), false);
-          break;
-        case 22: // INT32_LIST:
-          size +=
-              SchemaUtil.computeSizeInt32List(
-                  number, (List<Integer>) listAt(message, offset), false);
-          break;
-        case 23: // FIXED64_LIST:
-          size += SchemaUtil.computeSizeFixed64List(number, listAt(message, offset), false);
-          break;
-        case 24: // FIXED32_LIST:
-          size += SchemaUtil.computeSizeFixed32List(number, listAt(message, offset), false);
-          break;
-        case 25: // BOOL_LIST:
-          size += SchemaUtil.computeSizeBoolList(number, listAt(message, offset), false);
-          break;
-        case 26: // STRING_LIST:
-          size += SchemaUtil.computeSizeStringList(number, listAt(message, offset));
-          break;
-        case 27: // MESSAGE_LIST:
-          size +=
-              SchemaUtil.computeSizeMessageList(
-                  number, listAt(message, offset), getMessageFieldSchema(i));
-          break;
-        case 28: // BYTES_LIST:
-          size +=
-              SchemaUtil.computeSizeByteStringList(
-                  number, (List<ByteString>) listAt(message, offset));
-          break;
-        case 29: // UINT32_LIST:
-          size +=
-              SchemaUtil.computeSizeUInt32List(
-                  number, (List<Integer>) listAt(message, offset), false);
-          break;
-        case 30: // ENUM_LIST:
-          size +=
-              SchemaUtil.computeSizeEnumList(
-                  number, (List<Integer>) listAt(message, offset), false);
-          break;
-        case 31: // SFIXED32_LIST:
-          size += SchemaUtil.computeSizeFixed32List(number, listAt(message, offset), false);
-          break;
-        case 32: // SFIXED64_LIST:
-          size += SchemaUtil.computeSizeFixed64List(number, listAt(message, offset), false);
-          break;
-        case 33: // SINT32_LIST:
-          size +=
-              SchemaUtil.computeSizeSInt32List(
-                  number, (List<Integer>) listAt(message, offset), false);
-          break;
-        case 34: // SINT64_LIST:
-          size +=
-              SchemaUtil.computeSizeSInt64List(number, (List<Long>) listAt(message, offset), false);
-          break;
-        case 35:
-          { // DOUBLE_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeFixed64ListNoTag(
-                    (List<Double>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 36:
-          { // FLOAT_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeFixed32ListNoTag(
-                    (List<Float>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 37:
-          { // INT64_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeInt64ListNoTag(
-                    (List<Long>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 38:
-          { // UINT64_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeUInt64ListNoTag(
-                    (List<Long>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 39:
-          { // INT32_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeInt32ListNoTag(
-                    (List<Integer>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 40:
-          { // FIXED64_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeFixed64ListNoTag(
-                    (List<Long>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 41:
-          { // FIXED32_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeFixed32ListNoTag(
-                    (List<Integer>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 42:
-          { // BOOL_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeBoolListNoTag(
-                    (List<Boolean>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 43:
-          { // UINT32_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeUInt32ListNoTag(
-                    (List<Integer>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 44:
-          { // ENUM_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeEnumListNoTag(
-                    (List<Integer>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 45:
-          { // SFIXED32_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeFixed32ListNoTag(
-                    (List<Integer>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 46:
-          { // SFIXED64_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeFixed64ListNoTag(
-                    (List<Long>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 47:
-          { // SINT32_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeSInt32ListNoTag(
-                    (List<Integer>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 48:
-          { // SINT64_LIST_PACKED:
-            int fieldSize =
-                SchemaUtil.computeSizeSInt64ListNoTag(
-                    (List<Long>) unsafe.getObject(message, offset));
-            if (fieldSize > 0) {
-              if (useCachedSizeField) {
-                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
-              }
-              size +=
-                  CodedOutputStream.computeTagSize(number)
-                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
-                      + fieldSize;
-            }
-            break;
-          }
-        case 49: // GROUP_LIST:
-          size +=
-              SchemaUtil.computeSizeGroupList(
-                  number, (List<MessageLite>) listAt(message, offset), getMessageFieldSchema(i));
-          break;
-        case 50: // MAP:
-          // TODO(dweis): Use schema cache.
-          size +=
-              mapFieldSchema.getSerializedSize(
-                  number, UnsafeUtil.getObject(message, offset), getMapFieldDefaultEntry(i));
-          break;
-        case 51: // ONEOF_DOUBLE:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeDoubleSize(number, 0);
-          }
-          break;
-        case 52: // ONEOF_FLOAT:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeFloatSize(number, 0);
-          }
-          break;
-        case 53: // ONEOF_INT64:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeInt64Size(number, oneofLongAt(message, offset));
-          }
-          break;
-        case 54: // ONEOF_UINT64:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeUInt64Size(number, oneofLongAt(message, offset));
-          }
-          break;
-        case 55: // ONEOF_INT32:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeInt32Size(number, oneofIntAt(message, offset));
-          }
-          break;
-        case 56: // ONEOF_FIXED64:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeFixed64Size(number, 0);
-          }
-          break;
-        case 57: // ONEOF_FIXED32:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeFixed32Size(number, 0);
-          }
-          break;
-        case 58: // ONEOF_BOOL:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeBoolSize(number, true);
-          }
-          break;
-        case 59: // ONEOF_STRING:
-          if (isOneofPresent(message, number, i)) {
-            Object value = UnsafeUtil.getObject(message, offset);
-            if (value instanceof ByteString) {
-              size += CodedOutputStream.computeBytesSize(number, (ByteString) value);
-            } else {
-              size += CodedOutputStream.computeStringSize(number, (String) value);
-            }
-          }
-          break;
-        case 60: // ONEOF_MESSAGE:
-          if (isOneofPresent(message, number, i)) {
-            Object value = UnsafeUtil.getObject(message, offset);
-            size += SchemaUtil.computeSizeMessage(number, value, getMessageFieldSchema(i));
-          }
-          break;
-        case 61: // ONEOF_BYTES:
-          if (isOneofPresent(message, number, i)) {
-            size +=
-                CodedOutputStream.computeBytesSize(
-                    number, (ByteString) UnsafeUtil.getObject(message, offset));
-          }
-          break;
-        case 62: // ONEOF_UINT32:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeUInt32Size(number, oneofIntAt(message, offset));
-          }
-          break;
-        case 63: // ONEOF_ENUM:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeEnumSize(number, oneofIntAt(message, offset));
-          }
-          break;
-        case 64: // ONEOF_SFIXED32:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeSFixed32Size(number, 0);
-          }
-          break;
-        case 65: // ONEOF_SFIXED64:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeSFixed64Size(number, 0);
-          }
-          break;
-        case 66: // ONEOF_SINT32:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeSInt32Size(number, oneofIntAt(message, offset));
-          }
-          break;
-        case 67: // ONEOF_SINT64:
-          if (isOneofPresent(message, number, i)) {
-            size += CodedOutputStream.computeSInt64Size(number, oneofLongAt(message, offset));
-          }
-          break;
-        case 68: // ONEOF_GROUP:
-          if (isOneofPresent(message, number, i)) {
-            size +=
-                CodedOutputStream.computeGroupSize(
-                    number,
-                    (MessageLite) UnsafeUtil.getObject(message, offset),
-                    getMessageFieldSchema(i));
-          }
-          break;
-        default:
-          // Assume it's an empty entry.
-      }
-    }
-
-    size += getUnknownFieldsSerializedSize(unknownFieldSchema, message);
-
-    return size;
-  }
-
-  private <UT, UB> int getUnknownFieldsSerializedSize(
-      UnknownFieldSchema<UT, UB> schema, T message) {
-    UT unknowns = schema.getFromMessage(message);
-    return schema.getSerializedSize(unknowns);
-  }
-
-  private static List<?> listAt(Object message, long offset) {
-    return (List<?>) UnsafeUtil.getObject(message, offset);
-  }
-
-  @SuppressWarnings("unchecked")
-  @Override
-  // TODO(nathanmittler): Consider serializing oneof fields last so that only one entry per
-  // oneof is actually serialized. This would mean that we would violate the serialization order
-  // contract. It should also be noted that Go currently does this.
-  public void writeTo(T message, Writer writer) throws IOException {
-    if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) {
-      writeFieldsInDescendingOrder(message, writer);
-    } else {
-      if (proto3) {
-        writeFieldsInAscendingOrderProto3(message, writer);
-      } else {
-        writeFieldsInAscendingOrderProto2(message, writer);
-      }
-    }
-  }
-
-  @SuppressWarnings("unchecked")
-  private void writeFieldsInAscendingOrderProto2(T message, Writer writer) throws IOException {
-    Iterator<? extends Map.Entry<?, ?>> extensionIterator = null;
-    Map.Entry nextExtension = null;
-    if (hasExtensions) {
-      FieldSet<?> extensions = extensionSchema.getExtensions(message);
-      if (!extensions.isEmpty()) {
-        extensionIterator = extensions.iterator();
-        nextExtension = extensionIterator.next();
-      }
-    }
-    int currentPresenceFieldOffset = NO_PRESENCE_SENTINEL;
-    int currentPresenceField = 0;
-    final int bufferLength = buffer.length;
-    final sun.misc.Unsafe unsafe = UNSAFE;
-    for (int pos = 0; pos < bufferLength; pos += INTS_PER_FIELD) {
-      final int typeAndOffset = typeAndOffsetAt(pos);
-      final int number = numberAt(pos);
-      final int fieldType = type(typeAndOffset);
-
-      int presenceMaskAndOffset = 0;
-      int presenceMask = 0;
-      if (fieldType <= 17) {
-        presenceMaskAndOffset = buffer[pos + 2];
-        final int presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK;
-        if (presenceFieldOffset != currentPresenceFieldOffset) {
-          currentPresenceFieldOffset = presenceFieldOffset;
-          currentPresenceField = unsafe.getInt(message, (long) presenceFieldOffset);
-        }
-        presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS);
-      }
-
-      // Write any extensions that need to be written before the current field.
-      while (nextExtension != null && extensionSchema.extensionNumber(nextExtension) <= number) {
-        extensionSchema.serializeExtension(writer, nextExtension);
-        nextExtension = extensionIterator.hasNext() ? extensionIterator.next() : null;
-      }
-      final long offset = offset(typeAndOffset);
-
-      switch (fieldType) {
-        case 0: // DOUBLE:
-          if ((currentPresenceField & presenceMask) != 0) {
-            writer.writeDouble(number, doubleAt(message, offset));
-          }
-          break;
-        case 1: // FLOAT:
-          if ((currentPresenceField & presenceMask) != 0) {
-            writer.writeFloat(number, floatAt(message, offset));
-          }
-          break;
-        case 2: // INT64:
-          if ((currentPresenceField & presenceMask) != 0) {
-            writer.writeInt64(number, unsafe.getLong(message, offset));
-          }
-          break;
-        case 3: // UINT64:
-          if ((currentPresenceField & presenceMask) != 0) {
-            writer.writeUInt64(number, unsafe.getLong(message, offset));
-          }
-          break;
-        case 4: // INT32:
-          if ((currentPresenceField & presenceMask) != 0) {
-            writer.writeInt32(number, unsafe.getInt(message, offset));
-          }
-          break;
-        case 5: // FIXED64:
-          if ((currentPresenceField & presenceMask) != 0) {
-            writer.writeFixed64(number, unsafe.getLong(message, offset));
-          }
-          break;
-        case 6: // FIXED32:
-          if ((currentPresenceField & presenceMask) != 0) {
-            writer.writeFixed32(number, unsafe.getInt(message, offset));
-          }
-          break;
-        case 7: // BOOL:
-          if ((currentPresenceField & presenceMask) != 0) {
-            writer.writeBool(number, booleanAt(message, offset));
-          }
-          break;
-        case 8: // STRING:
-          if ((currentPresenceField & presenceMask) != 0) {
-            writeString(number, unsafe.getObject(message, offset), writer);
-          }
-          break;
-        case 9: // MESSAGE:
-          if ((currentPresenceField & presenceMask) != 0) {
-            Object value = unsafe.getObject(message, offset);
-            writer.writeMessage(number, value, getMessageFieldSchema(pos));
-          }
-          break;
-        case 10: // BYTES:
-          if ((currentPresenceField & presenceMask) != 0) {
-            writer.writeBytes(number, (ByteString) unsafe.getObject(message, offset));
-          }
-          break;
-        case 11: // UINT32:
-          if ((currentPresenceField & presenceMask) != 0) {
-            writer.writeUInt32(number, unsafe.getInt(message, offset));
-          }
-          break;
-        case 12: // ENUM:
-          if ((currentPresenceField & presenceMask) != 0) {
-            writer.writeEnum(number, unsafe.getInt(message, offset));
-          }
-          break;
-        case 13: // SFIXED32:
-          if ((currentPresenceField & presenceMask) != 0) {
-            writer.writeSFixed32(number, unsafe.getInt(message, offset));
-          }
-          break;
-        case 14: // SFIXED64:
-          if ((currentPresenceField & presenceMask) != 0) {
-            writer.writeSFixed64(number, unsafe.getLong(message, offset));
-          }
-          break;
-        case 15: // SINT32:
-          if ((currentPresenceField & presenceMask) != 0) {
-            writer.writeSInt32(number, unsafe.getInt(message, offset));
-          }
-          break;
-        case 16: // SINT64:
-          if ((currentPresenceField & presenceMask) != 0) {
-            writer.writeSInt64(number, unsafe.getLong(message, offset));
-          }
-          break;
-        case 17: // GROUP:
-          if ((currentPresenceField & presenceMask) != 0) {
-            writer.writeGroup(
-                number, unsafe.getObject(message, offset), getMessageFieldSchema(pos));
-          }
-          break;
-        case 18: // DOUBLE_LIST:
-          SchemaUtil.writeDoubleList(
-              numberAt(pos), (List<Double>) unsafe.getObject(message, offset), writer, false);
-          break;
-        case 19: // FLOAT_LIST:
-          SchemaUtil.writeFloatList(
-              numberAt(pos), (List<Float>) unsafe.getObject(message, offset), writer, false);
-          break;
-        case 20: // INT64_LIST:
-          SchemaUtil.writeInt64List(
-              numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, false);
-          break;
-        case 21: // UINT64_LIST:
-          SchemaUtil.writeUInt64List(
-              numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, false);
-          break;
-        case 22: // INT32_LIST:
-          SchemaUtil.writeInt32List(
-              numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, false);
-          break;
-        case 23: // FIXED64_LIST:
-          SchemaUtil.writeFixed64List(
-              numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, false);
-          break;
-        case 24: // FIXED32_LIST:
-          SchemaUtil.writeFixed32List(
-              numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, false);
-          break;
-        case 25: // BOOL_LIST:
-          SchemaUtil.writeBoolList(
-              numberAt(pos), (List<Boolean>) unsafe.getObject(message, offset), writer, false);
-          break;
-        case 26: // STRING_LIST:
-          SchemaUtil.writeStringList(
-              numberAt(pos), (List<String>) unsafe.getObject(message, offset), writer);
-          break;
-        case 27: // MESSAGE_LIST:
-          SchemaUtil.writeMessageList(
-              numberAt(pos),
-              (List<?>) unsafe.getObject(message, offset),
-              writer,
-              getMessageFieldSchema(pos));
-          break;
-        case 28: // BYTES_LIST:
-          SchemaUtil.writeBytesList(
-              numberAt(pos), (List<ByteString>) unsafe.getObject(message, offset), writer);
-          break;
-        case 29: // UINT32_LIST:
-          SchemaUtil.writeUInt32List(
-              numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, false);
-          break;
-        case 30: // ENUM_LIST:
-          SchemaUtil.writeEnumList(
-              numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, false);
-          break;
-        case 31: // SFIXED32_LIST:
-          SchemaUtil.writeSFixed32List(
-              numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, false);
-          break;
-        case 32: // SFIXED64_LIST:
-          SchemaUtil.writeSFixed64List(
-              numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, false);
-          break;
-        case 33: // SINT32_LIST:
-          SchemaUtil.writeSInt32List(
-              numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, false);
-          break;
-        case 34: // SINT64_LIST:
-          SchemaUtil.writeSInt64List(
-              numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, false);
-          break;
-        case 35: // DOUBLE_LIST_PACKED:
-          // TODO(xiaofeng): Make use of cached field size to speed up serialization.
-          SchemaUtil.writeDoubleList(
-              numberAt(pos), (List<Double>) unsafe.getObject(message, offset), writer, true);
-          break;
-        case 36: // FLOAT_LIST_PACKED:
-          SchemaUtil.writeFloatList(
-              numberAt(pos), (List<Float>) unsafe.getObject(message, offset), writer, true);
-          break;
-        case 37: // INT64_LIST_PACKED:
-          SchemaUtil.writeInt64List(
-              numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, true);
-          break;
-        case 38: // UINT64_LIST_PACKED:
-          SchemaUtil.writeUInt64List(
-              numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, true);
-          break;
-        case 39: // INT32_LIST_PACKED:
-          SchemaUtil.writeInt32List(
-              numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, true);
-          break;
-        case 40: // FIXED64_LIST_PACKED:
-          SchemaUtil.writeFixed64List(
-              numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, true);
-          break;
-        case 41: // FIXED32_LIST_PACKED:
-          SchemaUtil.writeFixed32List(
-              numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, true);
-
-          break;
-        case 42: // BOOL_LIST_PACKED:
-          SchemaUtil.writeBoolList(
-              numberAt(pos), (List<Boolean>) unsafe.getObject(message, offset), writer, true);
-          break;
-        case 43: // UINT32_LIST_PACKED:
-          SchemaUtil.writeUInt32List(
-              numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, true);
-          break;
-        case 44: // ENUM_LIST_PACKED:
-          SchemaUtil.writeEnumList(
-              numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, true);
-          break;
-        case 45: // SFIXED32_LIST_PACKED:
-          SchemaUtil.writeSFixed32List(
-              numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, true);
-          break;
-        case 46: // SFIXED64_LIST_PACKED:
-          SchemaUtil.writeSFixed64List(
-              numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, true);
-          break;
-        case 47: // SINT32_LIST_PACKED:
-          SchemaUtil.writeSInt32List(
-              numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, true);
-          break;
-        case 48: // SINT64_LIST_PACKED:
-          SchemaUtil.writeSInt64List(
-              numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, true);
-          break;
-        case 49: // GROUP_LIST:
-          SchemaUtil.writeGroupList(
-              numberAt(pos),
-              (List<?>) unsafe.getObject(message, offset),
-              writer,
-              getMessageFieldSchema(pos));
-          break;
-        case 50: // MAP:
-          // TODO(dweis): Use schema cache.
-          writeMapHelper(writer, number, unsafe.getObject(message, offset), pos);
-          break;
-        case 51: // ONEOF_DOUBLE:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeDouble(number, oneofDoubleAt(message, offset));
-          }
-          break;
-        case 52: // ONEOF_FLOAT:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeFloat(number, oneofFloatAt(message, offset));
-          }
-          break;
-        case 53: // ONEOF_INT64:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeInt64(number, oneofLongAt(message, offset));
-          }
-          break;
-        case 54: // ONEOF_UINT64:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeUInt64(number, oneofLongAt(message, offset));
-          }
-          break;
-        case 55: // ONEOF_INT32:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeInt32(number, oneofIntAt(message, offset));
-          }
-          break;
-        case 56: // ONEOF_FIXED64:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeFixed64(number, oneofLongAt(message, offset));
-          }
-          break;
-        case 57: // ONEOF_FIXED32:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeFixed32(number, oneofIntAt(message, offset));
-          }
-          break;
-        case 58: // ONEOF_BOOL:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeBool(number, oneofBooleanAt(message, offset));
-          }
-          break;
-        case 59: // ONEOF_STRING:
-          if (isOneofPresent(message, number, pos)) {
-            writeString(number, unsafe.getObject(message, offset), writer);
-          }
-          break;
-        case 60: // ONEOF_MESSAGE:
-          if (isOneofPresent(message, number, pos)) {
-            Object value = unsafe.getObject(message, offset);
-            writer.writeMessage(number, value, getMessageFieldSchema(pos));
-          }
-          break;
-        case 61: // ONEOF_BYTES:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeBytes(number, (ByteString) unsafe.getObject(message, offset));
-          }
-          break;
-        case 62: // ONEOF_UINT32:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeUInt32(number, oneofIntAt(message, offset));
-          }
-          break;
-        case 63: // ONEOF_ENUM:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeEnum(number, oneofIntAt(message, offset));
-          }
-          break;
-        case 64: // ONEOF_SFIXED32:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeSFixed32(number, oneofIntAt(message, offset));
-          }
-          break;
-        case 65: // ONEOF_SFIXED64:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeSFixed64(number, oneofLongAt(message, offset));
-          }
-          break;
-        case 66: // ONEOF_SINT32:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeSInt32(number, oneofIntAt(message, offset));
-          }
-          break;
-        case 67: // ONEOF_SINT64:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeSInt64(number, oneofLongAt(message, offset));
-          }
-          break;
-        case 68: // ONEOF_GROUP:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeGroup(
-                number, unsafe.getObject(message, offset), getMessageFieldSchema(pos));
-          }
-          break;
-        default:
-          // Assume it's an empty entry - just go to the next entry.
-          break;
-      }
-    }
-    while (nextExtension != null) {
-      extensionSchema.serializeExtension(writer, nextExtension);
-      nextExtension = extensionIterator.hasNext() ? extensionIterator.next() : null;
-    }
-    writeUnknownInMessageTo(unknownFieldSchema, message, writer);
-  }
-
-  @SuppressWarnings("unchecked")
-  private void writeFieldsInAscendingOrderProto3(T message, Writer writer) throws IOException {
-    Iterator<? extends Map.Entry<?, ?>> extensionIterator = null;
-    Map.Entry nextExtension = null;
-    if (hasExtensions) {
-      FieldSet<?> extensions = extensionSchema.getExtensions(message);
-      if (!extensions.isEmpty()) {
-        extensionIterator = extensions.iterator();
-        nextExtension = extensionIterator.next();
-      }
-    }
-    final int bufferLength = buffer.length;
-    for (int pos = 0; pos < bufferLength; pos += INTS_PER_FIELD) {
-      final int typeAndOffset = typeAndOffsetAt(pos);
-      final int number = numberAt(pos);
-
-      // Write any extensions that need to be written before the current field.
-      while (nextExtension != null && extensionSchema.extensionNumber(nextExtension) <= number) {
-        extensionSchema.serializeExtension(writer, nextExtension);
-        nextExtension = extensionIterator.hasNext() ? extensionIterator.next() : null;
-      }
-
-      switch (type(typeAndOffset)) {
-        case 0: // DOUBLE:
-          if (isFieldPresent(message, pos)) {
-            writer.writeDouble(number, doubleAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 1: // FLOAT:
-          if (isFieldPresent(message, pos)) {
-            writer.writeFloat(number, floatAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 2: // INT64:
-          if (isFieldPresent(message, pos)) {
-            writer.writeInt64(number, longAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 3: // UINT64:
-          if (isFieldPresent(message, pos)) {
-            writer.writeUInt64(number, longAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 4: // INT32:
-          if (isFieldPresent(message, pos)) {
-            writer.writeInt32(number, intAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 5: // FIXED64:
-          if (isFieldPresent(message, pos)) {
-            writer.writeFixed64(number, longAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 6: // FIXED32:
-          if (isFieldPresent(message, pos)) {
-            writer.writeFixed32(number, intAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 7: // BOOL:
-          if (isFieldPresent(message, pos)) {
-            writer.writeBool(number, booleanAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 8: // STRING:
-          if (isFieldPresent(message, pos)) {
-            writeString(number, UnsafeUtil.getObject(message, offset(typeAndOffset)), writer);
-          }
-          break;
-        case 9: // MESSAGE:
-          if (isFieldPresent(message, pos)) {
-            Object value = UnsafeUtil.getObject(message, offset(typeAndOffset));
-            writer.writeMessage(number, value, getMessageFieldSchema(pos));
-          }
-          break;
-        case 10: // BYTES:
-          if (isFieldPresent(message, pos)) {
-            writer.writeBytes(
-                number, (ByteString) UnsafeUtil.getObject(message, offset(typeAndOffset)));
-          }
-          break;
-        case 11: // UINT32:
-          if (isFieldPresent(message, pos)) {
-            writer.writeUInt32(number, intAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 12: // ENUM:
-          if (isFieldPresent(message, pos)) {
-            writer.writeEnum(number, intAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 13: // SFIXED32:
-          if (isFieldPresent(message, pos)) {
-            writer.writeSFixed32(number, intAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 14: // SFIXED64:
-          if (isFieldPresent(message, pos)) {
-            writer.writeSFixed64(number, longAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 15: // SINT32:
-          if (isFieldPresent(message, pos)) {
-            writer.writeSInt32(number, intAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 16: // SINT64:
-          if (isFieldPresent(message, pos)) {
-            writer.writeSInt64(number, longAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 17: // GROUP:
-          if (isFieldPresent(message, pos)) {
-            writer.writeGroup(
-                number,
-                UnsafeUtil.getObject(message, offset(typeAndOffset)),
-                getMessageFieldSchema(pos));
-          }
-          break;
-        case 18: // DOUBLE_LIST:
-          SchemaUtil.writeDoubleList(
-              numberAt(pos),
-              (List<Double>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 19: // FLOAT_LIST:
-          SchemaUtil.writeFloatList(
-              numberAt(pos),
-              (List<Float>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 20: // INT64_LIST:
-          SchemaUtil.writeInt64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 21: // UINT64_LIST:
-          SchemaUtil.writeUInt64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 22: // INT32_LIST:
-          SchemaUtil.writeInt32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 23: // FIXED64_LIST:
-          SchemaUtil.writeFixed64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 24: // FIXED32_LIST:
-          SchemaUtil.writeFixed32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 25: // BOOL_LIST:
-          SchemaUtil.writeBoolList(
-              numberAt(pos),
-              (List<Boolean>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 26: // STRING_LIST:
-          SchemaUtil.writeStringList(
-              numberAt(pos),
-              (List<String>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer);
-          break;
-        case 27: // MESSAGE_LIST:
-          SchemaUtil.writeMessageList(
-              numberAt(pos),
-              (List<?>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              getMessageFieldSchema(pos));
-          break;
-        case 28: // BYTES_LIST:
-          SchemaUtil.writeBytesList(
-              numberAt(pos),
-              (List<ByteString>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer);
-          break;
-        case 29: // UINT32_LIST:
-          SchemaUtil.writeUInt32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 30: // ENUM_LIST:
-          SchemaUtil.writeEnumList(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 31: // SFIXED32_LIST:
-          SchemaUtil.writeSFixed32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 32: // SFIXED64_LIST:
-          SchemaUtil.writeSFixed64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 33: // SINT32_LIST:
-          SchemaUtil.writeSInt32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 34: // SINT64_LIST:
-          SchemaUtil.writeSInt64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 35: // DOUBLE_LIST_PACKED:
-          // TODO(xiaofeng): Make use of cached field size to speed up serialization.
-          SchemaUtil.writeDoubleList(
-              numberAt(pos),
-              (List<Double>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 36: // FLOAT_LIST_PACKED:
-          SchemaUtil.writeFloatList(
-              numberAt(pos),
-              (List<Float>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 37: // INT64_LIST_PACKED:
-          SchemaUtil.writeInt64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 38: // UINT64_LIST_PACKED:
-          SchemaUtil.writeUInt64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 39: // INT32_LIST_PACKED:
-          SchemaUtil.writeInt32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 40: // FIXED64_LIST_PACKED:
-          SchemaUtil.writeFixed64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 41: // FIXED32_LIST_PACKED:
-          SchemaUtil.writeFixed32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-
-          break;
-        case 42: // BOOL_LIST_PACKED:
-          SchemaUtil.writeBoolList(
-              numberAt(pos),
-              (List<Boolean>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 43: // UINT32_LIST_PACKED:
-          SchemaUtil.writeUInt32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 44: // ENUM_LIST_PACKED:
-          SchemaUtil.writeEnumList(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 45: // SFIXED32_LIST_PACKED:
-          SchemaUtil.writeSFixed32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 46: // SFIXED64_LIST_PACKED:
-          SchemaUtil.writeSFixed64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 47: // SINT32_LIST_PACKED:
-          SchemaUtil.writeSInt32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 48: // SINT64_LIST_PACKED:
-          SchemaUtil.writeSInt64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 49: // GROUP_LIST:
-          SchemaUtil.writeGroupList(
-              numberAt(pos),
-              (List<?>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              getMessageFieldSchema(pos));
-          break;
-        case 50: // MAP:
-          // TODO(dweis): Use schema cache.
-          writeMapHelper(writer, number, UnsafeUtil.getObject(message, offset(typeAndOffset)), pos);
-          break;
-        case 51: // ONEOF_DOUBLE:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeDouble(number, oneofDoubleAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 52: // ONEOF_FLOAT:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeFloat(number, oneofFloatAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 53: // ONEOF_INT64:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeInt64(number, oneofLongAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 54: // ONEOF_UINT64:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeUInt64(number, oneofLongAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 55: // ONEOF_INT32:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeInt32(number, oneofIntAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 56: // ONEOF_FIXED64:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeFixed64(number, oneofLongAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 57: // ONEOF_FIXED32:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeFixed32(number, oneofIntAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 58: // ONEOF_BOOL:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeBool(number, oneofBooleanAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 59: // ONEOF_STRING:
-          if (isOneofPresent(message, number, pos)) {
-            writeString(number, UnsafeUtil.getObject(message, offset(typeAndOffset)), writer);
-          }
-          break;
-        case 60: // ONEOF_MESSAGE:
-          if (isOneofPresent(message, number, pos)) {
-            Object value = UnsafeUtil.getObject(message, offset(typeAndOffset));
-            writer.writeMessage(number, value, getMessageFieldSchema(pos));
-          }
-          break;
-        case 61: // ONEOF_BYTES:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeBytes(
-                number, (ByteString) UnsafeUtil.getObject(message, offset(typeAndOffset)));
-          }
-          break;
-        case 62: // ONEOF_UINT32:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeUInt32(number, oneofIntAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 63: // ONEOF_ENUM:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeEnum(number, oneofIntAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 64: // ONEOF_SFIXED32:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeSFixed32(number, oneofIntAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 65: // ONEOF_SFIXED64:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeSFixed64(number, oneofLongAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 66: // ONEOF_SINT32:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeSInt32(number, oneofIntAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 67: // ONEOF_SINT64:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeSInt64(number, oneofLongAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 68: // ONEOF_GROUP:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeGroup(
-                number,
-                UnsafeUtil.getObject(message, offset(typeAndOffset)),
-                getMessageFieldSchema(pos));
-          }
-          break;
-        default:
-          // Assume it's an empty entry - just go to the next entry.
-          break;
-      }
-    }
-    while (nextExtension != null) {
-      extensionSchema.serializeExtension(writer, nextExtension);
-      nextExtension = extensionIterator.hasNext() ? extensionIterator.next() : null;
-    }
-    writeUnknownInMessageTo(unknownFieldSchema, message, writer);
-  }
-
-  @SuppressWarnings("unchecked")
-  private void writeFieldsInDescendingOrder(T message, Writer writer) throws IOException {
-    writeUnknownInMessageTo(unknownFieldSchema, message, writer);
-
-    Iterator<? extends Map.Entry<?, ?>> extensionIterator = null;
-    Map.Entry nextExtension = null;
-    if (hasExtensions) {
-      FieldSet<?> extensions = extensionSchema.getExtensions(message);
-      if (!extensions.isEmpty()) {
-        extensionIterator = extensions.descendingIterator();
-        nextExtension = extensionIterator.next();
-      }
-    }
-
-    for (int pos = buffer.length - INTS_PER_FIELD; pos >= 0; pos -= INTS_PER_FIELD) {
-      final int typeAndOffset = typeAndOffsetAt(pos);
-      final int number = numberAt(pos);
-
-      // Write any extensions that need to be written before the current field.
-      while (nextExtension != null && extensionSchema.extensionNumber(nextExtension) > number) {
-        extensionSchema.serializeExtension(writer, nextExtension);
-        nextExtension = extensionIterator.hasNext() ? extensionIterator.next() : null;
-      }
-
-      switch (type(typeAndOffset)) {
-        case 0: // DOUBLE:
-          if (isFieldPresent(message, pos)) {
-            writer.writeDouble(number, doubleAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 1: // FLOAT:
-          if (isFieldPresent(message, pos)) {
-            writer.writeFloat(number, floatAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 2: // INT64:
-          if (isFieldPresent(message, pos)) {
-            writer.writeInt64(number, longAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 3: // UINT64:
-          if (isFieldPresent(message, pos)) {
-            writer.writeUInt64(number, longAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 4: // INT32:
-          if (isFieldPresent(message, pos)) {
-            writer.writeInt32(number, intAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 5: // FIXED64:
-          if (isFieldPresent(message, pos)) {
-            writer.writeFixed64(number, longAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 6: // FIXED32:
-          if (isFieldPresent(message, pos)) {
-            writer.writeFixed32(number, intAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 7: // BOOL:
-          if (isFieldPresent(message, pos)) {
-            writer.writeBool(number, booleanAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 8: // STRING:
-          if (isFieldPresent(message, pos)) {
-            writeString(number, UnsafeUtil.getObject(message, offset(typeAndOffset)), writer);
-          }
-          break;
-        case 9: // MESSAGE:
-          if (isFieldPresent(message, pos)) {
-            Object value = UnsafeUtil.getObject(message, offset(typeAndOffset));
-            writer.writeMessage(number, value, getMessageFieldSchema(pos));
-          }
-          break;
-        case 10: // BYTES:
-          if (isFieldPresent(message, pos)) {
-            writer.writeBytes(
-                number, (ByteString) UnsafeUtil.getObject(message, offset(typeAndOffset)));
-          }
-          break;
-        case 11: // UINT32:
-          if (isFieldPresent(message, pos)) {
-            writer.writeUInt32(number, intAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 12: // ENUM:
-          if (isFieldPresent(message, pos)) {
-            writer.writeEnum(number, intAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 13: // SFIXED32:
-          if (isFieldPresent(message, pos)) {
-            writer.writeSFixed32(number, intAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 14: // SFIXED64:
-          if (isFieldPresent(message, pos)) {
-            writer.writeSFixed64(number, longAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 15: // SINT32:
-          if (isFieldPresent(message, pos)) {
-            writer.writeSInt32(number, intAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 16: // SINT64:
-          if (isFieldPresent(message, pos)) {
-            writer.writeSInt64(number, longAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 17: // GROUP:
-          if (isFieldPresent(message, pos)) {
-            writer.writeGroup(
-                number,
-                UnsafeUtil.getObject(message, offset(typeAndOffset)),
-                getMessageFieldSchema(pos));
-          }
-          break;
-        case 18: // DOUBLE_LIST:
-          SchemaUtil.writeDoubleList(
-              numberAt(pos),
-              (List<Double>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 19: // FLOAT_LIST:
-          SchemaUtil.writeFloatList(
-              numberAt(pos),
-              (List<Float>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 20: // INT64_LIST:
-          SchemaUtil.writeInt64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 21: // UINT64_LIST:
-          SchemaUtil.writeUInt64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 22: // INT32_LIST:
-          SchemaUtil.writeInt32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 23: // FIXED64_LIST:
-          SchemaUtil.writeFixed64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 24: // FIXED32_LIST:
-          SchemaUtil.writeFixed32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 25: // BOOL_LIST:
-          SchemaUtil.writeBoolList(
-              numberAt(pos),
-              (List<Boolean>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 26: // STRING_LIST:
-          SchemaUtil.writeStringList(
-              numberAt(pos),
-              (List<String>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer);
-          break;
-        case 27: // MESSAGE_LIST:
-          SchemaUtil.writeMessageList(
-              numberAt(pos),
-              (List<?>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              getMessageFieldSchema(pos));
-          break;
-        case 28: // BYTES_LIST:
-          SchemaUtil.writeBytesList(
-              numberAt(pos),
-              (List<ByteString>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer);
-          break;
-        case 29: // UINT32_LIST:
-          SchemaUtil.writeUInt32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 30: // ENUM_LIST:
-          SchemaUtil.writeEnumList(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 31: // SFIXED32_LIST:
-          SchemaUtil.writeSFixed32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 32: // SFIXED64_LIST:
-          SchemaUtil.writeSFixed64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 33: // SINT32_LIST:
-          SchemaUtil.writeSInt32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 34: // SINT64_LIST:
-          SchemaUtil.writeSInt64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              false);
-          break;
-        case 35: // DOUBLE_LIST_PACKED:
-          SchemaUtil.writeDoubleList(
-              numberAt(pos),
-              (List<Double>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 36: // FLOAT_LIST_PACKED:
-          SchemaUtil.writeFloatList(
-              numberAt(pos),
-              (List<Float>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 37: // INT64_LIST_PACKED:
-          SchemaUtil.writeInt64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 38: // UINT64_LIST_PACKED:
-          SchemaUtil.writeUInt64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 39: // INT32_LIST_PACKED:
-          SchemaUtil.writeInt32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 40: // FIXED64_LIST_PACKED:
-          SchemaUtil.writeFixed64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 41: // FIXED32_LIST_PACKED:
-          SchemaUtil.writeFixed32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-
-          break;
-        case 42: // BOOL_LIST_PACKED:
-          SchemaUtil.writeBoolList(
-              numberAt(pos),
-              (List<Boolean>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 43: // UINT32_LIST_PACKED:
-          SchemaUtil.writeUInt32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 44: // ENUM_LIST_PACKED:
-          SchemaUtil.writeEnumList(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 45: // SFIXED32_LIST_PACKED:
-          SchemaUtil.writeSFixed32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 46: // SFIXED64_LIST_PACKED:
-          SchemaUtil.writeSFixed64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 47: // SINT32_LIST_PACKED:
-          SchemaUtil.writeSInt32List(
-              numberAt(pos),
-              (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 48: // SINT64_LIST_PACKED:
-          SchemaUtil.writeSInt64List(
-              numberAt(pos),
-              (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              true);
-          break;
-        case 49: // GROUP_LIST:
-          SchemaUtil.writeGroupList(
-              numberAt(pos),
-              (List<?>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
-              writer,
-              getMessageFieldSchema(pos));
-          break;
-        case 50: // MAP:
-          // TODO(dweis): Use schema cache.
-          writeMapHelper(writer, number, UnsafeUtil.getObject(message, offset(typeAndOffset)), pos);
-          break;
-        case 51: // ONEOF_DOUBLE:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeDouble(number, oneofDoubleAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 52: // ONEOF_FLOAT:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeFloat(number, oneofFloatAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 53: // ONEOF_INT64:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeInt64(number, oneofLongAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 54: // ONEOF_UINT64:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeUInt64(number, oneofLongAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 55: // ONEOF_INT32:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeInt32(number, oneofIntAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 56: // ONEOF_FIXED64:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeFixed64(number, oneofLongAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 57: // ONEOF_FIXED32:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeFixed32(number, oneofIntAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 58: // ONEOF_BOOL:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeBool(number, oneofBooleanAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 59: // ONEOF_STRING:
-          if (isOneofPresent(message, number, pos)) {
-            writeString(number, UnsafeUtil.getObject(message, offset(typeAndOffset)), writer);
-          }
-          break;
-        case 60: // ONEOF_MESSAGE:
-          if (isOneofPresent(message, number, pos)) {
-            Object value = UnsafeUtil.getObject(message, offset(typeAndOffset));
-            writer.writeMessage(number, value, getMessageFieldSchema(pos));
-          }
-          break;
-        case 61: // ONEOF_BYTES:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeBytes(
-                number, (ByteString) UnsafeUtil.getObject(message, offset(typeAndOffset)));
-          }
-          break;
-        case 62: // ONEOF_UINT32:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeUInt32(number, oneofIntAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 63: // ONEOF_ENUM:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeEnum(number, oneofIntAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 64: // ONEOF_SFIXED32:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeSFixed32(number, oneofIntAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 65: // ONEOF_SFIXED64:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeSFixed64(number, oneofLongAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 66: // ONEOF_SINT32:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeSInt32(number, oneofIntAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 67: // ONEOF_SINT64:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeSInt64(number, oneofLongAt(message, offset(typeAndOffset)));
-          }
-          break;
-        case 68: // ONEOF_GROUP:
-          if (isOneofPresent(message, number, pos)) {
-            writer.writeGroup(
-                number,
-                UnsafeUtil.getObject(message, offset(typeAndOffset)),
-                getMessageFieldSchema(pos));
-          }
-          break;
-        default:
-          break;
-      }
-    }
-    while (nextExtension != null) {
-      extensionSchema.serializeExtension(writer, nextExtension);
-      nextExtension = extensionIterator.hasNext() ? extensionIterator.next() : null;
-    }
-  }
-
-  @SuppressWarnings("unchecked")
-  private <K, V> void writeMapHelper(Writer writer, int number, Object mapField, int pos)
-      throws IOException {
-    if (mapField != null) {
-      writer.writeMap(
-          number,
-          (MapEntryLite.Metadata<K, V>) mapFieldSchema.forMapMetadata(getMapFieldDefaultEntry(pos)),
-          (Map<K, V>) mapFieldSchema.forMapData(mapField));
-    }
-  }
-
-  private <UT, UB> void writeUnknownInMessageTo(
-      UnknownFieldSchema<UT, UB> schema, T message, Writer writer) throws IOException {
-    schema.writeTo(schema.getFromMessage(message), writer);
-  }
-
-  @Override
-  public void mergeFrom(T message, Reader reader, ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    if (extensionRegistry == null) {
-      throw new NullPointerException();
-    }
-    mergeFromHelper(unknownFieldSchema, extensionSchema, message, reader, extensionRegistry);
-  }
-
-  /**
-   * A helper method for wildcard capture of {@code unknownFieldSchema}. See:
-   * https://docs.oracle.com/javase/tutorial/java/generics/capture.html
-   */
-  private <UT, UB, ET extends FieldDescriptorLite<ET>> void mergeFromHelper(
-      UnknownFieldSchema<UT, UB> unknownFieldSchema,
-      ExtensionSchema<ET> extensionSchema,
-      T message,
-      Reader reader,
-      ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    UB unknownFields = null;
-    FieldSet<ET> extensions = null;
-    try {
-      while (true) {
-        final int number = reader.getFieldNumber();
-        final int pos = positionForFieldNumber(number);
-        if (pos < 0) {
-          if (number == Reader.READ_DONE) {
-            return;
-          }
-          // Check if it's an extension.
-          Object extension =
-              !hasExtensions
-                  ? null
-                  : extensionSchema.findExtensionByNumber(
-                      extensionRegistry, defaultInstance, number);
-          if (extension != null) {
-            if (extensions == null) {
-              extensions = extensionSchema.getMutableExtensions(message);
-            }
-            unknownFields =
-                extensionSchema.parseExtension(
-                    reader,
-                    extension,
-                    extensionRegistry,
-                    extensions,
-                    unknownFields,
-                    unknownFieldSchema);
-            continue;
-          }
-          if (unknownFieldSchema.shouldDiscardUnknownFields(reader)) {
-            if (reader.skipField()) {
-              continue;
-            }
-          } else {
-            if (unknownFields == null) {
-              unknownFields = unknownFieldSchema.getBuilderFromMessage(message);
-            }
-            // Unknown field.
-            if (unknownFieldSchema.mergeOneFieldFrom(unknownFields, reader)) {
-              continue;
-            }
-          }
-          // Done reading.
-          return;
-        }
-        final int typeAndOffset = typeAndOffsetAt(pos);
-
-        try {
-          switch (type(typeAndOffset)) {
-            case 0: // DOUBLE:
-              UnsafeUtil.putDouble(message, offset(typeAndOffset), reader.readDouble());
-              setFieldPresent(message, pos);
-              break;
-            case 1: // FLOAT:
-              UnsafeUtil.putFloat(message, offset(typeAndOffset), reader.readFloat());
-              setFieldPresent(message, pos);
-              break;
-            case 2: // INT64:
-              UnsafeUtil.putLong(message, offset(typeAndOffset), reader.readInt64());
-              setFieldPresent(message, pos);
-              break;
-            case 3: // UINT64:
-              UnsafeUtil.putLong(message, offset(typeAndOffset), reader.readUInt64());
-              setFieldPresent(message, pos);
-              break;
-            case 4: // INT32:
-              UnsafeUtil.putInt(message, offset(typeAndOffset), reader.readInt32());
-              setFieldPresent(message, pos);
-              break;
-            case 5: // FIXED64:
-              UnsafeUtil.putLong(message, offset(typeAndOffset), reader.readFixed64());
-              setFieldPresent(message, pos);
-              break;
-            case 6: // FIXED32:
-              UnsafeUtil.putInt(message, offset(typeAndOffset), reader.readFixed32());
-              setFieldPresent(message, pos);
-              break;
-            case 7: // BOOL:
-              UnsafeUtil.putBoolean(message, offset(typeAndOffset), reader.readBool());
-              setFieldPresent(message, pos);
-              break;
-            case 8: // STRING:
-              readString(message, typeAndOffset, reader);
-              setFieldPresent(message, pos);
-              break;
-            case 9:
-              { // MESSAGE:
-                if (isFieldPresent(message, pos)) {
-                  Object mergedResult =
-                      Internal.mergeMessage(
-                          UnsafeUtil.getObject(message, offset(typeAndOffset)),
-                          reader.readMessageBySchemaWithCheck(
-                              (Schema<T>) getMessageFieldSchema(pos), extensionRegistry));
-                  UnsafeUtil.putObject(message, offset(typeAndOffset), mergedResult);
-                } else {
-                  UnsafeUtil.putObject(
-                      message,
-                      offset(typeAndOffset),
-                      reader.readMessageBySchemaWithCheck(
-                          (Schema<T>) getMessageFieldSchema(pos), extensionRegistry));
-                  setFieldPresent(message, pos);
-                }
-                break;
-              }
-            case 10: // BYTES:
-              UnsafeUtil.putObject(message, offset(typeAndOffset), reader.readBytes());
-              setFieldPresent(message, pos);
-              break;
-            case 11: // UINT32:
-              UnsafeUtil.putInt(message, offset(typeAndOffset), reader.readUInt32());
-              setFieldPresent(message, pos);
-              break;
-            case 12: // ENUM:
-              {
-                int enumValue = reader.readEnum();
-                EnumVerifier enumVerifier = getEnumFieldVerifier(pos);
-                if (enumVerifier == null || enumVerifier.isInRange(enumValue)) {
-                  UnsafeUtil.putInt(message, offset(typeAndOffset), enumValue);
-                  setFieldPresent(message, pos);
-                } else {
-                  unknownFields =
-                      SchemaUtil.storeUnknownEnum(
-                          number, enumValue, unknownFields, unknownFieldSchema);
-                }
-                break;
-              }
-            case 13: // SFIXED32:
-              UnsafeUtil.putInt(message, offset(typeAndOffset), reader.readSFixed32());
-              setFieldPresent(message, pos);
-              break;
-            case 14: // SFIXED64:
-              UnsafeUtil.putLong(message, offset(typeAndOffset), reader.readSFixed64());
-              setFieldPresent(message, pos);
-              break;
-            case 15: // SINT32:
-              UnsafeUtil.putInt(message, offset(typeAndOffset), reader.readSInt32());
-              setFieldPresent(message, pos);
-              break;
-            case 16: // SINT64:
-              UnsafeUtil.putLong(message, offset(typeAndOffset), reader.readSInt64());
-              setFieldPresent(message, pos);
-              break;
-            case 17:
-              { // GROUP:
-                if (isFieldPresent(message, pos)) {
-                  Object mergedResult =
-                      Internal.mergeMessage(
-                          UnsafeUtil.getObject(message, offset(typeAndOffset)),
-                          reader.readGroupBySchemaWithCheck(
-                              (Schema<T>) getMessageFieldSchema(pos), extensionRegistry));
-                  UnsafeUtil.putObject(message, offset(typeAndOffset), mergedResult);
-                } else {
-                  UnsafeUtil.putObject(
-                      message,
-                      offset(typeAndOffset),
-                      reader.readGroupBySchemaWithCheck(
-                          (Schema<T>) getMessageFieldSchema(pos), extensionRegistry));
-                  setFieldPresent(message, pos);
-                }
-                break;
-              }
-            case 18: // DOUBLE_LIST:
-              reader.readDoubleList(
-                  listFieldSchema.<Double>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 19: // FLOAT_LIST:
-              reader.readFloatList(
-                  listFieldSchema.<Float>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 20: // INT64_LIST:
-              reader.readInt64List(
-                  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 21: // UINT64_LIST:
-              reader.readUInt64List(
-                  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 22: // INT32_LIST:
-              reader.readInt32List(
-                  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 23: // FIXED64_LIST:
-              reader.readFixed64List(
-                  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 24: // FIXED32_LIST:
-              reader.readFixed32List(
-                  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 25: // BOOL_LIST:
-              reader.readBoolList(
-                  listFieldSchema.<Boolean>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 26: // STRING_LIST:
-              readStringList(message, typeAndOffset, reader);
-              break;
-            case 27:
-              { // MESSAGE_LIST:
-                readMessageList(
-                    message,
-                    typeAndOffset,
-                    reader,
-                    (Schema<T>) getMessageFieldSchema(pos),
-                    extensionRegistry);
-                break;
-              }
-            case 28: // BYTES_LIST:
-              reader.readBytesList(
-                  listFieldSchema.<ByteString>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 29: // UINT32_LIST:
-              reader.readUInt32List(
-                  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 30: // ENUM_LIST:
-              {
-                List<Integer> enumList =
-                    listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset));
-                reader.readEnumList(enumList);
-                unknownFields =
-                    SchemaUtil.filterUnknownEnumList(
-                        number,
-                        enumList,
-                        getEnumFieldVerifier(pos),
-                        unknownFields,
-                        unknownFieldSchema);
-                break;
-              }
-            case 31: // SFIXED32_LIST:
-              reader.readSFixed32List(
-                  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 32: // SFIXED64_LIST:
-              reader.readSFixed64List(
-                  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 33: // SINT32_LIST:
-              reader.readSInt32List(
-                  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 34: // SINT64_LIST:
-              reader.readSInt64List(
-                  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 35: // DOUBLE_LIST_PACKED:
-              reader.readDoubleList(
-                  listFieldSchema.<Double>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 36: // FLOAT_LIST_PACKED:
-              reader.readFloatList(
-                  listFieldSchema.<Float>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 37: // INT64_LIST_PACKED:
-              reader.readInt64List(
-                  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 38: // UINT64_LIST_PACKED:
-              reader.readUInt64List(
-                  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 39: // INT32_LIST_PACKED:
-              reader.readInt32List(
-                  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 40: // FIXED64_LIST_PACKED:
-              reader.readFixed64List(
-                  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 41: // FIXED32_LIST_PACKED:
-              reader.readFixed32List(
-                  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 42: // BOOL_LIST_PACKED:
-              reader.readBoolList(
-                  listFieldSchema.<Boolean>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 43: // UINT32_LIST_PACKED:
-              reader.readUInt32List(
-                  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 44: // ENUM_LIST_PACKED:
-              {
-                List<Integer> enumList =
-                    listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset));
-                reader.readEnumList(enumList);
-                unknownFields =
-                    SchemaUtil.filterUnknownEnumList(
-                        number,
-                        enumList,
-                        getEnumFieldVerifier(pos),
-                        unknownFields,
-                        unknownFieldSchema);
-                break;
-              }
-            case 45: // SFIXED32_LIST_PACKED:
-              reader.readSFixed32List(
-                  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 46: // SFIXED64_LIST_PACKED:
-              reader.readSFixed64List(
-                  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 47: // SINT32_LIST_PACKED:
-              reader.readSInt32List(
-                  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 48: // SINT64_LIST_PACKED:
-              reader.readSInt64List(
-                  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
-              break;
-            case 49:
-              { // GROUP_LIST:
-                readGroupList(
-                    message,
-                    offset(typeAndOffset),
-                    reader,
-                    (Schema<T>) getMessageFieldSchema(pos),
-                    extensionRegistry);
-                break;
-              }
-            case 50: // MAP:
-              mergeMap(message, pos, getMapFieldDefaultEntry(pos), extensionRegistry, reader);
-              break;
-            case 51: // ONEOF_DOUBLE:
-              UnsafeUtil.putObject(
-                  message, offset(typeAndOffset), Double.valueOf(reader.readDouble()));
-              setOneofPresent(message, number, pos);
-              break;
-            case 52: // ONEOF_FLOAT:
-              UnsafeUtil.putObject(
-                  message, offset(typeAndOffset), Float.valueOf(reader.readFloat()));
-              setOneofPresent(message, number, pos);
-              break;
-            case 53: // ONEOF_INT64:
-              UnsafeUtil.putObject(
-                  message, offset(typeAndOffset), Long.valueOf(reader.readInt64()));
-              setOneofPresent(message, number, pos);
-              break;
-            case 54: // ONEOF_UINT64:
-              UnsafeUtil.putObject(
-                  message, offset(typeAndOffset), Long.valueOf(reader.readUInt64()));
-              setOneofPresent(message, number, pos);
-              break;
-            case 55: // ONEOF_INT32:
-              UnsafeUtil.putObject(
-                  message, offset(typeAndOffset), Integer.valueOf(reader.readInt32()));
-              setOneofPresent(message, number, pos);
-              break;
-            case 56: // ONEOF_FIXED64:
-              UnsafeUtil.putObject(
-                  message, offset(typeAndOffset), Long.valueOf(reader.readFixed64()));
-              setOneofPresent(message, number, pos);
-              break;
-            case 57: // ONEOF_FIXED32:
-              UnsafeUtil.putObject(
-                  message, offset(typeAndOffset), Integer.valueOf(reader.readFixed32()));
-              setOneofPresent(message, number, pos);
-              break;
-            case 58: // ONEOF_BOOL:
-              UnsafeUtil.putObject(
-                  message, offset(typeAndOffset), Boolean.valueOf(reader.readBool()));
-              setOneofPresent(message, number, pos);
-              break;
-            case 59: // ONEOF_STRING:
-              readString(message, typeAndOffset, reader);
-              setOneofPresent(message, number, pos);
-              break;
-            case 60: // ONEOF_MESSAGE:
-              if (isOneofPresent(message, number, pos)) {
-                Object mergedResult =
-                    Internal.mergeMessage(
-                        UnsafeUtil.getObject(message, offset(typeAndOffset)),
-                        reader.readMessageBySchemaWithCheck(
-                            getMessageFieldSchema(pos), extensionRegistry));
-                UnsafeUtil.putObject(message, offset(typeAndOffset), mergedResult);
-              } else {
-                UnsafeUtil.putObject(
-                    message,
-                    offset(typeAndOffset),
-                    reader.readMessageBySchemaWithCheck(
-                        getMessageFieldSchema(pos), extensionRegistry));
-                setFieldPresent(message, pos);
-              }
-              setOneofPresent(message, number, pos);
-              break;
-            case 61: // ONEOF_BYTES:
-              UnsafeUtil.putObject(message, offset(typeAndOffset), reader.readBytes());
-              setOneofPresent(message, number, pos);
-              break;
-            case 62: // ONEOF_UINT32:
-              UnsafeUtil.putObject(
-                  message, offset(typeAndOffset), Integer.valueOf(reader.readUInt32()));
-              setOneofPresent(message, number, pos);
-              break;
-            case 63: // ONEOF_ENUM:
-              {
-                int enumValue = reader.readEnum();
-                EnumVerifier enumVerifier = getEnumFieldVerifier(pos);
-                if (enumVerifier == null || enumVerifier.isInRange(enumValue)) {
-                  UnsafeUtil.putObject(message, offset(typeAndOffset), enumValue);
-                  setOneofPresent(message, number, pos);
-                } else {
-                  unknownFields =
-                      SchemaUtil.storeUnknownEnum(
-                          number, enumValue, unknownFields, unknownFieldSchema);
-                }
-                break;
-              }
-            case 64: // ONEOF_SFIXED32:
-              UnsafeUtil.putObject(
-                  message, offset(typeAndOffset), Integer.valueOf(reader.readSFixed32()));
-              setOneofPresent(message, number, pos);
-              break;
-            case 65: // ONEOF_SFIXED64:
-              UnsafeUtil.putObject(
-                  message, offset(typeAndOffset), Long.valueOf(reader.readSFixed64()));
-              setOneofPresent(message, number, pos);
-              break;
-            case 66: // ONEOF_SINT32:
-              UnsafeUtil.putObject(
-                  message, offset(typeAndOffset), Integer.valueOf(reader.readSInt32()));
-              setOneofPresent(message, number, pos);
-              break;
-            case 67: // ONEOF_SINT64:
-              UnsafeUtil.putObject(
-                  message, offset(typeAndOffset), Long.valueOf(reader.readSInt64()));
-              setOneofPresent(message, number, pos);
-              break;
-            case 68: // ONEOF_GROUP:
-              UnsafeUtil.putObject(
-                  message,
-                  offset(typeAndOffset),
-                  reader.readGroupBySchemaWithCheck(getMessageFieldSchema(pos), extensionRegistry));
-              setOneofPresent(message, number, pos);
-              break;
-            default:
-              // Assume we've landed on an empty entry. Treat it as an unknown field.
-              if (unknownFields == null) {
-                unknownFields = unknownFieldSchema.newBuilder();
-              }
-              if (!unknownFieldSchema.mergeOneFieldFrom(unknownFields, reader)) {
-                return;
-              }
-              break;
-          }
-        } catch (InvalidProtocolBufferException.InvalidWireTypeException e) {
-          // Treat fields with an invalid wire type as unknown fields
-          // (i.e. same as the default case).
-          if (unknownFieldSchema.shouldDiscardUnknownFields(reader)) {
-            if (!reader.skipField()) {
-              return;
-            }
-          } else {
-            if (unknownFields == null) {
-              unknownFields = unknownFieldSchema.getBuilderFromMessage(message);
-            }
-            if (!unknownFieldSchema.mergeOneFieldFrom(unknownFields, reader)) {
-              return;
-            }
-          }
-        }
-      }
-    } finally {
-      for (int i = checkInitializedCount; i < repeatedFieldOffsetStart; i++) {
-        unknownFields =
-            filterMapUnknownEnumValues(message, intArray[i], unknownFields, unknownFieldSchema);
-      }
-      if (unknownFields != null) {
-        unknownFieldSchema.setBuilderToMessage(message, unknownFields);
-      }
-    }
-  }
-
-  @SuppressWarnings("ReferenceEquality")
-  static UnknownFieldSetLite getMutableUnknownFields(Object message) {
-    UnknownFieldSetLite unknownFields = ((GeneratedMessageLite) message).unknownFields;
-    if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
-      unknownFields = UnknownFieldSetLite.newInstance();
-      ((GeneratedMessageLite) message).unknownFields = unknownFields;
-    }
-    return unknownFields;
-  }
-
-  /** Decodes a map entry key or value. Stores result in registers.object1. */
-  private int decodeMapEntryValue(
-      byte[] data,
-      int position,
-      int limit,
-      WireFormat.FieldType fieldType,
-      Class<?> messageType,
-      Registers registers)
-      throws IOException {
-    switch (fieldType) {
-      case BOOL:
-        position = decodeVarint64(data, position, registers);
-        registers.object1 = registers.long1 != 0;
-        break;
-      case BYTES:
-        position = decodeBytes(data, position, registers);
-        break;
-      case DOUBLE:
-        registers.object1 = decodeDouble(data, position);
-        position += 8;
-        break;
-      case FIXED32:
-      case SFIXED32:
-        registers.object1 = decodeFixed32(data, position);
-        position += 4;
-        break;
-      case FIXED64:
-      case SFIXED64:
-        registers.object1 = decodeFixed64(data, position);
-        position += 8;
-        break;
-      case FLOAT:
-        registers.object1 = decodeFloat(data, position);
-        position += 4;
-        break;
-      case ENUM:
-      case INT32:
-      case UINT32:
-        position = decodeVarint32(data, position, registers);
-        registers.object1 = registers.int1;
-        break;
-      case INT64:
-      case UINT64:
-        position = decodeVarint64(data, position, registers);
-        registers.object1 = registers.long1;
-        break;
-      case MESSAGE:
-        position =
-            decodeMessageField(
-                Protobuf.getInstance().schemaFor(messageType), data, position, limit, registers);
-        break;
-      case SINT32:
-        position = decodeVarint32(data, position, registers);
-        registers.object1 = CodedInputStream.decodeZigZag32(registers.int1);
-        break;
-      case SINT64:
-        position = decodeVarint64(data, position, registers);
-        registers.object1 = CodedInputStream.decodeZigZag64(registers.long1);
-        break;
-      case STRING:
-        position = decodeStringRequireUtf8(data, position, registers);
-        break;
-      default:
-        throw new RuntimeException("unsupported field type.");
-    }
-    return position;
-  }
-
-  /** Decodes a map entry. */
-  private <K, V> int decodeMapEntry(
-      byte[] data,
-      int position,
-      int limit,
-      MapEntryLite.Metadata<K, V> metadata,
-      Map<K, V> target,
-      Registers registers)
-      throws IOException {
-    position = decodeVarint32(data, position, registers);
-    final int length = registers.int1;
-    if (length < 0 || length > limit - position) {
-      throw InvalidProtocolBufferException.truncatedMessage();
-    }
-    final int end = position + length;
-    K key = metadata.defaultKey;
-    V value = metadata.defaultValue;
-    while (position < end) {
-      int tag = data[position++];
-      if (tag < 0) {
-        position = decodeVarint32(tag, data, position, registers);
-        tag = registers.int1;
-      }
-      final int fieldNumber = tag >>> 3;
-      final int wireType = tag & 0x7;
-      switch (fieldNumber) {
-        case 1:
-          if (wireType == metadata.keyType.getWireType()) {
-            position =
-                decodeMapEntryValue(data, position, limit, metadata.keyType, null, registers);
-            key = (K) registers.object1;
-            continue;
-          }
-          break;
-        case 2:
-          if (wireType == metadata.valueType.getWireType()) {
-            position =
-                decodeMapEntryValue(
-                    data,
-                    position,
-                    limit,
-                    metadata.valueType,
-                    metadata.defaultValue.getClass(),
-                    registers);
-            value = (V) registers.object1;
-            continue;
-          }
-          break;
-        default:
-          break;
-      }
-      position = skipField(tag, data, position, limit, registers);
-    }
-    if (position != end) {
-      throw InvalidProtocolBufferException.parseFailure();
-    }
-    target.put(key, value);
-    return end;
-  }
-
-  @SuppressWarnings("ReferenceEquality")
-  private int parseRepeatedField(
-      T message,
-      byte[] data,
-      int position,
-      int limit,
-      int tag,
-      int number,
-      int wireType,
-      int bufferPosition,
-      long typeAndOffset,
-      int fieldType,
-      long fieldOffset,
-      Registers registers)
-      throws IOException {
-    ProtobufList<?> list = (ProtobufList<?>) UNSAFE.getObject(message, fieldOffset);
-    if (!list.isModifiable()) {
-      final int size = list.size();
-      list =
-          list.mutableCopyWithCapacity(
-              size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
-      UNSAFE.putObject(message, fieldOffset, list);
-    }
-    switch (fieldType) {
-      case 18: // DOUBLE_LIST:
-      case 35: // DOUBLE_LIST_PACKED:
-        if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-          position = decodePackedDoubleList(data, position, list, registers);
-        } else if (wireType == WireFormat.WIRETYPE_FIXED64) {
-          position = decodeDoubleList(tag, data, position, limit, list, registers);
-        }
-        break;
-      case 19: // FLOAT_LIST:
-      case 36: // FLOAT_LIST_PACKED:
-        if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-          position = decodePackedFloatList(data, position, list, registers);
-        } else if (wireType == WireFormat.WIRETYPE_FIXED32) {
-          position = decodeFloatList(tag, data, position, limit, list, registers);
-        }
-        break;
-      case 20: // INT64_LIST:
-      case 21: // UINT64_LIST:
-      case 37: // INT64_LIST_PACKED:
-      case 38: // UINT64_LIST_PACKED:
-        if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-          position = decodePackedVarint64List(data, position, list, registers);
-        } else if (wireType == WireFormat.WIRETYPE_VARINT) {
-          position = decodeVarint64List(tag, data, position, limit, list, registers);
-        }
-        break;
-      case 22: // INT32_LIST:
-      case 29: // UINT32_LIST:
-      case 39: // INT32_LIST_PACKED:
-      case 43: // UINT32_LIST_PACKED:
-        if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-          position = decodePackedVarint32List(data, position, list, registers);
-        } else if (wireType == WireFormat.WIRETYPE_VARINT) {
-          position = decodeVarint32List(tag, data, position, limit, list, registers);
-        }
-        break;
-      case 23: // FIXED64_LIST:
-      case 32: // SFIXED64_LIST:
-      case 40: // FIXED64_LIST_PACKED:
-      case 46: // SFIXED64_LIST_PACKED:
-        if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-          position = decodePackedFixed64List(data, position, list, registers);
-        } else if (wireType == WireFormat.WIRETYPE_FIXED64) {
-          position = decodeFixed64List(tag, data, position, limit, list, registers);
-        }
-        break;
-      case 24: // FIXED32_LIST:
-      case 31: // SFIXED32_LIST:
-      case 41: // FIXED32_LIST_PACKED:
-      case 45: // SFIXED32_LIST_PACKED:
-        if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-          position = decodePackedFixed32List(data, position, list, registers);
-        } else if (wireType == WireFormat.WIRETYPE_FIXED32) {
-          position = decodeFixed32List(tag, data, position, limit, list, registers);
-        }
-        break;
-      case 25: // BOOL_LIST:
-      case 42: // BOOL_LIST_PACKED:
-        if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-          position = decodePackedBoolList(data, position, list, registers);
-        } else if (wireType == WireFormat.WIRETYPE_VARINT) {
-          position = decodeBoolList(tag, data, position, limit, list, registers);
-        }
-        break;
-      case 26: // STRING_LIST:
-        if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-          if ((typeAndOffset & ENFORCE_UTF8_MASK) == 0) {
-            position = decodeStringList(tag, data, position, limit, list, registers);
-          } else {
-            position = decodeStringListRequireUtf8(tag, data, position, limit, list, registers);
-          }
-        }
-        break;
-      case 27: // MESSAGE_LIST:
-        if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-          position =
-              decodeMessageList(
-                  getMessageFieldSchema(bufferPosition),
-                  tag,
-                  data,
-                  position,
-                  limit,
-                  list,
-                  registers);
-        }
-        break;
-      case 28: // BYTES_LIST:
-        if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-          position = decodeBytesList(tag, data, position, limit, list, registers);
-        }
-        break;
-      case 30: // ENUM_LIST:
-      case 44: // ENUM_LIST_PACKED:
-        if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-          position = decodePackedVarint32List(data, position, list, registers);
-        } else if (wireType == WireFormat.WIRETYPE_VARINT) {
-          position = decodeVarint32List(tag, data, position, limit, list, registers);
-        } else {
-          break;
-        }
-        UnknownFieldSetLite unknownFields = ((GeneratedMessageLite) message).unknownFields;
-        if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
-          // filterUnknownEnumList() expects the unknownFields parameter to be mutable or null.
-          // Since we don't know yet whether there exist unknown enum values, we'd better pass
-          // null to it instead of allocating a mutable instance. This is also needed to be
-          // consistent with the behavior of generated parser/builder.
-          unknownFields = null;
-        }
-        unknownFields =
-            SchemaUtil.filterUnknownEnumList(
-                number,
-                (ProtobufList<Integer>) list,
-                getEnumFieldVerifier(bufferPosition),
-                unknownFields,
-                (UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite>) unknownFieldSchema);
-        if (unknownFields != null) {
-          ((GeneratedMessageLite) message).unknownFields = unknownFields;
-        }
-        break;
-      case 33: // SINT32_LIST:
-      case 47: // SINT32_LIST_PACKED:
-        if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-          position = decodePackedSInt32List(data, position, list, registers);
-        } else if (wireType == WireFormat.WIRETYPE_VARINT) {
-          position = decodeSInt32List(tag, data, position, limit, list, registers);
-        }
-        break;
-      case 34: // SINT64_LIST:
-      case 48: // SINT64_LIST_PACKED:
-        if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-          position = decodePackedSInt64List(data, position, list, registers);
-        } else if (wireType == WireFormat.WIRETYPE_VARINT) {
-          position = decodeSInt64List(tag, data, position, limit, list, registers);
-        }
-        break;
-      case 49: // GROUP_LIST:
-        if (wireType == WireFormat.WIRETYPE_START_GROUP) {
-          position =
-              decodeGroupList(
-                  getMessageFieldSchema(bufferPosition),
-                  tag,
-                  data,
-                  position,
-                  limit,
-                  list,
-                  registers);
-        }
-        break;
-      default:
-        break;
-    }
-    return position;
-  }
-
-  private <K, V> int parseMapField(
-      T message,
-      byte[] data,
-      int position,
-      int limit,
-      int bufferPosition,
-      long fieldOffset,
-      Registers registers)
-      throws IOException {
-    final sun.misc.Unsafe unsafe = UNSAFE;
-    Object mapDefaultEntry = getMapFieldDefaultEntry(bufferPosition);
-    Object mapField = unsafe.getObject(message, fieldOffset);
-    if (mapFieldSchema.isImmutable(mapField)) {
-      Object oldMapField = mapField;
-      mapField = mapFieldSchema.newMapField(mapDefaultEntry);
-      mapFieldSchema.mergeFrom(mapField, oldMapField);
-      unsafe.putObject(message, fieldOffset, mapField);
-    }
-    return decodeMapEntry(
-        data,
-        position,
-        limit,
-        (Metadata<K, V>) mapFieldSchema.forMapMetadata(mapDefaultEntry),
-        (Map<K, V>) mapFieldSchema.forMutableMapData(mapField),
-        registers);
-  }
-
-  private int parseOneofField(
-      T message,
-      byte[] data,
-      int position,
-      int limit,
-      int tag,
-      int number,
-      int wireType,
-      int typeAndOffset,
-      int fieldType,
-      long fieldOffset,
-      int bufferPosition,
-      Registers registers)
-      throws IOException {
-    final sun.misc.Unsafe unsafe = UNSAFE;
-    final long oneofCaseOffset = buffer[bufferPosition + 2] & OFFSET_MASK;
-    switch (fieldType) {
-      case 51: // ONEOF_DOUBLE:
-        if (wireType == WireFormat.WIRETYPE_FIXED64) {
-          unsafe.putObject(message, fieldOffset, decodeDouble(data, position));
-          position += 8;
-          unsafe.putInt(message, oneofCaseOffset, number);
-        }
-        break;
-      case 52: // ONEOF_FLOAT:
-        if (wireType == WireFormat.WIRETYPE_FIXED32) {
-          unsafe.putObject(message, fieldOffset, decodeFloat(data, position));
-          position += 4;
-          unsafe.putInt(message, oneofCaseOffset, number);
-        }
-        break;
-      case 53: // ONEOF_INT64:
-      case 54: // ONEOF_UINT64:
-        if (wireType == WireFormat.WIRETYPE_VARINT) {
-          position = decodeVarint64(data, position, registers);
-          unsafe.putObject(message, fieldOffset, registers.long1);
-          unsafe.putInt(message, oneofCaseOffset, number);
-        }
-        break;
-      case 55: // ONEOF_INT32:
-      case 62: // ONEOF_UINT32:
-        if (wireType == WireFormat.WIRETYPE_VARINT) {
-          position = decodeVarint32(data, position, registers);
-          unsafe.putObject(message, fieldOffset, registers.int1);
-          unsafe.putInt(message, oneofCaseOffset, number);
-        }
-        break;
-      case 56: // ONEOF_FIXED64:
-      case 65: // ONEOF_SFIXED64:
-        if (wireType == WireFormat.WIRETYPE_FIXED64) {
-          unsafe.putObject(message, fieldOffset, decodeFixed64(data, position));
-          position += 8;
-          unsafe.putInt(message, oneofCaseOffset, number);
-        }
-        break;
-      case 57: // ONEOF_FIXED32:
-      case 64: // ONEOF_SFIXED32:
-        if (wireType == WireFormat.WIRETYPE_FIXED32) {
-          unsafe.putObject(message, fieldOffset, decodeFixed32(data, position));
-          position += 4;
-          unsafe.putInt(message, oneofCaseOffset, number);
-        }
-        break;
-      case 58: // ONEOF_BOOL:
-        if (wireType == WireFormat.WIRETYPE_VARINT) {
-          position = decodeVarint64(data, position, registers);
-          unsafe.putObject(message, fieldOffset, registers.long1 != 0);
-          unsafe.putInt(message, oneofCaseOffset, number);
-        }
-        break;
-      case 59: // ONEOF_STRING:
-        if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-          position = decodeVarint32(data, position, registers);
-          final int length = registers.int1;
-          if (length == 0) {
-            unsafe.putObject(message, fieldOffset, "");
-          } else {
-            if ((typeAndOffset & ENFORCE_UTF8_MASK) != 0
-                && !Utf8.isValidUtf8(data, position, position + length)) {
-              throw InvalidProtocolBufferException.invalidUtf8();
-            }
-            final String value = new String(data, position, length, Internal.UTF_8);
-            unsafe.putObject(message, fieldOffset, value);
-            position += length;
-          }
-          unsafe.putInt(message, oneofCaseOffset, number);
-        }
-        break;
-      case 60: // ONEOF_MESSAGE:
-        if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-          position =
-              decodeMessageField(
-                  getMessageFieldSchema(bufferPosition), data, position, limit, registers);
-          final Object oldValue =
-              unsafe.getInt(message, oneofCaseOffset) == number
-                  ? unsafe.getObject(message, fieldOffset)
-                  : null;
-          if (oldValue == null) {
-            unsafe.putObject(message, fieldOffset, registers.object1);
-          } else {
-            unsafe.putObject(
-                message, fieldOffset, Internal.mergeMessage(oldValue, registers.object1));
-          }
-          unsafe.putInt(message, oneofCaseOffset, number);
-        }
-        break;
-      case 61: // ONEOF_BYTES:
-        if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-          position = decodeBytes(data, position, registers);
-          unsafe.putObject(message, fieldOffset, registers.object1);
-          unsafe.putInt(message, oneofCaseOffset, number);
-        }
-        break;
-      case 63: // ONEOF_ENUM:
-        if (wireType == WireFormat.WIRETYPE_VARINT) {
-          position = decodeVarint32(data, position, registers);
-          final int enumValue = registers.int1;
-          EnumVerifier enumVerifier = getEnumFieldVerifier(bufferPosition);
-          if (enumVerifier == null || enumVerifier.isInRange(enumValue)) {
-            unsafe.putObject(message, fieldOffset, enumValue);
-            unsafe.putInt(message, oneofCaseOffset, number);
-          } else {
-            // UnknownFieldSetLite requires varint to be represented as Long.
-            getMutableUnknownFields(message).storeField(tag, (long) enumValue);
-          }
-        }
-        break;
-      case 66: // ONEOF_SINT32:
-        if (wireType == WireFormat.WIRETYPE_VARINT) {
-          position = decodeVarint32(data, position, registers);
-          unsafe.putObject(message, fieldOffset, CodedInputStream.decodeZigZag32(registers.int1));
-          unsafe.putInt(message, oneofCaseOffset, number);
-        }
-        break;
-      case 67: // ONEOF_SINT64:
-        if (wireType == WireFormat.WIRETYPE_VARINT) {
-          position = decodeVarint64(data, position, registers);
-          unsafe.putObject(message, fieldOffset, CodedInputStream.decodeZigZag64(registers.long1));
-          unsafe.putInt(message, oneofCaseOffset, number);
-        }
-        break;
-      case 68: // ONEOF_GROUP:
-        if (wireType == WireFormat.WIRETYPE_START_GROUP) {
-          final int endTag = (tag & ~0x7) | WireFormat.WIRETYPE_END_GROUP;
-          position =
-              decodeGroupField(
-                  getMessageFieldSchema(bufferPosition), data, position, limit, endTag, registers);
-          final Object oldValue =
-              unsafe.getInt(message, oneofCaseOffset) == number
-                  ? unsafe.getObject(message, fieldOffset)
-                  : null;
-          if (oldValue == null) {
-            unsafe.putObject(message, fieldOffset, registers.object1);
-          } else {
-            unsafe.putObject(
-                message, fieldOffset, Internal.mergeMessage(oldValue, registers.object1));
-          }
-          unsafe.putInt(message, oneofCaseOffset, number);
-        }
-        break;
-      default:
-        break;
-    }
-    return position;
-  }
-
-  private Schema getMessageFieldSchema(int pos) {
-    final int index = pos / INTS_PER_FIELD * 2;
-    Schema schema = (Schema) objects[index];
-    if (schema != null) {
-      return schema;
-    }
-    schema = Protobuf.getInstance().schemaFor((Class) objects[index + 1]);
-    objects[index] = schema;
-    return schema;
-  }
-
-  private Object getMapFieldDefaultEntry(int pos) {
-    return objects[pos / INTS_PER_FIELD * 2];
-  }
-
-  private EnumVerifier getEnumFieldVerifier(int pos) {
-    return (EnumVerifier) objects[pos / INTS_PER_FIELD * 2 + 1];
-  }
-
-  /**
-   * Parses a proto2 message or group and returns the position after the message/group. If it's
-   * parsing a message (endGroup == 0), returns limit if parsing is successful; It it's parsing a
-   * group (endGroup != 0), parsing ends when a tag == endGroup is encountered and the position
-   * after that tag is returned.
-   */
-  int parseProto2Message(
-      T message, byte[] data, int position, int limit, int endGroup, Registers registers)
-      throws IOException {
-    final sun.misc.Unsafe unsafe = UNSAFE;
-    int currentPresenceFieldOffset = NO_PRESENCE_SENTINEL;
-    int currentPresenceField = 0;
-    int tag = 0;
-    int oldNumber = -1;
-    int pos = 0;
-    while (position < limit) {
-      tag = data[position++];
-      if (tag < 0) {
-        position = decodeVarint32(tag, data, position, registers);
-        tag = registers.int1;
-      }
-      final int number = tag >>> 3;
-      final int wireType = tag & 0x7;
-      if (number > oldNumber) {
-        pos = positionForFieldNumber(number, pos / INTS_PER_FIELD);
-      } else {
-        pos = positionForFieldNumber(number);
-      }
-      oldNumber = number;
-      if (pos == -1) {
-        // need to reset
-        pos = 0;
-      } else {
-        final int typeAndOffset = buffer[pos + 1];
-        final int fieldType = type(typeAndOffset);
-        final long fieldOffset = offset(typeAndOffset);
-        if (fieldType <= 17) {
-          // Proto2 optional fields have has-bits.
-          final int presenceMaskAndOffset = buffer[pos + 2];
-          final int presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS);
-          final int presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK;
-          // We cache the 32-bit has-bits integer value and only write it back when parsing a field
-          // using a different has-bits integer.
-          if (presenceFieldOffset != currentPresenceFieldOffset) {
-            if (currentPresenceFieldOffset != NO_PRESENCE_SENTINEL) {
-              unsafe.putInt(message, (long) currentPresenceFieldOffset, currentPresenceField);
-            }
-            currentPresenceFieldOffset = presenceFieldOffset;
-            currentPresenceField = unsafe.getInt(message, (long) presenceFieldOffset);
-          }
-          switch (fieldType) {
-            case 0: // DOUBLE
-              if (wireType == WireFormat.WIRETYPE_FIXED64) {
-                UnsafeUtil.putDouble(message, fieldOffset, decodeDouble(data, position));
-                position += 8;
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 1: // FLOAT
-              if (wireType == WireFormat.WIRETYPE_FIXED32) {
-                UnsafeUtil.putFloat(message, fieldOffset, decodeFloat(data, position));
-                position += 4;
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 2: // INT64
-            case 3: // UINT64
-              if (wireType == WireFormat.WIRETYPE_VARINT) {
-                position = decodeVarint64(data, position, registers);
-                unsafe.putLong(message, fieldOffset, registers.long1);
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 4: // INT32
-            case 11: // UINT32
-              if (wireType == WireFormat.WIRETYPE_VARINT) {
-                position = decodeVarint32(data, position, registers);
-                unsafe.putInt(message, fieldOffset, registers.int1);
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 5: // FIXED64
-            case 14: // SFIXED64
-              if (wireType == WireFormat.WIRETYPE_FIXED64) {
-                unsafe.putLong(message, fieldOffset, decodeFixed64(data, position));
-                position += 8;
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 6: // FIXED32
-            case 13: // SFIXED32
-              if (wireType == WireFormat.WIRETYPE_FIXED32) {
-                unsafe.putInt(message, fieldOffset, decodeFixed32(data, position));
-                position += 4;
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 7: // BOOL
-              if (wireType == WireFormat.WIRETYPE_VARINT) {
-                position = decodeVarint64(data, position, registers);
-                UnsafeUtil.putBoolean(message, fieldOffset, registers.long1 != 0);
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 8: // STRING
-              if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-                if ((typeAndOffset & ENFORCE_UTF8_MASK) == 0) {
-                  position = decodeString(data, position, registers);
-                } else {
-                  position = decodeStringRequireUtf8(data, position, registers);
-                }
-                unsafe.putObject(message, fieldOffset, registers.object1);
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 9: // MESSAGE
-              if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-                position =
-                    decodeMessageField(
-                        getMessageFieldSchema(pos), data, position, limit, registers);
-                if ((currentPresenceField & presenceMask) == 0) {
-                  unsafe.putObject(message, fieldOffset, registers.object1);
-                } else {
-                  unsafe.putObject(
-                      message,
-                      fieldOffset,
-                      Internal.mergeMessage(
-                          unsafe.getObject(message, fieldOffset), registers.object1));
-                }
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 10: // BYTES
-              if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-                position = decodeBytes(data, position, registers);
-                unsafe.putObject(message, fieldOffset, registers.object1);
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 12: // ENUM
-              if (wireType == WireFormat.WIRETYPE_VARINT) {
-                position = decodeVarint32(data, position, registers);
-                final int enumValue = registers.int1;
-                EnumVerifier enumVerifier = getEnumFieldVerifier(pos);
-                if (enumVerifier == null || enumVerifier.isInRange(enumValue)) {
-                  unsafe.putInt(message, fieldOffset, enumValue);
-                  currentPresenceField |= presenceMask;
-                } else {
-                  // UnknownFieldSetLite requires varint to be represented as Long.
-                  getMutableUnknownFields(message).storeField(tag, (long) enumValue);
-                }
-                continue;
-              }
-              break;
-            case 15: // SINT32
-              if (wireType == WireFormat.WIRETYPE_VARINT) {
-                position = decodeVarint32(data, position, registers);
-                unsafe.putInt(
-                    message, fieldOffset, CodedInputStream.decodeZigZag32(registers.int1));
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 16: // SINT64
-              if (wireType == WireFormat.WIRETYPE_VARINT) {
-                position = decodeVarint64(data, position, registers);
-                unsafe.putLong(
-                    message, fieldOffset, CodedInputStream.decodeZigZag64(registers.long1));
-
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 17: // GROUP
-              if (wireType == WireFormat.WIRETYPE_START_GROUP) {
-                final int endTag = (number << 3) | WireFormat.WIRETYPE_END_GROUP;
-                position =
-                    decodeGroupField(
-                        getMessageFieldSchema(pos), data, position, limit, endTag, registers);
-                if ((currentPresenceField & presenceMask) == 0) {
-                  unsafe.putObject(message, fieldOffset, registers.object1);
-                } else {
-                  unsafe.putObject(
-                      message,
-                      fieldOffset,
-                      Internal.mergeMessage(
-                          unsafe.getObject(message, fieldOffset), registers.object1));
-                }
-
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            default:
-              break;
-          }
-        } else if (fieldType == 27) {
-          // Handle repeated message fields.
-          if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-            ProtobufList<?> list = (ProtobufList<?>) unsafe.getObject(message, fieldOffset);
-            if (!list.isModifiable()) {
-              final int size = list.size();
-              list =
-                  list.mutableCopyWithCapacity(
-                      size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
-              unsafe.putObject(message, fieldOffset, list);
-            }
-            position =
-                decodeMessageList(
-                    getMessageFieldSchema(pos), tag, data, position, limit, list, registers);
-            continue;
-          }
-        } else if (fieldType <= 49) {
-          // Handle all other repeated fields.
-          final int oldPosition = position;
-          position =
-              parseRepeatedField(
-                  message,
-                  data,
-                  position,
-                  limit,
-                  tag,
-                  number,
-                  wireType,
-                  pos,
-                  typeAndOffset,
-                  fieldType,
-                  fieldOffset,
-                  registers);
-          if (position != oldPosition) {
-            continue;
-          }
-        } else if (fieldType == 50) {
-          if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-            final int oldPosition = position;
-            position = parseMapField(message, data, position, limit, pos, fieldOffset, registers);
-            if (position != oldPosition) {
-              continue;
-            }
-          }
-        } else {
-          final int oldPosition = position;
-          position =
-              parseOneofField(
-                  message,
-                  data,
-                  position,
-                  limit,
-                  tag,
-                  number,
-                  wireType,
-                  typeAndOffset,
-                  fieldType,
-                  fieldOffset,
-                  pos,
-                  registers);
-          if (position != oldPosition) {
-            continue;
-          }
-        }
-      }
-      if (tag == endGroup && endGroup != 0) {
-        break;
-      }
-
-      if (hasExtensions
-          && registers.extensionRegistry != ExtensionRegistryLite.getEmptyRegistry()) {
-        position = decodeExtensionOrUnknownField(
-            tag, data, position, limit, message, defaultInstance,
-            (UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite>) unknownFieldSchema,
-            registers);
-      } else {
-        position = decodeUnknownField(
-            tag, data, position, limit, getMutableUnknownFields(message), registers);
-      }
-    }
-    if (currentPresenceFieldOffset != NO_PRESENCE_SENTINEL) {
-      unsafe.putInt(message, (long) currentPresenceFieldOffset, currentPresenceField);
-    }
-    UnknownFieldSetLite unknownFields = null;
-    for (int i = checkInitializedCount; i < repeatedFieldOffsetStart; i++) {
-      unknownFields =
-          filterMapUnknownEnumValues(
-              message,
-              intArray[i],
-              unknownFields,
-              (UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite>) unknownFieldSchema);
-    }
-    if (unknownFields != null) {
-      ((UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite>) unknownFieldSchema)
-          .setBuilderToMessage(message, unknownFields);
-    }
-    if (endGroup == 0) {
-      if (position != limit) {
-        throw InvalidProtocolBufferException.parseFailure();
-      }
-    } else {
-      if (position > limit || tag != endGroup) {
-        throw InvalidProtocolBufferException.parseFailure();
-      }
-    }
-    return position;
-  }
-
-  /** Parses a proto3 message and returns the limit if parsing is successful. */
-  private int parseProto3Message(
-      T message, byte[] data, int position, int limit, Registers registers) throws IOException {
-    final sun.misc.Unsafe unsafe = UNSAFE;
-    int currentPresenceFieldOffset = NO_PRESENCE_SENTINEL;
-    int currentPresenceField = 0;
-    int tag = 0;
-    int oldNumber = -1;
-    int pos = 0;
-    while (position < limit) {
-      tag = data[position++];
-      if (tag < 0) {
-        position = decodeVarint32(tag, data, position, registers);
-        tag = registers.int1;
-      }
-      final int number = tag >>> 3;
-      final int wireType = tag & 0x7;
-      if (number > oldNumber) {
-        pos = positionForFieldNumber(number, pos / INTS_PER_FIELD);
-      } else {
-        pos = positionForFieldNumber(number);
-      }
-      oldNumber = number;
-      if (pos == -1) {
-        // need to reset
-        pos = 0;
-      } else {
-        final int typeAndOffset = buffer[pos + 1];
-        final int fieldType = type(typeAndOffset);
-        final long fieldOffset = offset(typeAndOffset);
-        if (fieldType <= 17) {
-          // Proto3 optional fields have has-bits.
-          final int presenceMaskAndOffset = buffer[pos + 2];
-          final int presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS);
-          final int presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK;
-          // We cache the 32-bit has-bits integer value and only write it back when parsing a field
-          // using a different has-bits integer.
-          //
-          // Note that for fields that do not have hasbits, we unconditionally write and discard
-          // the data.
-          if (presenceFieldOffset != currentPresenceFieldOffset) {
-            if (currentPresenceFieldOffset != NO_PRESENCE_SENTINEL) {
-              unsafe.putInt(message, (long) currentPresenceFieldOffset, currentPresenceField);
-            }
-            if (presenceFieldOffset != NO_PRESENCE_SENTINEL) {
-              currentPresenceField = unsafe.getInt(message, (long) presenceFieldOffset);
-            }
-            currentPresenceFieldOffset = presenceFieldOffset;
-          }
-          switch (fieldType) {
-            case 0: // DOUBLE:
-              if (wireType == WireFormat.WIRETYPE_FIXED64) {
-                UnsafeUtil.putDouble(message, fieldOffset, decodeDouble(data, position));
-                position += 8;
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 1: // FLOAT:
-              if (wireType == WireFormat.WIRETYPE_FIXED32) {
-                UnsafeUtil.putFloat(message, fieldOffset, decodeFloat(data, position));
-                position += 4;
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 2: // INT64:
-            case 3: // UINT64:
-              if (wireType == WireFormat.WIRETYPE_VARINT) {
-                position = decodeVarint64(data, position, registers);
-                unsafe.putLong(message, fieldOffset, registers.long1);
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 4: // INT32:
-            case 11: // UINT32:
-              if (wireType == WireFormat.WIRETYPE_VARINT) {
-                position = decodeVarint32(data, position, registers);
-                unsafe.putInt(message, fieldOffset, registers.int1);
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 5: // FIXED64:
-            case 14: // SFIXED64:
-              if (wireType == WireFormat.WIRETYPE_FIXED64) {
-                unsafe.putLong(message, fieldOffset, decodeFixed64(data, position));
-                position += 8;
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 6: // FIXED32:
-            case 13: // SFIXED32:
-              if (wireType == WireFormat.WIRETYPE_FIXED32) {
-                unsafe.putInt(message, fieldOffset, decodeFixed32(data, position));
-                position += 4;
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 7: // BOOL:
-              if (wireType == WireFormat.WIRETYPE_VARINT) {
-                position = decodeVarint64(data, position, registers);
-                UnsafeUtil.putBoolean(message, fieldOffset, registers.long1 != 0);
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 8: // STRING:
-              if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-                if ((typeAndOffset & ENFORCE_UTF8_MASK) == 0) {
-                  position = decodeString(data, position, registers);
-                } else {
-                  position = decodeStringRequireUtf8(data, position, registers);
-                }
-                unsafe.putObject(message, fieldOffset, registers.object1);
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 9: // MESSAGE:
-              if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-                position =
-                    decodeMessageField(
-                        getMessageFieldSchema(pos), data, position, limit, registers);
-                final Object oldValue = unsafe.getObject(message, fieldOffset);
-                if (oldValue == null) {
-                  unsafe.putObject(message, fieldOffset, registers.object1);
-                } else {
-                  unsafe.putObject(
-                      message, fieldOffset, Internal.mergeMessage(oldValue, registers.object1));
-                }
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 10: // BYTES:
-              if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-                position = decodeBytes(data, position, registers);
-                unsafe.putObject(message, fieldOffset, registers.object1);
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 12: // ENUM:
-              if (wireType == WireFormat.WIRETYPE_VARINT) {
-                position = decodeVarint32(data, position, registers);
-                unsafe.putInt(message, fieldOffset, registers.int1);
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 15: // SINT32:
-              if (wireType == WireFormat.WIRETYPE_VARINT) {
-                position = decodeVarint32(data, position, registers);
-                unsafe.putInt(
-                    message, fieldOffset, CodedInputStream.decodeZigZag32(registers.int1));
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            case 16: // SINT64:
-              if (wireType == WireFormat.WIRETYPE_VARINT) {
-                position = decodeVarint64(data, position, registers);
-                unsafe.putLong(
-                    message, fieldOffset, CodedInputStream.decodeZigZag64(registers.long1));
-                currentPresenceField |= presenceMask;
-                continue;
-              }
-              break;
-            default:
-              break;
-          }
-        } else if (fieldType == 27) {
-          // Handle repeated message field.
-          if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-            ProtobufList<?> list = (ProtobufList<?>) unsafe.getObject(message, fieldOffset);
-            if (!list.isModifiable()) {
-              final int size = list.size();
-              list =
-                  list.mutableCopyWithCapacity(
-                      size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
-              unsafe.putObject(message, fieldOffset, list);
-            }
-            position =
-                decodeMessageList(
-                    getMessageFieldSchema(pos), tag, data, position, limit, list, registers);
-            continue;
-          }
-        } else if (fieldType <= 49) {
-          // Handle all other repeated fields.
-          final int oldPosition = position;
-          position =
-              parseRepeatedField(
-                  message,
-                  data,
-                  position,
-                  limit,
-                  tag,
-                  number,
-                  wireType,
-                  pos,
-                  typeAndOffset,
-                  fieldType,
-                  fieldOffset,
-                  registers);
-          if (position != oldPosition) {
-            continue;
-          }
-        } else if (fieldType == 50) {
-          if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-            final int oldPosition = position;
-            position = parseMapField(message, data, position, limit, pos, fieldOffset, registers);
-            if (position != oldPosition) {
-              continue;
-            }
-          }
-        } else {
-          final int oldPosition = position;
-          position =
-              parseOneofField(
-                  message,
-                  data,
-                  position,
-                  limit,
-                  tag,
-                  number,
-                  wireType,
-                  typeAndOffset,
-                  fieldType,
-                  fieldOffset,
-                  pos,
-                  registers);
-          if (position != oldPosition) {
-            continue;
-          }
-        }
-      }
-      position = decodeUnknownField(
-          tag, data, position, limit, getMutableUnknownFields(message), registers);
-    }
-    if (currentPresenceFieldOffset != NO_PRESENCE_SENTINEL) {
-      unsafe.putInt(message, (long) currentPresenceFieldOffset, currentPresenceField);
-    }
-    if (position != limit) {
-      throw InvalidProtocolBufferException.parseFailure();
-    }
-    return position;
-  }
-
-  @Override
-  public void mergeFrom(T message, byte[] data, int position, int limit, Registers registers)
-      throws IOException {
-    if (proto3) {
-      parseProto3Message(message, data, position, limit, registers);
-    } else {
-      parseProto2Message(message, data, position, limit, 0, registers);
-    }
-  }
-
-  @Override
-  public void makeImmutable(T message) {
-    // Make all repeated/map fields immutable.
-    for (int i = checkInitializedCount; i < repeatedFieldOffsetStart; i++) {
-      long offset = offset(typeAndOffsetAt(intArray[i]));
-      Object mapField = UnsafeUtil.getObject(message, offset);
-      if (mapField == null) {
-        continue;
-      }
-      UnsafeUtil.putObject(message, offset, mapFieldSchema.toImmutable(mapField));
-    }
-    final int length = intArray.length;
-    for (int i = repeatedFieldOffsetStart; i < length; i++) {
-      listFieldSchema.makeImmutableListAt(message, intArray[i]);
-    }
-    unknownFieldSchema.makeImmutable(message);
-    if (hasExtensions) {
-      extensionSchema.makeImmutable(message);
-    }
-  }
-
-  @SuppressWarnings("unchecked")
-  private final <K, V> void mergeMap(
-      Object message,
-      int pos,
-      Object mapDefaultEntry,
-      ExtensionRegistryLite extensionRegistry,
-      Reader reader)
-      throws IOException {
-    long offset = offset(typeAndOffsetAt(pos));
-    Object mapField = UnsafeUtil.getObject(message, offset);
-    // TODO(xiaofeng): Consider creating separate implementations for full and lite. In lite
-    // runtime map field will never be null but here we still need to check null because the
-    // code is shared by both full and lite. It might be better if full/lite uses different
-    // schema implementations.
-    if (mapField == null) {
-      mapField = mapFieldSchema.newMapField(mapDefaultEntry);
-      UnsafeUtil.putObject(message, offset, mapField);
-    } else if (mapFieldSchema.isImmutable(mapField)) {
-      Object oldMapField = mapField;
-      mapField = mapFieldSchema.newMapField(mapDefaultEntry);
-      mapFieldSchema.mergeFrom(mapField, oldMapField);
-      UnsafeUtil.putObject(message, offset, mapField);
-    }
-    reader.readMap(
-        (Map<K, V>) mapFieldSchema.forMutableMapData(mapField),
-        (Metadata<K, V>) mapFieldSchema.forMapMetadata(mapDefaultEntry),
-        extensionRegistry);
-  }
-
-  private final <UT, UB> UB filterMapUnknownEnumValues(
-      Object message, int pos, UB unknownFields, UnknownFieldSchema<UT, UB> unknownFieldSchema) {
-    int fieldNumber = numberAt(pos);
-    long offset = offset(typeAndOffsetAt(pos));
-    Object mapField = UnsafeUtil.getObject(message, offset);
-    if (mapField == null) {
-      return unknownFields;
-    }
-    EnumVerifier enumVerifier = getEnumFieldVerifier(pos);
-    if (enumVerifier == null) {
-      return unknownFields;
-    }
-    Map<?, ?> mapData = mapFieldSchema.forMutableMapData(mapField);
-    // Filter unknown enum values.
-    unknownFields =
-        filterUnknownEnumMap(
-            pos, fieldNumber, mapData, enumVerifier, unknownFields, unknownFieldSchema);
-    return unknownFields;
-  }
-
-  @SuppressWarnings("unchecked")
-  private final <K, V, UT, UB> UB filterUnknownEnumMap(
-      int pos,
-      int number,
-      Map<K, V> mapData,
-      EnumVerifier enumVerifier,
-      UB unknownFields,
-      UnknownFieldSchema<UT, UB> unknownFieldSchema) {
-    Metadata<K, V> metadata =
-        (Metadata<K, V>) mapFieldSchema.forMapMetadata(getMapFieldDefaultEntry(pos));
-    for (Iterator<Map.Entry<K, V>> it = mapData.entrySet().iterator(); it.hasNext(); ) {
-      Map.Entry<K, V> entry = it.next();
-      if (!enumVerifier.isInRange((Integer) entry.getValue())) {
-        if (unknownFields == null) {
-          unknownFields = unknownFieldSchema.newBuilder();
-        }
-        int entrySize =
-            MapEntryLite.computeSerializedSize(metadata, entry.getKey(), entry.getValue());
-        CodedBuilder codedBuilder = ByteString.newCodedBuilder(entrySize);
-        CodedOutputStream codedOutput = codedBuilder.getCodedOutput();
-        try {
-          MapEntryLite.writeTo(codedOutput, metadata, entry.getKey(), entry.getValue());
-        } catch (IOException e) {
-          // Writing to ByteString CodedOutputStream should not throw IOException.
-          throw new RuntimeException(e);
-        }
-        unknownFieldSchema.addLengthDelimited(unknownFields, number, codedBuilder.build());
-        it.remove();
-      }
-    }
-    return unknownFields;
-  }
-
-  @Override
-  public final boolean isInitialized(T message) {
-    int currentPresenceFieldOffset = NO_PRESENCE_SENTINEL;
-    int currentPresenceField = 0;
-    for (int i = 0; i < checkInitializedCount; i++) {
-      final int pos = intArray[i];
-      final int number = numberAt(pos);
-      final int typeAndOffset = typeAndOffsetAt(pos);
-
-      int presenceMaskAndOffset = buffer[pos + 2];
-      final int presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK;
-      int presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS);
-      if (presenceFieldOffset != currentPresenceFieldOffset) {
-        currentPresenceFieldOffset = presenceFieldOffset;
-        if (currentPresenceFieldOffset != NO_PRESENCE_SENTINEL) {
-          currentPresenceField = UNSAFE.getInt(message, (long) presenceFieldOffset);
-        }
-      }
-
-      if (isRequired(typeAndOffset)) {
-        if (!isFieldPresent(
-            message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) {
-          return false;
-        }
-        // If a required message field is set but has no required fields of it's own, we still
-        // proceed and check the message is initialized. It should be fairly cheap to check these
-        // messages but is worth documenting.
-      }
-      // Check nested message and groups.
-      switch (type(typeAndOffset)) {
-        case 9: // MESSAGE
-        case 17: // GROUP
-          if (isFieldPresent(
-                  message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)
-              && !isInitialized(message, typeAndOffset, getMessageFieldSchema(pos))) {
-            return false;
-          }
-          break;
-        case 27: // MESSAGE_LIST
-        case 49: // GROUP_LIST
-          if (!isListInitialized(message, typeAndOffset, pos)) {
-            return false;
-          }
-          break;
-        case 60: // ONEOF_MESSAGE
-        case 68: // ONEOF_GROUP
-          if (isOneofPresent(message, number, pos)
-              && !isInitialized(message, typeAndOffset, getMessageFieldSchema(pos))) {
-            return false;
-          }
-          break;
-        case 50: // MAP
-          if (!isMapInitialized(message, typeAndOffset, pos)) {
-            return false;
-          }
-          break;
-        default:
-          break;
-      }
-    }
-
-    if (hasExtensions) {
-      if (!extensionSchema.getExtensions(message).isInitialized()) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-  private static boolean isInitialized(Object message, int typeAndOffset, Schema schema) {
-    Object nested = UnsafeUtil.getObject(message, offset(typeAndOffset));
-    return schema.isInitialized(nested);
-  }
-
-  private <N> boolean isListInitialized(Object message, int typeAndOffset, int pos) {
-    @SuppressWarnings("unchecked")
-    List<N> list = (List<N>) UnsafeUtil.getObject(message, offset(typeAndOffset));
-    if (list.isEmpty()) {
-      return true;
-    }
-
-    Schema schema = getMessageFieldSchema(pos);
-    for (int i = 0; i < list.size(); i++) {
-      N nested = list.get(i);
-      if (!schema.isInitialized(nested)) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  private boolean isMapInitialized(T message, int typeAndOffset, int pos) {
-    Map<?, ?> map = mapFieldSchema.forMapData(UnsafeUtil.getObject(message, offset(typeAndOffset)));
-    if (map.isEmpty()) {
-      return true;
-    }
-    Object mapDefaultEntry = getMapFieldDefaultEntry(pos);
-    MapEntryLite.Metadata<?, ?> metadata = mapFieldSchema.forMapMetadata(mapDefaultEntry);
-    if (metadata.valueType.getJavaType() != WireFormat.JavaType.MESSAGE) {
-      return true;
-    }
-    // TODO(dweis): Use schema cache.
-    Schema schema = null;
-    for (Object nested : map.values()) {
-      if (schema == null) {
-        schema = Protobuf.getInstance().schemaFor(nested.getClass());
-      }
-      if (!schema.isInitialized(nested)) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  private void writeString(int fieldNumber, Object value, Writer writer) throws IOException {
-    if (value instanceof String) {
-      writer.writeString(fieldNumber, (String) value);
-    } else {
-      writer.writeBytes(fieldNumber, (ByteString) value);
-    }
-  }
-
-  private void readString(Object message, int typeAndOffset, Reader reader) throws IOException {
-    if (isEnforceUtf8(typeAndOffset)) {
-      // Enforce valid UTF-8 on the read.
-      UnsafeUtil.putObject(message, offset(typeAndOffset), reader.readStringRequireUtf8());
-    } else if (lite) {
-      // Lite messages use String fields to store strings. Read a string but do not
-      // enforce UTF-8
-      UnsafeUtil.putObject(message, offset(typeAndOffset), reader.readString());
-    } else {
-      // Full runtime messages use Objects to store either a String or ByteString. Read
-      // the string as a ByteString and do not enforce UTF-8.
-      UnsafeUtil.putObject(message, offset(typeAndOffset), reader.readBytes());
-    }
-  }
-
-  private void readStringList(Object message, int typeAndOffset, Reader reader) throws IOException {
-    if (isEnforceUtf8(typeAndOffset)) {
-      reader.readStringListRequireUtf8(
-          listFieldSchema.<String>mutableListAt(message, offset(typeAndOffset)));
-    } else {
-      reader.readStringList(listFieldSchema.<String>mutableListAt(message, offset(typeAndOffset)));
-    }
-  }
-
-  private <E> void readMessageList(
-      Object message,
-      int typeAndOffset,
-      Reader reader,
-      Schema<E> schema,
-      ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    long offset = offset(typeAndOffset);
-    reader.readMessageList(
-        listFieldSchema.<E>mutableListAt(message, offset), schema, extensionRegistry);
-  }
-
-  private <E> void readGroupList(
-      Object message,
-      long offset,
-      Reader reader,
-      Schema<E> schema,
-      ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    reader.readGroupList(
-        listFieldSchema.<E>mutableListAt(message, offset), schema, extensionRegistry);
-  }
-
-  private int numberAt(int pos) {
-    return buffer[pos];
-  }
-
-  private int typeAndOffsetAt(int pos) {
-    return buffer[pos + 1];
-  }
-
-  private int presenceMaskAndOffsetAt(int pos) {
-    return buffer[pos + 2];
-  }
-
-  private static int type(int value) {
-    return (value & FIELD_TYPE_MASK) >>> OFFSET_BITS;
-  }
-
-  private static boolean isRequired(int value) {
-    return (value & REQUIRED_MASK) != 0;
-  }
-
-  private static boolean isEnforceUtf8(int value) {
-    return (value & ENFORCE_UTF8_MASK) != 0;
-  }
-
-  private static long offset(int value) {
-    return value & OFFSET_MASK;
-  }
-
-  private static <T> double doubleAt(T message, long offset) {
-    return UnsafeUtil.getDouble(message, offset);
-  }
-
-  private static <T> float floatAt(T message, long offset) {
-    return UnsafeUtil.getFloat(message, offset);
-  }
-
-  private static <T> int intAt(T message, long offset) {
-    return UnsafeUtil.getInt(message, offset);
-  }
-
-  private static <T> long longAt(T message, long offset) {
-    return UnsafeUtil.getLong(message, offset);
-  }
-
-  private static <T> boolean booleanAt(T message, long offset) {
-    return UnsafeUtil.getBoolean(message, offset);
-  }
-
-  private static <T> double oneofDoubleAt(T message, long offset) {
-    return ((Double) UnsafeUtil.getObject(message, offset)).doubleValue();
-  }
-
-  private static <T> float oneofFloatAt(T message, long offset) {
-    return ((Float) UnsafeUtil.getObject(message, offset)).floatValue();
-  }
-
-  private static <T> int oneofIntAt(T message, long offset) {
-    return ((Integer) UnsafeUtil.getObject(message, offset)).intValue();
-  }
-
-  private static <T> long oneofLongAt(T message, long offset) {
-    return ((Long) UnsafeUtil.getObject(message, offset)).longValue();
-  }
-
-  private static <T> boolean oneofBooleanAt(T message, long offset) {
-    return ((Boolean) UnsafeUtil.getObject(message, offset)).booleanValue();
-  }
-
-  /** Returns true the field is present in both messages, or neither. */
-  private boolean arePresentForEquals(T message, T other, int pos) {
-    return isFieldPresent(message, pos) == isFieldPresent(other, pos);
-  }
-
-  private boolean isFieldPresent(
-      T message, int pos, int presenceFieldOffset, int presenceField, int presenceMask) {
-    if (presenceFieldOffset == NO_PRESENCE_SENTINEL) {
-      return isFieldPresent(message, pos);
-    } else {
-      return (presenceField & presenceMask) != 0;
-    }
-  }
-
-  private boolean isFieldPresent(T message, int pos) {
-    final int presenceMaskAndOffset = presenceMaskAndOffsetAt(pos);
-    final long presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK;
-    if (presenceFieldOffset == NO_PRESENCE_SENTINEL) {
-      final int typeAndOffset = typeAndOffsetAt(pos);
-      final long offset = offset(typeAndOffset);
-      switch (type(typeAndOffset)) {
-        case 0: // DOUBLE:
-          return UnsafeUtil.getDouble(message, offset) != 0D;
-        case 1: // FLOAT:
-          return UnsafeUtil.getFloat(message, offset) != 0F;
-        case 2: // INT64:
-          return UnsafeUtil.getLong(message, offset) != 0L;
-        case 3: // UINT64:
-          return UnsafeUtil.getLong(message, offset) != 0L;
-        case 4: // INT32:
-          return UnsafeUtil.getInt(message, offset) != 0;
-        case 5: // FIXED64:
-          return UnsafeUtil.getLong(message, offset) != 0L;
-        case 6: // FIXED32:
-          return UnsafeUtil.getInt(message, offset) != 0;
-        case 7: // BOOL:
-          return UnsafeUtil.getBoolean(message, offset);
-        case 8: // STRING:
-          Object value = UnsafeUtil.getObject(message, offset);
-          if (value instanceof String) {
-            return !((String) value).isEmpty();
-          } else if (value instanceof ByteString) {
-            return !ByteString.EMPTY.equals(value);
-          } else {
-            throw new IllegalArgumentException();
-          }
-        case 9: // MESSAGE:
-          return UnsafeUtil.getObject(message, offset) != null;
-        case 10: // BYTES:
-          return !ByteString.EMPTY.equals(UnsafeUtil.getObject(message, offset));
-        case 11: // UINT32:
-          return UnsafeUtil.getInt(message, offset) != 0;
-        case 12: // ENUM:
-          return UnsafeUtil.getInt(message, offset) != 0;
-        case 13: // SFIXED32:
-          return UnsafeUtil.getInt(message, offset) != 0;
-        case 14: // SFIXED64:
-          return UnsafeUtil.getLong(message, offset) != 0L;
-        case 15: // SINT32:
-          return UnsafeUtil.getInt(message, offset) != 0;
-        case 16: // SINT64:
-          return UnsafeUtil.getLong(message, offset) != 0L;
-        case 17: // GROUP:
-          return UnsafeUtil.getObject(message, offset) != null;
-        default:
-          throw new IllegalArgumentException();
-      }
-    } else {
-      final int presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS);
-      return (UnsafeUtil.getInt(message, presenceMaskAndOffset & OFFSET_MASK) & presenceMask) != 0;
-    }
-  }
-
-  private void setFieldPresent(T message, int pos) {
-    int presenceMaskAndOffset = presenceMaskAndOffsetAt(pos);
-    final long presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK;
-    if (presenceFieldOffset == NO_PRESENCE_SENTINEL) {
-      return;
-    }
-    final int presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS);
-    UnsafeUtil.putInt(
-        message,
-        presenceFieldOffset,
-        UnsafeUtil.getInt(message, presenceFieldOffset) | presenceMask);
-  }
-
-  private boolean isOneofPresent(T message, int fieldNumber, int pos) {
-    int presenceMaskAndOffset = presenceMaskAndOffsetAt(pos);
-    return UnsafeUtil.getInt(message, presenceMaskAndOffset & OFFSET_MASK) == fieldNumber;
-  }
-
-  private boolean isOneofCaseEqual(T message, T other, int pos) {
-    int presenceMaskAndOffset = presenceMaskAndOffsetAt(pos);
-    return UnsafeUtil.getInt(message, presenceMaskAndOffset & OFFSET_MASK)
-        == UnsafeUtil.getInt(other, presenceMaskAndOffset & OFFSET_MASK);
-  }
-
-  private void setOneofPresent(T message, int fieldNumber, int pos) {
-    int presenceMaskAndOffset = presenceMaskAndOffsetAt(pos);
-    UnsafeUtil.putInt(message, presenceMaskAndOffset & OFFSET_MASK, fieldNumber);
-  }
-
-  private int positionForFieldNumber(final int number) {
-    if (number >= minFieldNumber && number <= maxFieldNumber) {
-      return slowPositionForFieldNumber(number, 0);
-    }
-    return -1;
-  }
-
-  private int positionForFieldNumber(final int number, final int min) {
-    if (number >= minFieldNumber && number <= maxFieldNumber) {
-      return slowPositionForFieldNumber(number, min);
-    }
-    return -1;
-  }
-
-  private int slowPositionForFieldNumber(final int number, int min) {
-    int max = buffer.length / INTS_PER_FIELD - 1;
-    while (min <= max) {
-      // Find the midpoint address.
-      final int mid = (max + min) >>> 1;
-      final int pos = mid * INTS_PER_FIELD;
-      final int midFieldNumber = numberAt(pos);
-      if (number == midFieldNumber) {
-        // Found the field.
-        return pos;
-      }
-      if (number < midFieldNumber) {
-        // Search the lower half.
-        max = mid - 1;
-      } else {
-        // Search the upper half.
-        min = mid + 1;
-      }
-    }
-    return -1;
-  }
-
-  int getSchemaSize() {
-    return buffer.length * 3;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageSetSchema.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageSetSchema.java
deleted file mode 100644
index 187dc8b..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MessageSetSchema.java
+++ /dev/null
@@ -1,392 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.Map.Entry;
-
-/** Schema used for proto2 messages using message_set_wireformat. */
-final class MessageSetSchema<T> implements Schema<T> {
-  private final MessageLite defaultInstance;
-  private final UnknownFieldSchema<?, ?> unknownFieldSchema;
-  private final boolean hasExtensions;
-  private final ExtensionSchema<?> extensionSchema;
-
-  private MessageSetSchema(
-      UnknownFieldSchema<?, ?> unknownFieldSchema,
-      ExtensionSchema<?> extensionSchema,
-      MessageLite defaultInstance) {
-    this.unknownFieldSchema = unknownFieldSchema;
-    this.hasExtensions = extensionSchema.hasExtensions(defaultInstance);
-    this.extensionSchema = extensionSchema;
-    this.defaultInstance = defaultInstance;
-  }
-
-  static <T> MessageSetSchema<T> newSchema(
-      UnknownFieldSchema<?, ?> unknownFieldSchema,
-      ExtensionSchema<?> extensionSchema,
-      MessageLite defaultInstance) {
-    return new MessageSetSchema<T>(unknownFieldSchema, extensionSchema, defaultInstance);
-  }
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public T newInstance() {
-    return (T) defaultInstance.newBuilderForType().buildPartial();
-  }
-
-  @Override
-  public boolean equals(T message, T other) {
-    Object messageUnknown = unknownFieldSchema.getFromMessage(message);
-    Object otherUnknown = unknownFieldSchema.getFromMessage(other);
-    if (!messageUnknown.equals(otherUnknown)) {
-      return false;
-    }
-    if (hasExtensions) {
-      FieldSet<?> messageExtensions = extensionSchema.getExtensions(message);
-      FieldSet<?> otherExtensions = extensionSchema.getExtensions(other);
-      return messageExtensions.equals(otherExtensions);
-    }
-    return true;
-  }
-
-  @Override
-  public int hashCode(T message) {
-    int hashCode = unknownFieldSchema.getFromMessage(message).hashCode();
-    if (hasExtensions) {
-      FieldSet<?> extensions = extensionSchema.getExtensions(message);
-      hashCode = (hashCode * 53) + extensions.hashCode();
-    }
-    return hashCode;
-  }
-
-  @Override
-  public void mergeFrom(T message, T other) {
-    SchemaUtil.mergeUnknownFields(unknownFieldSchema, message, other);
-    if (hasExtensions) {
-      SchemaUtil.mergeExtensions(extensionSchema, message, other);
-    }
-  }
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public void writeTo(T message, Writer writer) throws IOException {
-    FieldSet<?> extensions = extensionSchema.getExtensions(message);
-    Iterator<?> iterator = extensions.iterator();
-    while (iterator.hasNext()) {
-      Entry<?, ?> extension = (Entry<?, ?>) iterator.next();
-      FieldSet.FieldDescriptorLite<?> fd = (FieldSet.FieldDescriptorLite<?>) extension.getKey();
-      if (fd.getLiteJavaType() != WireFormat.JavaType.MESSAGE || fd.isRepeated() || fd.isPacked()) {
-        throw new IllegalStateException("Found invalid MessageSet item.");
-      }
-      if (extension instanceof LazyField.LazyEntry) {
-        writer.writeMessageSetItem(
-            fd.getNumber(), ((LazyField.LazyEntry) extension).getField().toByteString());
-      } else {
-        writer.writeMessageSetItem(fd.getNumber(), extension.getValue());
-      }
-    }
-    writeUnknownFieldsHelper(unknownFieldSchema, message, writer);
-  }
-
-  /**
-   * A helper method for wildcard capture of {@code unknownFieldSchema}. See:
-   * https://docs.oracle.com/javase/tutorial/java/generics/capture.html
-   */
-  private <UT, UB> void writeUnknownFieldsHelper(
-      UnknownFieldSchema<UT, UB> unknownFieldSchema, T message, Writer writer) throws IOException {
-    unknownFieldSchema.writeAsMessageSetTo(unknownFieldSchema.getFromMessage(message), writer);
-  }
-
-  @SuppressWarnings("ReferenceEquality")
-  @Override
-  public void mergeFrom(
-      T message, byte[] data, int position, int limit, ArrayDecoders.Registers registers)
-      throws IOException {
-    UnknownFieldSetLite unknownFields = ((GeneratedMessageLite) message).unknownFields;
-    if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
-      unknownFields = UnknownFieldSetLite.newInstance();
-      ((GeneratedMessageLite) message).unknownFields = unknownFields;
-    }
-    final FieldSet<GeneratedMessageLite.ExtensionDescriptor> extensions =
-        ((GeneratedMessageLite.ExtendableMessage<?, ?>) message).ensureExtensionsAreMutable();
-    GeneratedMessageLite.GeneratedExtension<?, ?> extension = null;
-    while (position < limit) {
-      position = ArrayDecoders.decodeVarint32(data, position, registers);
-      final int startTag = registers.int1;
-      if (startTag != WireFormat.MESSAGE_SET_ITEM_TAG) {
-        if (WireFormat.getTagWireType(startTag) == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-          extension =
-              (GeneratedMessageLite.GeneratedExtension<?, ?>) extensionSchema.findExtensionByNumber(
-                  registers.extensionRegistry, defaultInstance,
-                  WireFormat.getTagFieldNumber(startTag));
-          if (extension != null) {
-            position =
-                ArrayDecoders.decodeMessageField(
-                    Protobuf.getInstance().schemaFor(
-                        extension.getMessageDefaultInstance().getClass()),
-                    data, position, limit, registers);
-            extensions.setField(extension.descriptor, registers.object1);
-          } else {
-            position =
-                ArrayDecoders.decodeUnknownField(
-                    startTag, data, position, limit, unknownFields, registers);
-          }
-        } else {
-          position = ArrayDecoders.skipField(startTag, data, position, limit, registers);
-        }
-        continue;
-      }
-
-      int typeId = 0;
-      ByteString rawBytes = null;
-
-      while (position < limit) {
-        position = ArrayDecoders.decodeVarint32(data, position, registers);
-        final int tag = registers.int1;
-        final int number = WireFormat.getTagFieldNumber(tag);
-        final int wireType = WireFormat.getTagWireType(tag);
-        switch (number) {
-          case WireFormat.MESSAGE_SET_TYPE_ID:
-            if (wireType == WireFormat.WIRETYPE_VARINT) {
-              position = ArrayDecoders.decodeVarint32(data, position, registers);
-              typeId = registers.int1;
-              extension =
-                  (GeneratedMessageLite.GeneratedExtension<?, ?>) extensionSchema
-                      .findExtensionByNumber(registers.extensionRegistry, defaultInstance, typeId);
-              continue;
-            }
-            break;
-          case WireFormat.MESSAGE_SET_MESSAGE:
-            if (extension != null) {
-              position = ArrayDecoders.decodeMessageField(
-                  Protobuf.getInstance().schemaFor(
-                      extension.getMessageDefaultInstance().getClass()),
-                  data, position, limit, registers);
-              extensions.setField(extension.descriptor, registers.object1);
-              continue;
-            } else {
-              if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-                position = ArrayDecoders.decodeBytes(data, position, registers);
-                rawBytes = (ByteString) registers.object1;
-                continue;
-              }
-              break;
-            }
-          default:
-            break;
-        }
-        if (tag == WireFormat.MESSAGE_SET_ITEM_END_TAG) {
-          break;
-        }
-        position = ArrayDecoders.skipField(tag, data, position, limit, registers);
-      }
-
-      if (rawBytes != null) {
-        unknownFields.storeField(
-            WireFormat.makeTag(typeId, WireFormat.WIRETYPE_LENGTH_DELIMITED), rawBytes);
-      }
-    }
-    if (position != limit) {
-      throw InvalidProtocolBufferException.parseFailure();
-    }
-  }
-
-  @Override
-  public void mergeFrom(T message, Reader reader, ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    mergeFromHelper(unknownFieldSchema, extensionSchema, message, reader, extensionRegistry);
-  }
-
-  /**
-   * A helper method for wildcard capture of {@code unknownFieldSchema}. See:
-   * https://docs.oracle.com/javase/tutorial/java/generics/capture.html
-   */
-  @SuppressWarnings("unchecked")
-  private <UT, UB, ET extends FieldSet.FieldDescriptorLite<ET>> void mergeFromHelper(
-      UnknownFieldSchema<UT, UB> unknownFieldSchema,
-      ExtensionSchema<ET> extensionSchema,
-      T message,
-      Reader reader,
-      ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    UB unknownFields = unknownFieldSchema.getBuilderFromMessage(message);
-    FieldSet<ET> extensions = extensionSchema.getMutableExtensions(message);
-    try {
-      while (true) {
-        final int number = reader.getFieldNumber();
-        if (number == Reader.READ_DONE) {
-          return;
-        }
-        if (parseMessageSetItemOrUnknownField(
-            reader,
-            extensionRegistry,
-            extensionSchema,
-            extensions,
-            unknownFieldSchema,
-            unknownFields)) {
-          continue;
-        }
-        // Done reading.
-        return;
-      }
-    } finally {
-      unknownFieldSchema.setBuilderToMessage(message, unknownFields);
-    }
-  }
-
-  @Override
-  public void makeImmutable(T message) {
-    unknownFieldSchema.makeImmutable(message);
-    extensionSchema.makeImmutable(message);
-  }
-
-  private <UT, UB, ET extends FieldSet.FieldDescriptorLite<ET>>
-      boolean parseMessageSetItemOrUnknownField(
-          Reader reader,
-          ExtensionRegistryLite extensionRegistry,
-          ExtensionSchema<ET> extensionSchema,
-          FieldSet<ET> extensions,
-          UnknownFieldSchema<UT, UB> unknownFieldSchema,
-          UB unknownFields)
-          throws IOException {
-    int startTag = reader.getTag();
-    if (startTag != WireFormat.MESSAGE_SET_ITEM_TAG) {
-      if (WireFormat.getTagWireType(startTag) == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
-        Object extension =
-            extensionSchema.findExtensionByNumber(
-                extensionRegistry, defaultInstance, WireFormat.getTagFieldNumber(startTag));
-        if (extension != null) {
-          extensionSchema.parseLengthPrefixedMessageSetItem(
-              reader, extension, extensionRegistry, extensions);
-          return true;
-        } else {
-          return unknownFieldSchema.mergeOneFieldFrom(unknownFields, reader);
-        }
-      } else {
-        return reader.skipField();
-      }
-    }
-
-    // The wire format for MessageSet is:
-    //   message MessageSet {
-    //     repeated group Item = 1 {
-    //       required int32 typeId = 2;
-    //       required bytes message = 3;
-    //     }
-    //   }
-    // "typeId" is the extension's field number.  The extension can only be
-    // a message type, where "message" contains the encoded bytes of that
-    // message.
-    //
-    // In practice, we will probably never see a MessageSet item in which
-    // the message appears before the type ID, or where either field does not
-    // appear exactly once.  However, in theory such cases are valid, so we
-    // should be prepared to accept them.
-
-    int typeId = 0;
-    ByteString rawBytes = null; // If we encounter "message" before "typeId"
-    Object extension = null;
-
-    // Read bytes from input, if we get it's type first then parse it eagerly,
-    // otherwise we store the raw bytes in a local variable.
-    loop:
-    while (true) {
-      final int number = reader.getFieldNumber();
-      if (number == Reader.READ_DONE) {
-        break;
-      }
-
-      final int tag = reader.getTag();
-      if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) {
-        typeId = reader.readUInt32();
-        extension =
-            extensionSchema.findExtensionByNumber(extensionRegistry, defaultInstance, typeId);
-        continue;
-      } else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) {
-        if (extension != null) {
-          extensionSchema.parseLengthPrefixedMessageSetItem(
-              reader, extension, extensionRegistry, extensions);
-          continue;
-        }
-        // We haven't seen a type ID yet or we want parse message lazily.
-        rawBytes = reader.readBytes();
-        continue;
-      } else {
-        if (!reader.skipField()) {
-          break loop; // End of group
-        }
-      }
-    }
-
-    if (reader.getTag() != WireFormat.MESSAGE_SET_ITEM_END_TAG) {
-      throw InvalidProtocolBufferException.invalidEndTag();
-    }
-
-    // If there are any rawBytes left, it means the message content appears before the type ID.
-    if (rawBytes != null) {
-      if (extension != null) { // We known the type
-        // TODO(xiaofeng): Instead of reading into a temporary ByteString, maybe there is a way
-        // to read directly from Reader to the submessage?
-        extensionSchema.parseMessageSetItem(rawBytes, extension, extensionRegistry, extensions);
-      } else {
-        unknownFieldSchema.addLengthDelimited(unknownFields, typeId, rawBytes);
-      }
-    }
-    return true;
-  }
-
-  @Override
-  public final boolean isInitialized(T message) {
-    FieldSet<?> extensions = extensionSchema.getExtensions(message);
-    return extensions.isInitialized();
-  }
-
-  @Override
-  public int getSerializedSize(T message) {
-    int size = 0;
-
-    size += getUnknownFieldsSerializedSize(unknownFieldSchema, message);
-
-    if (hasExtensions) {
-      size += extensionSchema.getExtensions(message).getMessageSetSerializedSize();
-    }
-
-    return size;
-  }
-
-  private <UT, UB> int getUnknownFieldsSerializedSize(
-      UnknownFieldSchema<UT, UB> schema, T message) {
-    UT unknowns = schema.getFromMessage(message);
-    return schema.getSerializedSizeAsMessageSet(unknowns);
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Method.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Method.java
deleted file mode 100644
index 8320af6..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Method.java
+++ /dev/null
@@ -1,1184 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/api.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * Method represents a method of an API interface.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.Method}
- */
-public  final class Method extends
-    com.google.protobuf.GeneratedMessageLite<
-        Method, Method.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.Method)
-    MethodOrBuilder {
-  private Method() {
-    name_ = "";
-    requestTypeUrl_ = "";
-    responseTypeUrl_ = "";
-    options_ = emptyProtobufList();
-  }
-  public static final int NAME_FIELD_NUMBER = 1;
-  private java.lang.String name_;
-  /**
-   * <pre>
-   * The simple name of this method.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The name.
-   */
-  @java.lang.Override
-  public java.lang.String getName() {
-    return name_;
-  }
-  /**
-   * <pre>
-   * The simple name of this method.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The bytes for name.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getNameBytes() {
-    return com.google.protobuf.ByteString.copyFromUtf8(name_);
-  }
-  /**
-   * <pre>
-   * The simple name of this method.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @param value The name to set.
-   */
-  private void setName(
-      java.lang.String value) {
-    value.getClass();
-  
-    name_ = value;
-  }
-  /**
-   * <pre>
-   * The simple name of this method.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   */
-  private void clearName() {
-    
-    name_ = getDefaultInstance().getName();
-  }
-  /**
-   * <pre>
-   * The simple name of this method.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @param value The bytes for name to set.
-   */
-  private void setNameBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    name_ = value.toStringUtf8();
-    
-  }
-
-  public static final int REQUEST_TYPE_URL_FIELD_NUMBER = 2;
-  private java.lang.String requestTypeUrl_;
-  /**
-   * <pre>
-   * A URL of the input message type.
-   * </pre>
-   *
-   * <code>string request_type_url = 2;</code>
-   * @return The requestTypeUrl.
-   */
-  @java.lang.Override
-  public java.lang.String getRequestTypeUrl() {
-    return requestTypeUrl_;
-  }
-  /**
-   * <pre>
-   * A URL of the input message type.
-   * </pre>
-   *
-   * <code>string request_type_url = 2;</code>
-   * @return The bytes for requestTypeUrl.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getRequestTypeUrlBytes() {
-    return com.google.protobuf.ByteString.copyFromUtf8(requestTypeUrl_);
-  }
-  /**
-   * <pre>
-   * A URL of the input message type.
-   * </pre>
-   *
-   * <code>string request_type_url = 2;</code>
-   * @param value The requestTypeUrl to set.
-   */
-  private void setRequestTypeUrl(
-      java.lang.String value) {
-    value.getClass();
-  
-    requestTypeUrl_ = value;
-  }
-  /**
-   * <pre>
-   * A URL of the input message type.
-   * </pre>
-   *
-   * <code>string request_type_url = 2;</code>
-   */
-  private void clearRequestTypeUrl() {
-    
-    requestTypeUrl_ = getDefaultInstance().getRequestTypeUrl();
-  }
-  /**
-   * <pre>
-   * A URL of the input message type.
-   * </pre>
-   *
-   * <code>string request_type_url = 2;</code>
-   * @param value The bytes for requestTypeUrl to set.
-   */
-  private void setRequestTypeUrlBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    requestTypeUrl_ = value.toStringUtf8();
-    
-  }
-
-  public static final int REQUEST_STREAMING_FIELD_NUMBER = 3;
-  private boolean requestStreaming_;
-  /**
-   * <pre>
-   * If true, the request is streamed.
-   * </pre>
-   *
-   * <code>bool request_streaming = 3;</code>
-   * @return The requestStreaming.
-   */
-  @java.lang.Override
-  public boolean getRequestStreaming() {
-    return requestStreaming_;
-  }
-  /**
-   * <pre>
-   * If true, the request is streamed.
-   * </pre>
-   *
-   * <code>bool request_streaming = 3;</code>
-   * @param value The requestStreaming to set.
-   */
-  private void setRequestStreaming(boolean value) {
-    
-    requestStreaming_ = value;
-  }
-  /**
-   * <pre>
-   * If true, the request is streamed.
-   * </pre>
-   *
-   * <code>bool request_streaming = 3;</code>
-   */
-  private void clearRequestStreaming() {
-    
-    requestStreaming_ = false;
-  }
-
-  public static final int RESPONSE_TYPE_URL_FIELD_NUMBER = 4;
-  private java.lang.String responseTypeUrl_;
-  /**
-   * <pre>
-   * The URL of the output message type.
-   * </pre>
-   *
-   * <code>string response_type_url = 4;</code>
-   * @return The responseTypeUrl.
-   */
-  @java.lang.Override
-  public java.lang.String getResponseTypeUrl() {
-    return responseTypeUrl_;
-  }
-  /**
-   * <pre>
-   * The URL of the output message type.
-   * </pre>
-   *
-   * <code>string response_type_url = 4;</code>
-   * @return The bytes for responseTypeUrl.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getResponseTypeUrlBytes() {
-    return com.google.protobuf.ByteString.copyFromUtf8(responseTypeUrl_);
-  }
-  /**
-   * <pre>
-   * The URL of the output message type.
-   * </pre>
-   *
-   * <code>string response_type_url = 4;</code>
-   * @param value The responseTypeUrl to set.
-   */
-  private void setResponseTypeUrl(
-      java.lang.String value) {
-    value.getClass();
-  
-    responseTypeUrl_ = value;
-  }
-  /**
-   * <pre>
-   * The URL of the output message type.
-   * </pre>
-   *
-   * <code>string response_type_url = 4;</code>
-   */
-  private void clearResponseTypeUrl() {
-    
-    responseTypeUrl_ = getDefaultInstance().getResponseTypeUrl();
-  }
-  /**
-   * <pre>
-   * The URL of the output message type.
-   * </pre>
-   *
-   * <code>string response_type_url = 4;</code>
-   * @param value The bytes for responseTypeUrl to set.
-   */
-  private void setResponseTypeUrlBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    responseTypeUrl_ = value.toStringUtf8();
-    
-  }
-
-  public static final int RESPONSE_STREAMING_FIELD_NUMBER = 5;
-  private boolean responseStreaming_;
-  /**
-   * <pre>
-   * If true, the response is streamed.
-   * </pre>
-   *
-   * <code>bool response_streaming = 5;</code>
-   * @return The responseStreaming.
-   */
-  @java.lang.Override
-  public boolean getResponseStreaming() {
-    return responseStreaming_;
-  }
-  /**
-   * <pre>
-   * If true, the response is streamed.
-   * </pre>
-   *
-   * <code>bool response_streaming = 5;</code>
-   * @param value The responseStreaming to set.
-   */
-  private void setResponseStreaming(boolean value) {
-    
-    responseStreaming_ = value;
-  }
-  /**
-   * <pre>
-   * If true, the response is streamed.
-   * </pre>
-   *
-   * <code>bool response_streaming = 5;</code>
-   */
-  private void clearResponseStreaming() {
-    
-    responseStreaming_ = false;
-  }
-
-  public static final int OPTIONS_FIELD_NUMBER = 6;
-  private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Option> options_;
-  /**
-   * <pre>
-   * Any metadata attached to the method.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 6;</code>
-   */
-  @java.lang.Override
-  public java.util.List<com.google.protobuf.Option> getOptionsList() {
-    return options_;
-  }
-  /**
-   * <pre>
-   * Any metadata attached to the method.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 6;</code>
-   */
-  public java.util.List<? extends com.google.protobuf.OptionOrBuilder> 
-      getOptionsOrBuilderList() {
-    return options_;
-  }
-  /**
-   * <pre>
-   * Any metadata attached to the method.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 6;</code>
-   */
-  @java.lang.Override
-  public int getOptionsCount() {
-    return options_.size();
-  }
-  /**
-   * <pre>
-   * Any metadata attached to the method.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 6;</code>
-   */
-  @java.lang.Override
-  public com.google.protobuf.Option getOptions(int index) {
-    return options_.get(index);
-  }
-  /**
-   * <pre>
-   * Any metadata attached to the method.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 6;</code>
-   */
-  public com.google.protobuf.OptionOrBuilder getOptionsOrBuilder(
-      int index) {
-    return options_.get(index);
-  }
-  private void ensureOptionsIsMutable() {
-    com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Option> tmp = options_;
-    if (!tmp.isModifiable()) {
-      options_ =
-          com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-     }
-  }
-
-  /**
-   * <pre>
-   * Any metadata attached to the method.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 6;</code>
-   */
-  private void setOptions(
-      int index, com.google.protobuf.Option value) {
-    value.getClass();
-  ensureOptionsIsMutable();
-    options_.set(index, value);
-  }
-  /**
-   * <pre>
-   * Any metadata attached to the method.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 6;</code>
-   */
-  private void addOptions(com.google.protobuf.Option value) {
-    value.getClass();
-  ensureOptionsIsMutable();
-    options_.add(value);
-  }
-  /**
-   * <pre>
-   * Any metadata attached to the method.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 6;</code>
-   */
-  private void addOptions(
-      int index, com.google.protobuf.Option value) {
-    value.getClass();
-  ensureOptionsIsMutable();
-    options_.add(index, value);
-  }
-  /**
-   * <pre>
-   * Any metadata attached to the method.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 6;</code>
-   */
-  private void addAllOptions(
-      java.lang.Iterable<? extends com.google.protobuf.Option> values) {
-    ensureOptionsIsMutable();
-    com.google.protobuf.AbstractMessageLite.addAll(
-        values, options_);
-  }
-  /**
-   * <pre>
-   * Any metadata attached to the method.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 6;</code>
-   */
-  private void clearOptions() {
-    options_ = emptyProtobufList();
-  }
-  /**
-   * <pre>
-   * Any metadata attached to the method.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 6;</code>
-   */
-  private void removeOptions(int index) {
-    ensureOptionsIsMutable();
-    options_.remove(index);
-  }
-
-  public static final int SYNTAX_FIELD_NUMBER = 7;
-  private int syntax_;
-  /**
-   * <pre>
-   * The source syntax of this method.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 7;</code>
-   * @return The enum numeric value on the wire for syntax.
-   */
-  @java.lang.Override
-  public int getSyntaxValue() {
-    return syntax_;
-  }
-  /**
-   * <pre>
-   * The source syntax of this method.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 7;</code>
-   * @return The syntax.
-   */
-  @java.lang.Override
-  public com.google.protobuf.Syntax getSyntax() {
-    com.google.protobuf.Syntax result = com.google.protobuf.Syntax.forNumber(syntax_);
-    return result == null ? com.google.protobuf.Syntax.UNRECOGNIZED : result;
-  }
-  /**
-   * <pre>
-   * The source syntax of this method.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 7;</code>
-   * @param value The enum numeric value on the wire for syntax to set.
-   */
-  private void setSyntaxValue(int value) {
-      syntax_ = value;
-  }
-  /**
-   * <pre>
-   * The source syntax of this method.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 7;</code>
-   * @param value The syntax to set.
-   */
-  private void setSyntax(com.google.protobuf.Syntax value) {
-    syntax_ = value.getNumber();
-    
-  }
-  /**
-   * <pre>
-   * The source syntax of this method.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 7;</code>
-   */
-  private void clearSyntax() {
-    
-    syntax_ = 0;
-  }
-
-  public static com.google.protobuf.Method parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Method parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Method parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Method parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Method parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Method parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Method parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Method parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Method parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Method parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Method parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Method parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.Method prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * Method represents a method of an API interface.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.Method}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.Method, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.Method)
-      com.google.protobuf.MethodOrBuilder {
-    // Construct using com.google.protobuf.Method.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * The simple name of this method.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return The name.
-     */
-    @java.lang.Override
-    public java.lang.String getName() {
-      return instance.getName();
-    }
-    /**
-     * <pre>
-     * The simple name of this method.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return The bytes for name.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getNameBytes() {
-      return instance.getNameBytes();
-    }
-    /**
-     * <pre>
-     * The simple name of this method.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @param value The name to set.
-     * @return This builder for chaining.
-     */
-    public Builder setName(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.setName(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The simple name of this method.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearName() {
-      copyOnWrite();
-      instance.clearName();
-      return this;
-    }
-    /**
-     * <pre>
-     * The simple name of this method.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @param value The bytes for name to set.
-     * @return This builder for chaining.
-     */
-    public Builder setNameBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setNameBytes(value);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * A URL of the input message type.
-     * </pre>
-     *
-     * <code>string request_type_url = 2;</code>
-     * @return The requestTypeUrl.
-     */
-    @java.lang.Override
-    public java.lang.String getRequestTypeUrl() {
-      return instance.getRequestTypeUrl();
-    }
-    /**
-     * <pre>
-     * A URL of the input message type.
-     * </pre>
-     *
-     * <code>string request_type_url = 2;</code>
-     * @return The bytes for requestTypeUrl.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getRequestTypeUrlBytes() {
-      return instance.getRequestTypeUrlBytes();
-    }
-    /**
-     * <pre>
-     * A URL of the input message type.
-     * </pre>
-     *
-     * <code>string request_type_url = 2;</code>
-     * @param value The requestTypeUrl to set.
-     * @return This builder for chaining.
-     */
-    public Builder setRequestTypeUrl(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.setRequestTypeUrl(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * A URL of the input message type.
-     * </pre>
-     *
-     * <code>string request_type_url = 2;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearRequestTypeUrl() {
-      copyOnWrite();
-      instance.clearRequestTypeUrl();
-      return this;
-    }
-    /**
-     * <pre>
-     * A URL of the input message type.
-     * </pre>
-     *
-     * <code>string request_type_url = 2;</code>
-     * @param value The bytes for requestTypeUrl to set.
-     * @return This builder for chaining.
-     */
-    public Builder setRequestTypeUrlBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setRequestTypeUrlBytes(value);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * If true, the request is streamed.
-     * </pre>
-     *
-     * <code>bool request_streaming = 3;</code>
-     * @return The requestStreaming.
-     */
-    @java.lang.Override
-    public boolean getRequestStreaming() {
-      return instance.getRequestStreaming();
-    }
-    /**
-     * <pre>
-     * If true, the request is streamed.
-     * </pre>
-     *
-     * <code>bool request_streaming = 3;</code>
-     * @param value The requestStreaming to set.
-     * @return This builder for chaining.
-     */
-    public Builder setRequestStreaming(boolean value) {
-      copyOnWrite();
-      instance.setRequestStreaming(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * If true, the request is streamed.
-     * </pre>
-     *
-     * <code>bool request_streaming = 3;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearRequestStreaming() {
-      copyOnWrite();
-      instance.clearRequestStreaming();
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The URL of the output message type.
-     * </pre>
-     *
-     * <code>string response_type_url = 4;</code>
-     * @return The responseTypeUrl.
-     */
-    @java.lang.Override
-    public java.lang.String getResponseTypeUrl() {
-      return instance.getResponseTypeUrl();
-    }
-    /**
-     * <pre>
-     * The URL of the output message type.
-     * </pre>
-     *
-     * <code>string response_type_url = 4;</code>
-     * @return The bytes for responseTypeUrl.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getResponseTypeUrlBytes() {
-      return instance.getResponseTypeUrlBytes();
-    }
-    /**
-     * <pre>
-     * The URL of the output message type.
-     * </pre>
-     *
-     * <code>string response_type_url = 4;</code>
-     * @param value The responseTypeUrl to set.
-     * @return This builder for chaining.
-     */
-    public Builder setResponseTypeUrl(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.setResponseTypeUrl(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The URL of the output message type.
-     * </pre>
-     *
-     * <code>string response_type_url = 4;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearResponseTypeUrl() {
-      copyOnWrite();
-      instance.clearResponseTypeUrl();
-      return this;
-    }
-    /**
-     * <pre>
-     * The URL of the output message type.
-     * </pre>
-     *
-     * <code>string response_type_url = 4;</code>
-     * @param value The bytes for responseTypeUrl to set.
-     * @return This builder for chaining.
-     */
-    public Builder setResponseTypeUrlBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setResponseTypeUrlBytes(value);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * If true, the response is streamed.
-     * </pre>
-     *
-     * <code>bool response_streaming = 5;</code>
-     * @return The responseStreaming.
-     */
-    @java.lang.Override
-    public boolean getResponseStreaming() {
-      return instance.getResponseStreaming();
-    }
-    /**
-     * <pre>
-     * If true, the response is streamed.
-     * </pre>
-     *
-     * <code>bool response_streaming = 5;</code>
-     * @param value The responseStreaming to set.
-     * @return This builder for chaining.
-     */
-    public Builder setResponseStreaming(boolean value) {
-      copyOnWrite();
-      instance.setResponseStreaming(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * If true, the response is streamed.
-     * </pre>
-     *
-     * <code>bool response_streaming = 5;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearResponseStreaming() {
-      copyOnWrite();
-      instance.clearResponseStreaming();
-      return this;
-    }
-
-    /**
-     * <pre>
-     * Any metadata attached to the method.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 6;</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.Option> getOptionsList() {
-      return java.util.Collections.unmodifiableList(
-          instance.getOptionsList());
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the method.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 6;</code>
-     */
-    @java.lang.Override
-    public int getOptionsCount() {
-      return instance.getOptionsCount();
-    }/**
-     * <pre>
-     * Any metadata attached to the method.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 6;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.Option getOptions(int index) {
-      return instance.getOptions(index);
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the method.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 6;</code>
-     */
-    public Builder setOptions(
-        int index, com.google.protobuf.Option value) {
-      copyOnWrite();
-      instance.setOptions(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the method.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 6;</code>
-     */
-    public Builder setOptions(
-        int index, com.google.protobuf.Option.Builder builderForValue) {
-      copyOnWrite();
-      instance.setOptions(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the method.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 6;</code>
-     */
-    public Builder addOptions(com.google.protobuf.Option value) {
-      copyOnWrite();
-      instance.addOptions(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the method.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 6;</code>
-     */
-    public Builder addOptions(
-        int index, com.google.protobuf.Option value) {
-      copyOnWrite();
-      instance.addOptions(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the method.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 6;</code>
-     */
-    public Builder addOptions(
-        com.google.protobuf.Option.Builder builderForValue) {
-      copyOnWrite();
-      instance.addOptions(builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the method.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 6;</code>
-     */
-    public Builder addOptions(
-        int index, com.google.protobuf.Option.Builder builderForValue) {
-      copyOnWrite();
-      instance.addOptions(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the method.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 6;</code>
-     */
-    public Builder addAllOptions(
-        java.lang.Iterable<? extends com.google.protobuf.Option> values) {
-      copyOnWrite();
-      instance.addAllOptions(values);
-      return this;
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the method.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 6;</code>
-     */
-    public Builder clearOptions() {
-      copyOnWrite();
-      instance.clearOptions();
-      return this;
-    }
-    /**
-     * <pre>
-     * Any metadata attached to the method.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 6;</code>
-     */
-    public Builder removeOptions(int index) {
-      copyOnWrite();
-      instance.removeOptions(index);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The source syntax of this method.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 7;</code>
-     * @return The enum numeric value on the wire for syntax.
-     */
-    @java.lang.Override
-    public int getSyntaxValue() {
-      return instance.getSyntaxValue();
-    }
-    /**
-     * <pre>
-     * The source syntax of this method.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 7;</code>
-     * @param value The syntax to set.
-     * @return This builder for chaining.
-     */
-    public Builder setSyntaxValue(int value) {
-      copyOnWrite();
-      instance.setSyntaxValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The source syntax of this method.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 7;</code>
-     * @return The syntax.
-     */
-    @java.lang.Override
-    public com.google.protobuf.Syntax getSyntax() {
-      return instance.getSyntax();
-    }
-    /**
-     * <pre>
-     * The source syntax of this method.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 7;</code>
-     * @param value The enum numeric value on the wire for syntax to set.
-     * @return This builder for chaining.
-     */
-    public Builder setSyntax(com.google.protobuf.Syntax value) {
-      copyOnWrite();
-      instance.setSyntax(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The source syntax of this method.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 7;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearSyntax() {
-      copyOnWrite();
-      instance.clearSyntax();
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.Method)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.Method();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "name_",
-            "requestTypeUrl_",
-            "requestStreaming_",
-            "responseTypeUrl_",
-            "responseStreaming_",
-            "options_",
-            com.google.protobuf.Option.class,
-            "syntax_",
-          };
-          java.lang.String info =
-              "\u0000\u0007\u0000\u0000\u0001\u0007\u0007\u0000\u0001\u0000\u0001\u0208\u0002\u0208" +
-              "\u0003\u0007\u0004\u0208\u0005\u0007\u0006\u001b\u0007\f";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.Method> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.Method.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.Method>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.Method)
-  private static final com.google.protobuf.Method DEFAULT_INSTANCE;
-  static {
-    Method defaultInstance = new Method();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      Method.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.Method getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<Method> PARSER;
-
-  public static com.google.protobuf.Parser<Method> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MethodOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/MethodOrBuilder.java
deleted file mode 100644
index 402432d..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MethodOrBuilder.java
+++ /dev/null
@@ -1,134 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/api.proto
-
-package com.google.protobuf;
-
-public interface MethodOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.Method)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * The simple name of this method.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The name.
-   */
-  java.lang.String getName();
-  /**
-   * <pre>
-   * The simple name of this method.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The bytes for name.
-   */
-  com.google.protobuf.ByteString
-      getNameBytes();
-
-  /**
-   * <pre>
-   * A URL of the input message type.
-   * </pre>
-   *
-   * <code>string request_type_url = 2;</code>
-   * @return The requestTypeUrl.
-   */
-  java.lang.String getRequestTypeUrl();
-  /**
-   * <pre>
-   * A URL of the input message type.
-   * </pre>
-   *
-   * <code>string request_type_url = 2;</code>
-   * @return The bytes for requestTypeUrl.
-   */
-  com.google.protobuf.ByteString
-      getRequestTypeUrlBytes();
-
-  /**
-   * <pre>
-   * If true, the request is streamed.
-   * </pre>
-   *
-   * <code>bool request_streaming = 3;</code>
-   * @return The requestStreaming.
-   */
-  boolean getRequestStreaming();
-
-  /**
-   * <pre>
-   * The URL of the output message type.
-   * </pre>
-   *
-   * <code>string response_type_url = 4;</code>
-   * @return The responseTypeUrl.
-   */
-  java.lang.String getResponseTypeUrl();
-  /**
-   * <pre>
-   * The URL of the output message type.
-   * </pre>
-   *
-   * <code>string response_type_url = 4;</code>
-   * @return The bytes for responseTypeUrl.
-   */
-  com.google.protobuf.ByteString
-      getResponseTypeUrlBytes();
-
-  /**
-   * <pre>
-   * If true, the response is streamed.
-   * </pre>
-   *
-   * <code>bool response_streaming = 5;</code>
-   * @return The responseStreaming.
-   */
-  boolean getResponseStreaming();
-
-  /**
-   * <pre>
-   * Any metadata attached to the method.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 6;</code>
-   */
-  java.util.List<com.google.protobuf.Option> 
-      getOptionsList();
-  /**
-   * <pre>
-   * Any metadata attached to the method.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 6;</code>
-   */
-  com.google.protobuf.Option getOptions(int index);
-  /**
-   * <pre>
-   * Any metadata attached to the method.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 6;</code>
-   */
-  int getOptionsCount();
-
-  /**
-   * <pre>
-   * The source syntax of this method.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 7;</code>
-   * @return The enum numeric value on the wire for syntax.
-   */
-  int getSyntaxValue();
-  /**
-   * <pre>
-   * The source syntax of this method.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 7;</code>
-   * @return The syntax.
-   */
-  com.google.protobuf.Syntax getSyntax();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Mixin.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Mixin.java
deleted file mode 100644
index 6a67f26..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Mixin.java
+++ /dev/null
@@ -1,600 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/api.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * Declares an API Interface to be included in this interface. The including
- * interface must redeclare all the methods from the included interface, but
- * documentation and options are inherited as follows:
- * - If after comment and whitespace stripping, the documentation
- *   string of the redeclared method is empty, it will be inherited
- *   from the original method.
- * - Each annotation belonging to the service config (http,
- *   visibility) which is not set in the redeclared method will be
- *   inherited.
- * - If an http annotation is inherited, the path pattern will be
- *   modified as follows. Any version prefix will be replaced by the
- *   version of the including interface plus the [root][] path if
- *   specified.
- * Example of a simple mixin:
- *     package google.acl.v1;
- *     service AccessControl {
- *       // Get the underlying ACL object.
- *       rpc GetAcl(GetAclRequest) returns (Acl) {
- *         option (google.api.http).get = "/v1/{resource=**}:getAcl";
- *       }
- *     }
- *     package google.storage.v2;
- *     service Storage {
- *       rpc GetAcl(GetAclRequest) returns (Acl);
- *       // Get a data record.
- *       rpc GetData(GetDataRequest) returns (Data) {
- *         option (google.api.http).get = "/v2/{resource=**}";
- *       }
- *     }
- * Example of a mixin configuration:
- *     apis:
- *     - name: google.storage.v2.Storage
- *       mixins:
- *       - name: google.acl.v1.AccessControl
- * The mixin construct implies that all methods in `AccessControl` are
- * also declared with same name and request/response types in
- * `Storage`. A documentation generator or annotation processor will
- * see the effective `Storage.GetAcl` method after inheriting
- * documentation and annotations as follows:
- *     service Storage {
- *       // Get the underlying ACL object.
- *       rpc GetAcl(GetAclRequest) returns (Acl) {
- *         option (google.api.http).get = "/v2/{resource=**}:getAcl";
- *       }
- *       ...
- *     }
- * Note how the version in the path pattern changed from `v1` to `v2`.
- * If the `root` field in the mixin is specified, it should be a
- * relative path under which inherited HTTP paths are placed. Example:
- *     apis:
- *     - name: google.storage.v2.Storage
- *       mixins:
- *       - name: google.acl.v1.AccessControl
- *         root: acls
- * This implies the following inherited HTTP annotation:
- *     service Storage {
- *       // Get the underlying ACL object.
- *       rpc GetAcl(GetAclRequest) returns (Acl) {
- *         option (google.api.http).get = "/v2/acls/{resource=**}:getAcl";
- *       }
- *       ...
- *     }
- * </pre>
- *
- * Protobuf type {@code google.protobuf.Mixin}
- */
-public  final class Mixin extends
-    com.google.protobuf.GeneratedMessageLite<
-        Mixin, Mixin.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.Mixin)
-    MixinOrBuilder {
-  private Mixin() {
-    name_ = "";
-    root_ = "";
-  }
-  public static final int NAME_FIELD_NUMBER = 1;
-  private java.lang.String name_;
-  /**
-   * <pre>
-   * The fully qualified name of the interface which is included.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The name.
-   */
-  @java.lang.Override
-  public java.lang.String getName() {
-    return name_;
-  }
-  /**
-   * <pre>
-   * The fully qualified name of the interface which is included.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The bytes for name.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getNameBytes() {
-    return com.google.protobuf.ByteString.copyFromUtf8(name_);
-  }
-  /**
-   * <pre>
-   * The fully qualified name of the interface which is included.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @param value The name to set.
-   */
-  private void setName(
-      java.lang.String value) {
-    value.getClass();
-  
-    name_ = value;
-  }
-  /**
-   * <pre>
-   * The fully qualified name of the interface which is included.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   */
-  private void clearName() {
-    
-    name_ = getDefaultInstance().getName();
-  }
-  /**
-   * <pre>
-   * The fully qualified name of the interface which is included.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @param value The bytes for name to set.
-   */
-  private void setNameBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    name_ = value.toStringUtf8();
-    
-  }
-
-  public static final int ROOT_FIELD_NUMBER = 2;
-  private java.lang.String root_;
-  /**
-   * <pre>
-   * If non-empty specifies a path under which inherited HTTP paths
-   * are rooted.
-   * </pre>
-   *
-   * <code>string root = 2;</code>
-   * @return The root.
-   */
-  @java.lang.Override
-  public java.lang.String getRoot() {
-    return root_;
-  }
-  /**
-   * <pre>
-   * If non-empty specifies a path under which inherited HTTP paths
-   * are rooted.
-   * </pre>
-   *
-   * <code>string root = 2;</code>
-   * @return The bytes for root.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getRootBytes() {
-    return com.google.protobuf.ByteString.copyFromUtf8(root_);
-  }
-  /**
-   * <pre>
-   * If non-empty specifies a path under which inherited HTTP paths
-   * are rooted.
-   * </pre>
-   *
-   * <code>string root = 2;</code>
-   * @param value The root to set.
-   */
-  private void setRoot(
-      java.lang.String value) {
-    value.getClass();
-  
-    root_ = value;
-  }
-  /**
-   * <pre>
-   * If non-empty specifies a path under which inherited HTTP paths
-   * are rooted.
-   * </pre>
-   *
-   * <code>string root = 2;</code>
-   */
-  private void clearRoot() {
-    
-    root_ = getDefaultInstance().getRoot();
-  }
-  /**
-   * <pre>
-   * If non-empty specifies a path under which inherited HTTP paths
-   * are rooted.
-   * </pre>
-   *
-   * <code>string root = 2;</code>
-   * @param value The bytes for root to set.
-   */
-  private void setRootBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    root_ = value.toStringUtf8();
-    
-  }
-
-  public static com.google.protobuf.Mixin parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Mixin parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Mixin parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Mixin parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Mixin parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Mixin parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Mixin parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Mixin parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Mixin parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Mixin parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Mixin parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Mixin parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.Mixin prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * Declares an API Interface to be included in this interface. The including
-   * interface must redeclare all the methods from the included interface, but
-   * documentation and options are inherited as follows:
-   * - If after comment and whitespace stripping, the documentation
-   *   string of the redeclared method is empty, it will be inherited
-   *   from the original method.
-   * - Each annotation belonging to the service config (http,
-   *   visibility) which is not set in the redeclared method will be
-   *   inherited.
-   * - If an http annotation is inherited, the path pattern will be
-   *   modified as follows. Any version prefix will be replaced by the
-   *   version of the including interface plus the [root][] path if
-   *   specified.
-   * Example of a simple mixin:
-   *     package google.acl.v1;
-   *     service AccessControl {
-   *       // Get the underlying ACL object.
-   *       rpc GetAcl(GetAclRequest) returns (Acl) {
-   *         option (google.api.http).get = "/v1/{resource=**}:getAcl";
-   *       }
-   *     }
-   *     package google.storage.v2;
-   *     service Storage {
-   *       rpc GetAcl(GetAclRequest) returns (Acl);
-   *       // Get a data record.
-   *       rpc GetData(GetDataRequest) returns (Data) {
-   *         option (google.api.http).get = "/v2/{resource=**}";
-   *       }
-   *     }
-   * Example of a mixin configuration:
-   *     apis:
-   *     - name: google.storage.v2.Storage
-   *       mixins:
-   *       - name: google.acl.v1.AccessControl
-   * The mixin construct implies that all methods in `AccessControl` are
-   * also declared with same name and request/response types in
-   * `Storage`. A documentation generator or annotation processor will
-   * see the effective `Storage.GetAcl` method after inheriting
-   * documentation and annotations as follows:
-   *     service Storage {
-   *       // Get the underlying ACL object.
-   *       rpc GetAcl(GetAclRequest) returns (Acl) {
-   *         option (google.api.http).get = "/v2/{resource=**}:getAcl";
-   *       }
-   *       ...
-   *     }
-   * Note how the version in the path pattern changed from `v1` to `v2`.
-   * If the `root` field in the mixin is specified, it should be a
-   * relative path under which inherited HTTP paths are placed. Example:
-   *     apis:
-   *     - name: google.storage.v2.Storage
-   *       mixins:
-   *       - name: google.acl.v1.AccessControl
-   *         root: acls
-   * This implies the following inherited HTTP annotation:
-   *     service Storage {
-   *       // Get the underlying ACL object.
-   *       rpc GetAcl(GetAclRequest) returns (Acl) {
-   *         option (google.api.http).get = "/v2/acls/{resource=**}:getAcl";
-   *       }
-   *       ...
-   *     }
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.Mixin}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.Mixin, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.Mixin)
-      com.google.protobuf.MixinOrBuilder {
-    // Construct using com.google.protobuf.Mixin.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * The fully qualified name of the interface which is included.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return The name.
-     */
-    @java.lang.Override
-    public java.lang.String getName() {
-      return instance.getName();
-    }
-    /**
-     * <pre>
-     * The fully qualified name of the interface which is included.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return The bytes for name.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getNameBytes() {
-      return instance.getNameBytes();
-    }
-    /**
-     * <pre>
-     * The fully qualified name of the interface which is included.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @param value The name to set.
-     * @return This builder for chaining.
-     */
-    public Builder setName(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.setName(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The fully qualified name of the interface which is included.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearName() {
-      copyOnWrite();
-      instance.clearName();
-      return this;
-    }
-    /**
-     * <pre>
-     * The fully qualified name of the interface which is included.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @param value The bytes for name to set.
-     * @return This builder for chaining.
-     */
-    public Builder setNameBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setNameBytes(value);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * If non-empty specifies a path under which inherited HTTP paths
-     * are rooted.
-     * </pre>
-     *
-     * <code>string root = 2;</code>
-     * @return The root.
-     */
-    @java.lang.Override
-    public java.lang.String getRoot() {
-      return instance.getRoot();
-    }
-    /**
-     * <pre>
-     * If non-empty specifies a path under which inherited HTTP paths
-     * are rooted.
-     * </pre>
-     *
-     * <code>string root = 2;</code>
-     * @return The bytes for root.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getRootBytes() {
-      return instance.getRootBytes();
-    }
-    /**
-     * <pre>
-     * If non-empty specifies a path under which inherited HTTP paths
-     * are rooted.
-     * </pre>
-     *
-     * <code>string root = 2;</code>
-     * @param value The root to set.
-     * @return This builder for chaining.
-     */
-    public Builder setRoot(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.setRoot(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * If non-empty specifies a path under which inherited HTTP paths
-     * are rooted.
-     * </pre>
-     *
-     * <code>string root = 2;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearRoot() {
-      copyOnWrite();
-      instance.clearRoot();
-      return this;
-    }
-    /**
-     * <pre>
-     * If non-empty specifies a path under which inherited HTTP paths
-     * are rooted.
-     * </pre>
-     *
-     * <code>string root = 2;</code>
-     * @param value The bytes for root to set.
-     * @return This builder for chaining.
-     */
-    public Builder setRootBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setRootBytes(value);
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.Mixin)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.Mixin();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "name_",
-            "root_",
-          };
-          java.lang.String info =
-              "\u0000\u0002\u0000\u0000\u0001\u0002\u0002\u0000\u0000\u0000\u0001\u0208\u0002\u0208" +
-              "";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.Mixin> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.Mixin.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.Mixin>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.Mixin)
-  private static final com.google.protobuf.Mixin DEFAULT_INSTANCE;
-  static {
-    Mixin defaultInstance = new Mixin();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      Mixin.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.Mixin getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<Mixin> PARSER;
-
-  public static com.google.protobuf.Parser<Mixin> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MixinOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/MixinOrBuilder.java
deleted file mode 100644
index 7808cdc..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MixinOrBuilder.java
+++ /dev/null
@@ -1,51 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/api.proto
-
-package com.google.protobuf;
-
-public interface MixinOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.Mixin)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * The fully qualified name of the interface which is included.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The name.
-   */
-  java.lang.String getName();
-  /**
-   * <pre>
-   * The fully qualified name of the interface which is included.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The bytes for name.
-   */
-  com.google.protobuf.ByteString
-      getNameBytes();
-
-  /**
-   * <pre>
-   * If non-empty specifies a path under which inherited HTTP paths
-   * are rooted.
-   * </pre>
-   *
-   * <code>string root = 2;</code>
-   * @return The root.
-   */
-  java.lang.String getRoot();
-  /**
-   * <pre>
-   * If non-empty specifies a path under which inherited HTTP paths
-   * are rooted.
-   * </pre>
-   *
-   * <code>string root = 2;</code>
-   * @return The bytes for root.
-   */
-  com.google.protobuf.ByteString
-      getRootBytes();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MutabilityOracle.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/MutabilityOracle.java
deleted file mode 100644
index 7c2f157..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/MutabilityOracle.java
+++ /dev/null
@@ -1,45 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-/** Verifies that an object is mutable, throwing if not. */
-interface MutabilityOracle {
-  static final MutabilityOracle IMMUTABLE =
-      new MutabilityOracle() {
-        @Override
-        public void ensureMutable() {
-          throw new UnsupportedOperationException();
-        }
-      };
-
-  /** Throws an {@link UnsupportedOperationException} if not mutable. */
-  void ensureMutable();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/NewInstanceSchema.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/NewInstanceSchema.java
deleted file mode 100644
index f2dbb8e..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/NewInstanceSchema.java
+++ /dev/null
@@ -1,36 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-interface NewInstanceSchema {
-  /** Create a new message instance given the default instance of the message type. */
-  Object newInstance(Object defaultInstance);
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/NewInstanceSchemaLite.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/NewInstanceSchemaLite.java
deleted file mode 100644
index 9b92266..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/NewInstanceSchemaLite.java
+++ /dev/null
@@ -1,39 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-final class NewInstanceSchemaLite implements NewInstanceSchema {
-  @Override
-  public Object newInstance(Object defaultInstance) {
-    return ((GeneratedMessageLite) defaultInstance)
-        .dynamicMethod(GeneratedMessageLite.MethodToInvoke.NEW_MUTABLE_INSTANCE);
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/NewInstanceSchemas.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/NewInstanceSchemas.java
deleted file mode 100644
index eff45f6..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/NewInstanceSchemas.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-final class NewInstanceSchemas {
-  private static final NewInstanceSchema FULL_SCHEMA = loadSchemaForFullRuntime();
-  private static final NewInstanceSchema LITE_SCHEMA = new NewInstanceSchemaLite();
-
-  static NewInstanceSchema full() {
-    return FULL_SCHEMA;
-  }
-
-  static NewInstanceSchema lite() {
-    return LITE_SCHEMA;
-  }
-
-  private static NewInstanceSchema loadSchemaForFullRuntime() {
-    try {
-      Class<?> clazz = Class.forName("com.google.protobuf.NewInstanceSchemaFull");
-      return (NewInstanceSchema) clazz.getDeclaredConstructor().newInstance();
-    } catch (Exception e) {
-      return null;
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/NioByteString.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/NioByteString.java
deleted file mode 100644
index 1e594ff..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/NioByteString.java
+++ /dev/null
@@ -1,293 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.Internal.checkNotNull;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InvalidObjectException;
-import java.io.ObjectInputStream;
-import java.io.OutputStream;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.InvalidMarkException;
-import java.nio.charset.Charset;
-import java.util.Collections;
-import java.util.List;
-
-/** A {@link ByteString} that wraps around a {@link ByteBuffer}. */
-final class NioByteString extends ByteString.LeafByteString {
-  private final ByteBuffer buffer;
-
-  NioByteString(ByteBuffer buffer) {
-    checkNotNull(buffer, "buffer");
-
-    // Use native byte order for fast fixed32/64 operations.
-    this.buffer = buffer.slice().order(ByteOrder.nativeOrder());
-  }
-
-  // =================================================================
-  // Serializable
-
-  /** Magic method that lets us override serialization behavior. */
-  private Object writeReplace() {
-    return ByteString.copyFrom(buffer.slice());
-  }
-
-  /** Magic method that lets us override deserialization behavior. */
-  private void readObject(@SuppressWarnings("unused") ObjectInputStream in) throws IOException {
-    throw new InvalidObjectException("NioByteString instances are not to be serialized directly");
-  }
-
-  // =================================================================
-
-  @Override
-  public byte byteAt(int index) {
-    try {
-      return buffer.get(index);
-    } catch (ArrayIndexOutOfBoundsException e) {
-      throw e;
-    } catch (IndexOutOfBoundsException e) {
-      throw new ArrayIndexOutOfBoundsException(e.getMessage());
-    }
-  }
-
-  @Override
-  public byte internalByteAt(int index) {
-    // it isn't possible to avoid the bounds checking inside of ByteBuffer, so just use the default
-    // implementation.
-    return byteAt(index);
-  }
-
-  @Override
-  public int size() {
-    return buffer.remaining();
-  }
-
-  @Override
-  public ByteString substring(int beginIndex, int endIndex) {
-    try {
-      ByteBuffer slice = slice(beginIndex, endIndex);
-      return new NioByteString(slice);
-    } catch (ArrayIndexOutOfBoundsException e) {
-      throw e;
-    } catch (IndexOutOfBoundsException e) {
-      throw new ArrayIndexOutOfBoundsException(e.getMessage());
-    }
-  }
-
-  @Override
-  protected void copyToInternal(
-      byte[] target, int sourceOffset, int targetOffset, int numberToCopy) {
-    ByteBuffer slice = buffer.slice();
-    ((Buffer) slice).position(sourceOffset);
-    slice.get(target, targetOffset, numberToCopy);
-  }
-
-  @Override
-  public void copyTo(ByteBuffer target) {
-    target.put(buffer.slice());
-  }
-
-  @Override
-  public void writeTo(OutputStream out) throws IOException {
-    out.write(toByteArray());
-  }
-
-  @Override
-  boolean equalsRange(ByteString other, int offset, int length) {
-    return substring(0, length).equals(other.substring(offset, offset + length));
-  }
-
-  @Override
-  void writeToInternal(OutputStream out, int sourceOffset, int numberToWrite) throws IOException {
-    if (buffer.hasArray()) {
-      // Optimized write for array-backed buffers.
-      // Note that we're taking the risk that a malicious OutputStream could modify the array.
-      int bufferOffset = buffer.arrayOffset() + buffer.position() + sourceOffset;
-      out.write(buffer.array(), bufferOffset, numberToWrite);
-      return;
-    }
-
-    ByteBufferWriter.write(slice(sourceOffset, sourceOffset + numberToWrite), out);
-  }
-
-  @Override
-  void writeTo(ByteOutput output) throws IOException {
-    output.writeLazy(buffer.slice());
-  }
-
-  @Override
-  public ByteBuffer asReadOnlyByteBuffer() {
-    return buffer.asReadOnlyBuffer();
-  }
-
-  @Override
-  public List<ByteBuffer> asReadOnlyByteBufferList() {
-    return Collections.singletonList(asReadOnlyByteBuffer());
-  }
-
-  @Override
-  protected String toStringInternal(Charset charset) {
-    final byte[] bytes;
-    final int offset;
-    final int length;
-    if (buffer.hasArray()) {
-      bytes = buffer.array();
-      offset = buffer.arrayOffset() + buffer.position();
-      length = buffer.remaining();
-    } else {
-      // TODO(nathanmittler): Can we optimize this?
-      bytes = toByteArray();
-      offset = 0;
-      length = bytes.length;
-    }
-    return new String(bytes, offset, length, charset);
-  }
-
-  @Override
-  public boolean isValidUtf8() {
-    return Utf8.isValidUtf8(buffer);
-  }
-
-  @Override
-  protected int partialIsValidUtf8(int state, int offset, int length) {
-    return Utf8.partialIsValidUtf8(state, buffer, offset, offset + length);
-  }
-
-  @Override
-  public boolean equals(Object other) {
-    if (other == this) {
-      return true;
-    }
-    if (!(other instanceof ByteString)) {
-      return false;
-    }
-    ByteString otherString = ((ByteString) other);
-    if (size() != otherString.size()) {
-      return false;
-    }
-    if (size() == 0) {
-      return true;
-    }
-    if (other instanceof NioByteString) {
-      return buffer.equals(((NioByteString) other).buffer);
-    }
-    if (other instanceof RopeByteString) {
-      return other.equals(this);
-    }
-    return buffer.equals(otherString.asReadOnlyByteBuffer());
-  }
-
-  @Override
-  protected int partialHash(int h, int offset, int length) {
-    for (int i = offset; i < offset + length; i++) {
-      h = h * 31 + buffer.get(i);
-    }
-    return h;
-  }
-
-  @Override
-  public InputStream newInput() {
-    return new InputStream() {
-      private final ByteBuffer buf = buffer.slice();
-
-      @Override
-      public void mark(int readlimit) {
-        buf.mark();
-      }
-
-      @Override
-      public boolean markSupported() {
-        return true;
-      }
-
-      @Override
-      public void reset() throws IOException {
-        try {
-          buf.reset();
-        } catch (InvalidMarkException e) {
-          throw new IOException(e);
-        }
-      }
-
-      @Override
-      public int available() throws IOException {
-        return buf.remaining();
-      }
-
-      @Override
-      public int read() throws IOException {
-        if (!buf.hasRemaining()) {
-          return -1;
-        }
-        return buf.get() & 0xFF;
-      }
-
-      @Override
-      public int read(byte[] bytes, int off, int len) throws IOException {
-        if (!buf.hasRemaining()) {
-          return -1;
-        }
-
-        len = Math.min(len, buf.remaining());
-        buf.get(bytes, off, len);
-        return len;
-      }
-    };
-  }
-
-  @Override
-  public CodedInputStream newCodedInput() {
-    return CodedInputStream.newInstance(buffer, true);
-  }
-
-  /**
-   * Creates a slice of a range of this buffer.
-   *
-   * @param beginIndex the beginning index of the slice (inclusive).
-   * @param endIndex the end index of the slice (exclusive).
-   * @return the requested slice.
-   */
-  private ByteBuffer slice(int beginIndex, int endIndex) {
-    if (beginIndex < buffer.position() || endIndex > buffer.limit() || beginIndex > endIndex) {
-      throw new IllegalArgumentException(
-          String.format("Invalid indices [%d, %d]", beginIndex, endIndex));
-    }
-
-    ByteBuffer slice = buffer.slice();
-    ((Buffer) slice).position(beginIndex - buffer.position());
-    ((Buffer) slice).limit(endIndex - buffer.position());
-    return slice;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/NullValue.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/NullValue.java
deleted file mode 100644
index 9c43011..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/NullValue.java
+++ /dev/null
@@ -1,99 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/struct.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * `NullValue` is a singleton enumeration to represent the null value for the
- * `Value` type union.
- *  The JSON representation for `NullValue` is JSON `null`.
- * </pre>
- *
- * Protobuf enum {@code google.protobuf.NullValue}
- */
-public enum NullValue
-    implements com.google.protobuf.Internal.EnumLite {
-  /**
-   * <pre>
-   * Null value.
-   * </pre>
-   *
-   * <code>NULL_VALUE = 0;</code>
-   */
-  NULL_VALUE(0),
-  UNRECOGNIZED(-1),
-  ;
-
-  /**
-   * <pre>
-   * Null value.
-   * </pre>
-   *
-   * <code>NULL_VALUE = 0;</code>
-   */
-  public static final int NULL_VALUE_VALUE = 0;
-
-
-  @java.lang.Override
-  public final int getNumber() {
-    if (this == UNRECOGNIZED) {
-      throw new java.lang.IllegalArgumentException(
-          "Can't get the number of an unknown enum value.");
-    }
-    return value;
-  }
-
-  /**
-   * @param value The number of the enum to look for.
-   * @return The enum associated with the given number.
-   * @deprecated Use {@link #forNumber(int)} instead.
-   */
-  @java.lang.Deprecated
-  public static NullValue valueOf(int value) {
-    return forNumber(value);
-  }
-
-  public static NullValue forNumber(int value) {
-    switch (value) {
-      case 0: return NULL_VALUE;
-      default: return null;
-    }
-  }
-
-  public static com.google.protobuf.Internal.EnumLiteMap<NullValue>
-      internalGetValueMap() {
-    return internalValueMap;
-  }
-  private static final com.google.protobuf.Internal.EnumLiteMap<
-      NullValue> internalValueMap =
-        new com.google.protobuf.Internal.EnumLiteMap<NullValue>() {
-          @java.lang.Override
-          public NullValue findValueByNumber(int number) {
-            return NullValue.forNumber(number);
-          }
-        };
-
-  public static com.google.protobuf.Internal.EnumVerifier 
-      internalGetVerifier() {
-    return NullValueVerifier.INSTANCE;
-  }
-
-  private static final class NullValueVerifier implements 
-       com.google.protobuf.Internal.EnumVerifier { 
-          static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new NullValueVerifier();
-          @java.lang.Override
-          public boolean isInRange(int number) {
-            return NullValue.forNumber(number) != null;
-          }
-        };
-
-  private final int value;
-
-  private NullValue(int value) {
-    this.value = value;
-  }
-
-  // @@protoc_insertion_point(enum_scope:google.protobuf.NullValue)
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/OneofInfo.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/OneofInfo.java
deleted file mode 100644
index bc518fc..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/OneofInfo.java
+++ /dev/null
@@ -1,66 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.lang.reflect.Field;
-
-/** Information for a oneof within a protobuf message. */
-// TODO(nathanmittler): make this private once all of experimental code is migrated to protobuf.
-@ExperimentalApi
-final class OneofInfo {
-  private final int id;
-  private final Field caseField;
-  private final Field valueField;
-
-  public OneofInfo(int id, Field caseField, Field valueField) {
-    this.id = id;
-    this.caseField = caseField;
-    this.valueField = valueField;
-  }
-
-  /**
-   * Returns the unique identifier of the oneof within the message. This is really just an index
-   * starting at zero.
-   */
-  public int getId() {
-    return id;
-  }
-
-  /** The {@code int} field containing the field number of the currently active member. */
-  public Field getCaseField() {
-    return caseField;
-  }
-
-  /** The {@link Object} field containing the value of the currently active member. */
-  public Field getValueField() {
-    return valueField;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/OnlyForUseByGeneratedProtoCode.kt b/java/kotlin-lite/target/generated-sources/com/google/protobuf/OnlyForUseByGeneratedProtoCode.kt
deleted file mode 100644
index 368912e..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/OnlyForUseByGeneratedProtoCode.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.google.protobuf.kotlin
-
-/**
- * Opt-in annotation to make it difficult to accidentally use APIs only intended for use by proto
- * generated code.  See https://kotlinlang.org/docs/reference/opt-in-requirements.html for details
- * on how this API works.
- */
-@RequiresOptIn(
-  message =
-    """
-    This API is only intended for use by generated protobuf code, the code generator, and their own
-    tests.  If this does not describe your code, you should not be using this API.
-  """,
-  level = RequiresOptIn.Level.ERROR
-)
-@Retention(AnnotationRetention.BINARY)
-@Target(AnnotationTarget.CONSTRUCTOR, AnnotationTarget.ANNOTATION_CLASS)
-annotation class OnlyForUseByGeneratedProtoCode
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Option.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Option.java
deleted file mode 100644
index 988766c..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Option.java
+++ /dev/null
@@ -1,533 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/type.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * A protocol buffer option, which can be attached to a message, field,
- * enumeration, etc.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.Option}
- */
-public  final class Option extends
-    com.google.protobuf.GeneratedMessageLite<
-        Option, Option.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.Option)
-    OptionOrBuilder {
-  private Option() {
-    name_ = "";
-  }
-  public static final int NAME_FIELD_NUMBER = 1;
-  private java.lang.String name_;
-  /**
-   * <pre>
-   * The option's name. For protobuf built-in options (options defined in
-   * descriptor.proto), this is the short name. For example, `"map_entry"`.
-   * For custom options, it should be the fully-qualified name. For example,
-   * `"google.api.http"`.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The name.
-   */
-  @java.lang.Override
-  public java.lang.String getName() {
-    return name_;
-  }
-  /**
-   * <pre>
-   * The option's name. For protobuf built-in options (options defined in
-   * descriptor.proto), this is the short name. For example, `"map_entry"`.
-   * For custom options, it should be the fully-qualified name. For example,
-   * `"google.api.http"`.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The bytes for name.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getNameBytes() {
-    return com.google.protobuf.ByteString.copyFromUtf8(name_);
-  }
-  /**
-   * <pre>
-   * The option's name. For protobuf built-in options (options defined in
-   * descriptor.proto), this is the short name. For example, `"map_entry"`.
-   * For custom options, it should be the fully-qualified name. For example,
-   * `"google.api.http"`.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @param value The name to set.
-   */
-  private void setName(
-      java.lang.String value) {
-    value.getClass();
-  
-    name_ = value;
-  }
-  /**
-   * <pre>
-   * The option's name. For protobuf built-in options (options defined in
-   * descriptor.proto), this is the short name. For example, `"map_entry"`.
-   * For custom options, it should be the fully-qualified name. For example,
-   * `"google.api.http"`.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   */
-  private void clearName() {
-    
-    name_ = getDefaultInstance().getName();
-  }
-  /**
-   * <pre>
-   * The option's name. For protobuf built-in options (options defined in
-   * descriptor.proto), this is the short name. For example, `"map_entry"`.
-   * For custom options, it should be the fully-qualified name. For example,
-   * `"google.api.http"`.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @param value The bytes for name to set.
-   */
-  private void setNameBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    name_ = value.toStringUtf8();
-    
-  }
-
-  public static final int VALUE_FIELD_NUMBER = 2;
-  private com.google.protobuf.Any value_;
-  /**
-   * <pre>
-   * The option's value packed in an Any message. If the value is a primitive,
-   * the corresponding wrapper type defined in google/protobuf/wrappers.proto
-   * should be used. If the value is an enum, it should be stored as an int32
-   * value using the google.protobuf.Int32Value type.
-   * </pre>
-   *
-   * <code>.google.protobuf.Any value = 2;</code>
-   */
-  @java.lang.Override
-  public boolean hasValue() {
-    return value_ != null;
-  }
-  /**
-   * <pre>
-   * The option's value packed in an Any message. If the value is a primitive,
-   * the corresponding wrapper type defined in google/protobuf/wrappers.proto
-   * should be used. If the value is an enum, it should be stored as an int32
-   * value using the google.protobuf.Int32Value type.
-   * </pre>
-   *
-   * <code>.google.protobuf.Any value = 2;</code>
-   */
-  @java.lang.Override
-  public com.google.protobuf.Any getValue() {
-    return value_ == null ? com.google.protobuf.Any.getDefaultInstance() : value_;
-  }
-  /**
-   * <pre>
-   * The option's value packed in an Any message. If the value is a primitive,
-   * the corresponding wrapper type defined in google/protobuf/wrappers.proto
-   * should be used. If the value is an enum, it should be stored as an int32
-   * value using the google.protobuf.Int32Value type.
-   * </pre>
-   *
-   * <code>.google.protobuf.Any value = 2;</code>
-   */
-  private void setValue(com.google.protobuf.Any value) {
-    value.getClass();
-  value_ = value;
-    
-    }
-  /**
-   * <pre>
-   * The option's value packed in an Any message. If the value is a primitive,
-   * the corresponding wrapper type defined in google/protobuf/wrappers.proto
-   * should be used. If the value is an enum, it should be stored as an int32
-   * value using the google.protobuf.Int32Value type.
-   * </pre>
-   *
-   * <code>.google.protobuf.Any value = 2;</code>
-   */
-  @java.lang.SuppressWarnings({"ReferenceEquality"})
-  private void mergeValue(com.google.protobuf.Any value) {
-    value.getClass();
-  if (value_ != null &&
-        value_ != com.google.protobuf.Any.getDefaultInstance()) {
-      value_ =
-        com.google.protobuf.Any.newBuilder(value_).mergeFrom(value).buildPartial();
-    } else {
-      value_ = value;
-    }
-    
-  }
-  /**
-   * <pre>
-   * The option's value packed in an Any message. If the value is a primitive,
-   * the corresponding wrapper type defined in google/protobuf/wrappers.proto
-   * should be used. If the value is an enum, it should be stored as an int32
-   * value using the google.protobuf.Int32Value type.
-   * </pre>
-   *
-   * <code>.google.protobuf.Any value = 2;</code>
-   */
-  private void clearValue() {  value_ = null;
-    
-  }
-
-  public static com.google.protobuf.Option parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Option parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Option parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Option parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Option parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Option parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Option parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Option parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Option parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Option parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Option parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Option parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.Option prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * A protocol buffer option, which can be attached to a message, field,
-   * enumeration, etc.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.Option}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.Option, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.Option)
-      com.google.protobuf.OptionOrBuilder {
-    // Construct using com.google.protobuf.Option.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * The option's name. For protobuf built-in options (options defined in
-     * descriptor.proto), this is the short name. For example, `"map_entry"`.
-     * For custom options, it should be the fully-qualified name. For example,
-     * `"google.api.http"`.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return The name.
-     */
-    @java.lang.Override
-    public java.lang.String getName() {
-      return instance.getName();
-    }
-    /**
-     * <pre>
-     * The option's name. For protobuf built-in options (options defined in
-     * descriptor.proto), this is the short name. For example, `"map_entry"`.
-     * For custom options, it should be the fully-qualified name. For example,
-     * `"google.api.http"`.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return The bytes for name.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getNameBytes() {
-      return instance.getNameBytes();
-    }
-    /**
-     * <pre>
-     * The option's name. For protobuf built-in options (options defined in
-     * descriptor.proto), this is the short name. For example, `"map_entry"`.
-     * For custom options, it should be the fully-qualified name. For example,
-     * `"google.api.http"`.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @param value The name to set.
-     * @return This builder for chaining.
-     */
-    public Builder setName(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.setName(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The option's name. For protobuf built-in options (options defined in
-     * descriptor.proto), this is the short name. For example, `"map_entry"`.
-     * For custom options, it should be the fully-qualified name. For example,
-     * `"google.api.http"`.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearName() {
-      copyOnWrite();
-      instance.clearName();
-      return this;
-    }
-    /**
-     * <pre>
-     * The option's name. For protobuf built-in options (options defined in
-     * descriptor.proto), this is the short name. For example, `"map_entry"`.
-     * For custom options, it should be the fully-qualified name. For example,
-     * `"google.api.http"`.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @param value The bytes for name to set.
-     * @return This builder for chaining.
-     */
-    public Builder setNameBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setNameBytes(value);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The option's value packed in an Any message. If the value is a primitive,
-     * the corresponding wrapper type defined in google/protobuf/wrappers.proto
-     * should be used. If the value is an enum, it should be stored as an int32
-     * value using the google.protobuf.Int32Value type.
-     * </pre>
-     *
-     * <code>.google.protobuf.Any value = 2;</code>
-     */
-    @java.lang.Override
-    public boolean hasValue() {
-      return instance.hasValue();
-    }
-    /**
-     * <pre>
-     * The option's value packed in an Any message. If the value is a primitive,
-     * the corresponding wrapper type defined in google/protobuf/wrappers.proto
-     * should be used. If the value is an enum, it should be stored as an int32
-     * value using the google.protobuf.Int32Value type.
-     * </pre>
-     *
-     * <code>.google.protobuf.Any value = 2;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.Any getValue() {
-      return instance.getValue();
-    }
-    /**
-     * <pre>
-     * The option's value packed in an Any message. If the value is a primitive,
-     * the corresponding wrapper type defined in google/protobuf/wrappers.proto
-     * should be used. If the value is an enum, it should be stored as an int32
-     * value using the google.protobuf.Int32Value type.
-     * </pre>
-     *
-     * <code>.google.protobuf.Any value = 2;</code>
-     */
-    public Builder setValue(com.google.protobuf.Any value) {
-      copyOnWrite();
-      instance.setValue(value);
-      return this;
-      }
-    /**
-     * <pre>
-     * The option's value packed in an Any message. If the value is a primitive,
-     * the corresponding wrapper type defined in google/protobuf/wrappers.proto
-     * should be used. If the value is an enum, it should be stored as an int32
-     * value using the google.protobuf.Int32Value type.
-     * </pre>
-     *
-     * <code>.google.protobuf.Any value = 2;</code>
-     */
-    public Builder setValue(
-        com.google.protobuf.Any.Builder builderForValue) {
-      copyOnWrite();
-      instance.setValue(builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * The option's value packed in an Any message. If the value is a primitive,
-     * the corresponding wrapper type defined in google/protobuf/wrappers.proto
-     * should be used. If the value is an enum, it should be stored as an int32
-     * value using the google.protobuf.Int32Value type.
-     * </pre>
-     *
-     * <code>.google.protobuf.Any value = 2;</code>
-     */
-    public Builder mergeValue(com.google.protobuf.Any value) {
-      copyOnWrite();
-      instance.mergeValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The option's value packed in an Any message. If the value is a primitive,
-     * the corresponding wrapper type defined in google/protobuf/wrappers.proto
-     * should be used. If the value is an enum, it should be stored as an int32
-     * value using the google.protobuf.Int32Value type.
-     * </pre>
-     *
-     * <code>.google.protobuf.Any value = 2;</code>
-     */
-    public Builder clearValue() {  copyOnWrite();
-      instance.clearValue();
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.Option)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.Option();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "name_",
-            "value_",
-          };
-          java.lang.String info =
-              "\u0000\u0002\u0000\u0000\u0001\u0002\u0002\u0000\u0000\u0000\u0001\u0208\u0002\t" +
-              "";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.Option> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.Option.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.Option>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.Option)
-  private static final com.google.protobuf.Option DEFAULT_INSTANCE;
-  static {
-    Option defaultInstance = new Option();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      Option.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.Option getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<Option> PARSER;
-
-  public static com.google.protobuf.Parser<Option> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/OptionOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/OptionOrBuilder.java
deleted file mode 100644
index 1b11720..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/OptionOrBuilder.java
+++ /dev/null
@@ -1,60 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/type.proto
-
-package com.google.protobuf;
-
-public interface OptionOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.Option)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * The option's name. For protobuf built-in options (options defined in
-   * descriptor.proto), this is the short name. For example, `"map_entry"`.
-   * For custom options, it should be the fully-qualified name. For example,
-   * `"google.api.http"`.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The name.
-   */
-  java.lang.String getName();
-  /**
-   * <pre>
-   * The option's name. For protobuf built-in options (options defined in
-   * descriptor.proto), this is the short name. For example, `"map_entry"`.
-   * For custom options, it should be the fully-qualified name. For example,
-   * `"google.api.http"`.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The bytes for name.
-   */
-  com.google.protobuf.ByteString
-      getNameBytes();
-
-  /**
-   * <pre>
-   * The option's value packed in an Any message. If the value is a primitive,
-   * the corresponding wrapper type defined in google/protobuf/wrappers.proto
-   * should be used. If the value is an enum, it should be stored as an int32
-   * value using the google.protobuf.Int32Value type.
-   * </pre>
-   *
-   * <code>.google.protobuf.Any value = 2;</code>
-   * @return Whether the value field is set.
-   */
-  boolean hasValue();
-  /**
-   * <pre>
-   * The option's value packed in an Any message. If the value is a primitive,
-   * the corresponding wrapper type defined in google/protobuf/wrappers.proto
-   * should be used. If the value is an enum, it should be stored as an int32
-   * value using the google.protobuf.Int32Value type.
-   * </pre>
-   *
-   * <code>.google.protobuf.Any value = 2;</code>
-   * @return The value.
-   */
-  com.google.protobuf.Any getValue();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Parser.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Parser.java
deleted file mode 100644
index 22ee99b..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Parser.java
+++ /dev/null
@@ -1,242 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-
-/**
- * Abstract interface for parsing Protocol Messages.
- *
- * <p>The implementation should be stateless and thread-safe.
- *
- * <p>All methods may throw {@link InvalidProtocolBufferException}. In the event of invalid data,
- * like an encoding error, the cause of the thrown exception will be {@code null}. However, if an
- * I/O problem occurs, an exception is thrown with an {@link java.io.IOException} cause.
- *
- * @author liujisi@google.com (Pherl Liu)
- */
-public interface Parser<MessageType> {
-
-  // NB(jh): Other parts of the protobuf API that parse messages distinguish between an I/O problem
-  // (like failure reading bytes from a socket) and invalid data (encoding error) via the type of
-  // thrown exception. But it would be source-incompatible to make the methods in this interface do
-  // so since they were originally spec'ed to only throw InvalidProtocolBufferException. So callers
-  // must inspect the cause of the exception to distinguish these two cases.
-
-  /**
-   * Parses a message of {@code MessageType} from the input.
-   *
-   * <p>Note: The caller should call {@link CodedInputStream#checkLastTagWas(int)} after calling
-   * this to verify that the last tag seen was the appropriate end-group tag, or zero for EOF.
-   */
-  public MessageType parseFrom(CodedInputStream input) throws InvalidProtocolBufferException;
-
-  /**
-   * Like {@link #parseFrom(CodedInputStream)}, but also parses extensions. The extensions that you
-   * want to be able to parse must be registered in {@code extensionRegistry}. Extensions not in the
-   * registry will be treated as unknown fields.
-   */
-  public MessageType parseFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException;
-
-  /**
-   * Like {@link #parseFrom(CodedInputStream)}, but does not throw an exception if the message is
-   * missing required fields. Instead, a partial message is returned.
-   */
-  public MessageType parsePartialFrom(CodedInputStream input) throws InvalidProtocolBufferException;
-
-  /**
-   * Like {@link #parseFrom(CodedInputStream input, ExtensionRegistryLite)}, but does not throw an
-   * exception if the message is missing required fields. Instead, a partial message is returned.
-   */
-  public MessageType parsePartialFrom(
-      CodedInputStream input, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException;
-
-  // ---------------------------------------------------------------
-  // Convenience methods.
-
-  /**
-   * Parses {@code data} as a message of {@code MessageType}. This is just a small wrapper around
-   * {@link #parseFrom(CodedInputStream)}.
-   */
-  public MessageType parseFrom(ByteBuffer data) throws InvalidProtocolBufferException;
-
-  /**
-   * Parses {@code data} as a message of {@code MessageType}. This is just a small wrapper around
-   * {@link #parseFrom(CodedInputStream, ExtensionRegistryLite)}.
-   */
-  public MessageType parseFrom(ByteBuffer data, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException;
-  /**
-   * Parses {@code data} as a message of {@code MessageType}. This is just a small wrapper around
-   * {@link #parseFrom(CodedInputStream)}.
-   */
-  public MessageType parseFrom(ByteString data) throws InvalidProtocolBufferException;
-
-  /**
-   * Parses {@code data} as a message of {@code MessageType}. This is just a small wrapper around
-   * {@link #parseFrom(CodedInputStream, ExtensionRegistryLite)}.
-   */
-  public MessageType parseFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException;
-
-  /**
-   * Like {@link #parseFrom(ByteString)}, but does not throw an exception if the message is missing
-   * required fields. Instead, a partial message is returned.
-   */
-  public MessageType parsePartialFrom(ByteString data) throws InvalidProtocolBufferException;
-
-  /**
-   * Like {@link #parseFrom(ByteString, ExtensionRegistryLite)}, but does not throw an exception if
-   * the message is missing required fields. Instead, a partial message is returned.
-   */
-  public MessageType parsePartialFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException;
-
-  /**
-   * Parses {@code data} as a message of {@code MessageType}. This is just a small wrapper around
-   * {@link #parseFrom(CodedInputStream)}.
-   */
-  public MessageType parseFrom(byte[] data, int off, int len) throws InvalidProtocolBufferException;
-
-  /**
-   * Parses {@code data} as a message of {@code MessageType}. This is just a small wrapper around
-   * {@link #parseFrom(CodedInputStream, ExtensionRegistryLite)}.
-   */
-  public MessageType parseFrom(
-      byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException;
-
-  /**
-   * Parses {@code data} as a message of {@code MessageType}. This is just a small wrapper around
-   * {@link #parseFrom(CodedInputStream)}.
-   */
-  public MessageType parseFrom(byte[] data) throws InvalidProtocolBufferException;
-
-  /**
-   * Parses {@code data} as a message of {@code MessageType}. This is just a small wrapper around
-   * {@link #parseFrom(CodedInputStream, ExtensionRegistryLite)}.
-   */
-  public MessageType parseFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException;
-
-  /**
-   * Like {@link #parseFrom(byte[], int, int)}, but does not throw an exception if the message is
-   * missing required fields. Instead, a partial message is returned.
-   */
-  public MessageType parsePartialFrom(byte[] data, int off, int len)
-      throws InvalidProtocolBufferException;
-
-  /**
-   * Like {@link #parseFrom(ByteString, ExtensionRegistryLite)}, but does not throw an exception if
-   * the message is missing required fields. Instead, a partial message is returned.
-   */
-  public MessageType parsePartialFrom(
-      byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException;
-
-  /**
-   * Like {@link #parseFrom(byte[])}, but does not throw an exception if the message is missing
-   * required fields. Instead, a partial message is returned.
-   */
-  public MessageType parsePartialFrom(byte[] data) throws InvalidProtocolBufferException;
-
-  /**
-   * Like {@link #parseFrom(byte[], ExtensionRegistryLite)}, but does not throw an exception if the
-   * message is missing required fields. Instead, a partial message is returned.
-   */
-  public MessageType parsePartialFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException;
-
-  /**
-   * Parse a message of {@code MessageType} from {@code input}. This is just a small wrapper around
-   * {@link #parseFrom(CodedInputStream)}. Note that this method always reads the <i>entire</i>
-   * input (unless it throws an exception). If you want it to stop earlier, you will need to wrap
-   * your input in some wrapper stream that limits reading. Or, use {@link
-   * MessageLite#writeDelimitedTo(java.io.OutputStream)} to write your message and {@link
-   * #parseDelimitedFrom(InputStream)} to read it.
-   *
-   * <p>Despite usually reading the entire input, this does not close the stream.
-   */
-  public MessageType parseFrom(InputStream input) throws InvalidProtocolBufferException;
-
-  /**
-   * Parses a message of {@code MessageType} from {@code input}. This is just a small wrapper around
-   * {@link #parseFrom(CodedInputStream, ExtensionRegistryLite)}.
-   */
-  public MessageType parseFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException;
-
-  /**
-   * Like {@link #parseFrom(InputStream)}, but does not throw an exception if the message is missing
-   * required fields. Instead, a partial message is returned.
-   */
-  public MessageType parsePartialFrom(InputStream input) throws InvalidProtocolBufferException;
-
-  /**
-   * Like {@link #parseFrom(InputStream, ExtensionRegistryLite)}, but does not throw an exception if
-   * the message is missing required fields. Instead, a partial message is returned.
-   */
-  public MessageType parsePartialFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException;
-
-  /**
-   * Like {@link #parseFrom(InputStream)}, but does not read until EOF. Instead, the size of message
-   * (encoded as a varint) is read first, then the message data. Use {@link
-   * MessageLite#writeDelimitedTo(java.io.OutputStream)} to write messages in this format.
-   *
-   * @return Parsed message if successful, or null if the stream is at EOF when the method starts.
-   *     Any other error (including reaching EOF during parsing) will cause an exception to be
-   *     thrown.
-   */
-  public MessageType parseDelimitedFrom(InputStream input) throws InvalidProtocolBufferException;
-
-  /** Like {@link #parseDelimitedFrom(InputStream)} but supporting extensions. */
-  public MessageType parseDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException;
-
-  /**
-   * Like {@link #parseDelimitedFrom(InputStream)}, but does not throw an exception if the message
-   * is missing required fields. Instead, a partial message is returned.
-   */
-  public MessageType parsePartialDelimitedFrom(InputStream input)
-      throws InvalidProtocolBufferException;
-
-  /**
-   * Like {@link #parseDelimitedFrom(InputStream, ExtensionRegistryLite)}, but does not throw an
-   * exception if the message is missing required fields. Instead, a partial message is returned.
-   */
-  public MessageType parsePartialDelimitedFrom(
-      InputStream input, ExtensionRegistryLite extensionRegistry)
-      throws InvalidProtocolBufferException;
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/PrimitiveNonBoxingCollection.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/PrimitiveNonBoxingCollection.java
deleted file mode 100644
index 79b5769..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/PrimitiveNonBoxingCollection.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-/** A marker interface indicating that the collection supports primitives and is non-boxing. */
-interface PrimitiveNonBoxingCollection {}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ProtoDslMarker.kt b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ProtoDslMarker.kt
deleted file mode 100644
index c51ba35..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ProtoDslMarker.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.google.protobuf.kotlin
-
-/**
- * Indicates an API that is part of a DSL to generate protocol buffer messages.
- */
-@DslMarker
-@Target(AnnotationTarget.CLASS)
-@Retention(AnnotationRetention.BINARY)
-@OnlyForUseByGeneratedProtoCode
-annotation class ProtoDslMarker
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ProtoSyntax.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ProtoSyntax.java
deleted file mode 100644
index 851b839..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ProtoSyntax.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-/** Represents the syntax version of the message. */
-@ExperimentalApi
-public enum ProtoSyntax {
-  PROTO2,
-  PROTO3;
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Protobuf.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Protobuf.java
deleted file mode 100644
index 0affac5..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Protobuf.java
+++ /dev/null
@@ -1,149 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.Internal.checkNotNull;
-
-import java.io.IOException;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-/**
- * Main runtime interface for protobuf. Applications should interact with this interface (rather
- * than directly accessing internal APIs) in order to perform operations on protobuf messages.
- */
-@ExperimentalApi
-final class Protobuf {
-  private static final Protobuf INSTANCE = new Protobuf();
-
-  private final SchemaFactory schemaFactory;
-
-  // TODO(nathanmittler): Consider using ClassValue instead.
-  private final ConcurrentMap<Class<?>, Schema<?>> schemaCache =
-      new ConcurrentHashMap<Class<?>, Schema<?>>();
-
-  /** Gets the singleton instance of the Protobuf runtime. */
-  public static Protobuf getInstance() {
-    return INSTANCE;
-  }
-
-  /** Writes the given message to the target {@link Writer}. */
-  public <T> void writeTo(T message, Writer writer) throws IOException {
-    schemaFor(message).writeTo(message, writer);
-  }
-
-  /** Reads fields from the given {@link Reader} and merges them into the message. */
-  public <T> void mergeFrom(T message, Reader reader) throws IOException {
-    mergeFrom(message, reader, ExtensionRegistryLite.getEmptyRegistry());
-  }
-
-  /** Reads fields from the given {@link Reader} and merges them into the message. */
-  public <T> void mergeFrom(T message, Reader reader, ExtensionRegistryLite extensionRegistry)
-      throws IOException {
-    schemaFor(message).mergeFrom(message, reader, extensionRegistry);
-  }
-
-  /** Marks repeated/map/extension/unknown fields as immutable. */
-  public <T> void makeImmutable(T message) {
-    schemaFor(message).makeImmutable(message);
-  }
-
-  /** Checks if all required fields are set. */
-  <T> boolean isInitialized(T message) {
-    return schemaFor(message).isInitialized(message);
-  }
-
-  /** Gets the schema for the given message type. */
-  public <T> Schema<T> schemaFor(Class<T> messageType) {
-    checkNotNull(messageType, "messageType");
-    @SuppressWarnings("unchecked")
-    Schema<T> schema = (Schema<T>) schemaCache.get(messageType);
-    if (schema == null) {
-      schema = schemaFactory.createSchema(messageType);
-      @SuppressWarnings("unchecked")
-      Schema<T> previous = (Schema<T>) registerSchema(messageType, schema);
-      if (previous != null) {
-        // A new schema was registered by another thread.
-        schema = previous;
-      }
-    }
-    return schema;
-  }
-
-  /** Gets the schema for the given message. */
-  @SuppressWarnings("unchecked")
-  public <T> Schema<T> schemaFor(T message) {
-    return schemaFor((Class<T>) message.getClass());
-  }
-
-  /**
-   * Registers the given schema for the message type only if a schema was not already registered.
-   *
-   * @param messageType the type of message on which the schema operates.
-   * @param schema the schema for the message type.
-   * @return the previously registered schema, or {@code null} if the given schema was successfully
-   *     registered.
-   */
-  public Schema<?> registerSchema(Class<?> messageType, Schema<?> schema) {
-    checkNotNull(messageType, "messageType");
-    checkNotNull(schema, "schema");
-    return schemaCache.putIfAbsent(messageType, schema);
-  }
-
-  /**
-   * Visible for testing only. Registers the given schema for the message type. If a schema was
-   * previously registered, it will be replaced by the provided schema.
-   *
-   * @param messageType the type of message on which the schema operates.
-   * @param schema the schema for the message type.
-   * @return the previously registered schema, or {@code null} if no schema was registered
-   *     previously.
-   */
-  public Schema<?> registerSchemaOverride(Class<?> messageType, Schema<?> schema) {
-    checkNotNull(messageType, "messageType");
-    checkNotNull(schema, "schema");
-    return schemaCache.put(messageType, schema);
-  }
-
-  private Protobuf() {
-    schemaFactory = new ManifestSchemaFactory();
-  }
-
-  int getTotalSchemaSize() {
-    int result = 0;
-    for (Schema<?> schema : schemaCache.values()) {
-      if (schema instanceof MessageSchema) {
-        result += ((MessageSchema) schema).getSchemaSize();
-      }
-    }
-    return result;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ProtobufArrayList.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ProtobufArrayList.java
deleted file mode 100644
index 33e4bd5..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ProtobufArrayList.java
+++ /dev/null
@@ -1,175 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import com.google.protobuf.Internal.ProtobufList;
-import java.util.Arrays;
-import java.util.RandomAccess;
-
-/** Implements {@link ProtobufList} for non-primitive and {@link String} types. */
-final class ProtobufArrayList<E> extends AbstractProtobufList<E> implements RandomAccess {
-
-  private static final ProtobufArrayList<Object> EMPTY_LIST =
-      new ProtobufArrayList<Object>(new Object[0], 0);
-
-  static {
-    EMPTY_LIST.makeImmutable();
-  }
-
-  @SuppressWarnings("unchecked") // Guaranteed safe by runtime.
-  public static <E> ProtobufArrayList<E> emptyList() {
-    return (ProtobufArrayList<E>) EMPTY_LIST;
-  }
-
-  private E[] array;
-  private int size;
-
-  @SuppressWarnings("unchecked")
-  ProtobufArrayList() {
-    this((E[]) new Object[DEFAULT_CAPACITY], 0);
-  }
-
-  private ProtobufArrayList(E[] array, int size) {
-    this.array = array;
-    this.size = size;
-  }
-
-  @Override
-  public ProtobufArrayList<E> mutableCopyWithCapacity(int capacity) {
-    if (capacity < size) {
-      throw new IllegalArgumentException();
-    }
-
-    E[] newArray = Arrays.copyOf(array, capacity);
-
-    return new ProtobufArrayList<E>(newArray, size);
-  }
-
-  @Override
-  public boolean add(E element) {
-    ensureIsMutable();
-
-    if (size == array.length) {
-      // Resize to 1.5x the size
-      int length = ((size * 3) / 2) + 1;
-      E[] newArray = Arrays.copyOf(array, length);
-
-      array = newArray;
-    }
-
-    array[size++] = element;
-    modCount++;
-
-    return true;
-  }
-
-  @Override
-  public void add(int index, E element) {
-    ensureIsMutable();
-
-    if (index < 0 || index > size) {
-      throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index));
-    }
-
-    if (size < array.length) {
-      // Shift everything over to make room
-      System.arraycopy(array, index, array, index + 1, size - index);
-    } else {
-      // Resize to 1.5x the size
-      int length = ((size * 3) / 2) + 1;
-      E[] newArray = createArray(length);
-
-      // Copy the first part directly
-      System.arraycopy(array, 0, newArray, 0, index);
-
-      // Copy the rest shifted over by one to make room
-      System.arraycopy(array, index, newArray, index + 1, size - index);
-      array = newArray;
-    }
-
-    array[index] = element;
-    size++;
-    modCount++;
-  }
-
-  @Override
-  public E get(int index) {
-    ensureIndexInRange(index);
-    return array[index];
-  }
-
-  @Override
-  public E remove(int index) {
-    ensureIsMutable();
-    ensureIndexInRange(index);
-
-    E value = array[index];
-    if (index < size - 1) {
-      System.arraycopy(array, index + 1, array, index, size - index - 1);
-    }
-
-    size--;
-    modCount++;
-    return value;
-  }
-
-  @Override
-  public E set(int index, E element) {
-    ensureIsMutable();
-    ensureIndexInRange(index);
-
-    E toReturn = array[index];
-    array[index] = element;
-
-    modCount++;
-    return toReturn;
-  }
-
-  @Override
-  public int size() {
-    return size;
-  }
-
-  @SuppressWarnings("unchecked")
-  private static <E> E[] createArray(int capacity) {
-    return (E[]) new Object[capacity];
-  }
-
-  private void ensureIndexInRange(int index) {
-    if (index < 0 || index >= size) {
-      throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index));
-    }
-  }
-
-  private String makeOutOfBoundsExceptionMessage(int index) {
-    return "Index:" + index + ", Size:" + size;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ProtobufLists.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ProtobufLists.java
deleted file mode 100644
index 271c849..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ProtobufLists.java
+++ /dev/null
@@ -1,94 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import com.google.protobuf.Internal.BooleanList;
-import com.google.protobuf.Internal.DoubleList;
-import com.google.protobuf.Internal.FloatList;
-import com.google.protobuf.Internal.IntList;
-import com.google.protobuf.Internal.LongList;
-import com.google.protobuf.Internal.ProtobufList;
-
-/** Utility class for construction of lists that extend {@link ProtobufList}. */
-@ExperimentalApi
-final class ProtobufLists {
-  private ProtobufLists() {}
-
-  public static <E> ProtobufList<E> emptyProtobufList() {
-    return ProtobufArrayList.emptyList();
-  }
-
-  public static <E> ProtobufList<E> mutableCopy(ProtobufList<E> list) {
-    int size = list.size();
-    return list.mutableCopyWithCapacity(
-        size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
-  }
-
-  public static BooleanList emptyBooleanList() {
-    return BooleanArrayList.emptyList();
-  }
-
-  public static BooleanList newBooleanList() {
-    return new BooleanArrayList();
-  }
-
-  public static IntList emptyIntList() {
-    return IntArrayList.emptyList();
-  }
-
-  public static IntList newIntList() {
-    return new IntArrayList();
-  }
-
-  public static LongList emptyLongList() {
-    return LongArrayList.emptyList();
-  }
-
-  public static LongList newLongList() {
-    return new LongArrayList();
-  }
-
-  public static FloatList emptyFloatList() {
-    return FloatArrayList.emptyList();
-  }
-
-  public static FloatList newFloatList() {
-    return new FloatArrayList();
-  }
-
-  public static DoubleList emptyDoubleList() {
-    return DoubleArrayList.emptyList();
-  }
-
-  public static DoubleList newDoubleList() {
-    return new DoubleArrayList();
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ProtocolStringList.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ProtocolStringList.java
deleted file mode 100644
index 5df3dbd..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ProtocolStringList.java
+++ /dev/null
@@ -1,46 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.util.List;
-
-/**
- * An interface extending {@code List<String>} used for repeated string fields to provide optional
- * access to the data as a list of ByteStrings. The underlying implementation stores values as
- * either ByteStrings or Strings (see {@link LazyStringArrayList}) depending on how the value was
- * initialized or last read, and it is often more efficient to deal with lists of ByteStrings when
- * handling protos that have been deserialized from bytes.
- */
-public interface ProtocolStringList extends List<String> {
-
-  /** Returns a view of the data as a list of ByteStrings. */
-  List<ByteString> asByteStringList();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/RawMessageInfo.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/RawMessageInfo.java
deleted file mode 100644
index d66f5c4..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/RawMessageInfo.java
+++ /dev/null
@@ -1,245 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-/**
- * RawMessageInfo stores the same amount of information as {@link MessageInfo} but in a more compact
- * format.
- */
-final class RawMessageInfo implements MessageInfo {
-
-  private final MessageLite defaultInstance;
-
-  /**
-   * The compact format packs everything in a String object and a Object[] array. The String object
-   * is encoded with field number, field type, hasbits offset, oneof index, etc., whereas the
-   * Object[] array contains field references, class references, instance references, etc.
-   *
-   * <p>The String object encodes a sequence of integers into UTF-16 characters. For each int, it
-   * will be encoding into 1 to 3 UTF-16 characters depending on its unsigned value:
-   *
-   * <ul>
-   *   <li>1 char: [c1: 0x0000 - 0xD7FF] = int of the same value.
-   *   <li>2 chars: [c1: 0xE000 - 0xFFFF], [c2: 0x0000 - 0xD7FF] = (c2 << 13) | (c1 & 0x1FFF)
-   *   <li>3 chars: [c1: 0xE000 - 0xFFFF], [c2: 0xE000 - 0xFFFF], [c3: 0x0000 - 0xD7FF] = (c3 << 26)
-   *       | ((c2 & 0x1FFF) << 13) | (c1 & 0x1FFF)
-   * </ul>
-   *
-   * <p>Note that we don't use UTF-16 surrogate pairs [0xD800 - 0xDFFF] because they have to come in
-   * pairs to form a valid UTF-16char sequence and don't help us encode values more efficiently.
-   *
-   * <p>The integer sequence encoded in the String object has the following layout:
-   *
-   * <ul>
-   *   <li>[0]: flags, flags & 0x1 = is proto2?, flags & 0x2 = is message?.
-   *   <li>[1]: field count, if 0, this is the end of the integer sequence and the corresponding
-   *       Object[] array should be null.
-   *   <li>[2]: oneof count
-   *   <li>[3]: hasbits count, how many hasbits integers are generated.
-   *   <li>[4]: min field number
-   *   <li>[5]: max field number
-   *   <li>[6]: total number of entries need to allocate
-   *   <li>[7]: map field count
-   *   <li>[8]: repeated field count, this doesn't include map fields.
-   *   <li>[9]: size of checkInitialized array
-   *   <li>[...]: field entries
-   * </ul>
-   *
-   * <p>Each field entry starts with a field number and the field type:
-   *
-   * <ul>
-   *   <li>[0]: field number
-   *   <li>[1]: field type with extra bits:
-   *       <ul>
-   *         <li>v & 0xFF = field type as defined in the FieldType class
-   *         <li>v & 0x0100 = is required?
-   *         <li>v & 0x0200 = is checkUtf8?
-   *         <li>v & 0x0400 = needs isInitialized check?
-   *         <li>v & 0x0800 = is map field with proto2 enum value?
-   *         <li>v & 0x1000 = supports presence checking?
-   *       </ul>
-   * </ul>
-   *
-   * If the (singular) field supports presence checking:
-   *
-   * <ul>
-   *   <li>[2]: hasbits offset
-   * </ul>
-   *
-   * If the field is in an oneof:
-   *
-   * <ul>
-   *   <li>[2]: oneof index
-   * </ul>
-   *
-   * For other types, the field entry only has field number and field type.
-   *
-   * <p>The Object[] array has 3 sections:
-   *
-   * <ul>
-   *   <li>---- oneof section ----
-   *       <ul>
-   *         <li>[0]: value field for oneof 1.
-   *         <li>[1]: case field for oneof 1.
-   *         <li>...
-   *         <li>[.]: value field for oneof n.
-   *         <li>[.]: case field for oneof n.
-   *       </ul>
-   *   <li>---- hasbits section ----
-   *       <ul>
-   *         <li>[.]: hasbits field 1
-   *         <li>[.]: hasbits field 2
-   *         <li>...
-   *         <li>[.]: hasbits field n
-   *       </ul>
-   *   <li>---- field section ----
-   *       <ul>
-   *         <li>[...]: field entries
-   *       </ul>
-   * </ul>
-   *
-   * <p>In the Object[] array, field entries are ordered in the same way as field entries in the
-   * String object. The size of each entry is determined by the field type.
-   *
-   * <ul>
-   *   <li>Oneof field:
-   *       <ul>
-   *         <li>Oneof message field:
-   *             <ul>
-   *               <li>[0]: message class reference.
-   *             </ul>
-   *         <li>Oneof enum fieldin proto2:
-   *             <ul>
-   *               <li>[0]: EnumLiteMap
-   *             </ul>
-   *         <li>For all other oneof fields, field entry in the Object[] array is empty.
-   *       </ul>
-   *   <li>Repeated message field:
-   *       <ul>
-   *         <li>[0]: field reference
-   *         <li>[1]: message class reference
-   *       </ul>
-   *   <li>Proto2 singular/repeated enum field:
-   *       <ul>
-   *         <li>[0]: field reference
-   *         <li>[1]: EnumLiteMap
-   *       </ul>
-   *   <li>Map field with a proto2 enum value:
-   *       <ul>
-   *         <li>[0]: field reference
-   *         <li>[1]: map default entry instance
-   *         <li>[2]: EnumLiteMap
-   *       </ul>
-   *   <li>Map field with other value types:
-   *       <ul>
-   *         <li>[0]: field reference
-   *         <li>[1]: map default entry instance
-   *       </ul>
-   *   <li>All other field type:
-   *       <ul>
-   *         <li>[0]: field reference
-   *       </ul>
-   * </ul>
-   *
-   * <p>In order to read the field info from this compact format, a reader needs to progress through
-   * the String object and the Object[] array simultaneously.
-   */
-  private final String info;
-
-  private final Object[] objects;
-  private final int flags;
-
-  RawMessageInfo(MessageLite defaultInstance, String info, Object[] objects) {
-    this.defaultInstance = defaultInstance;
-    this.info = info;
-    this.objects = objects;
-    int value;
-    try {
-      value = (int) info.charAt(0);
-    } catch (StringIndexOutOfBoundsException e) {
-      // This is a fix for issues
-      // that error out on a subset of phones on charAt(0) with an index out of bounds exception.
-      char[] infoChars = info.toCharArray();
-      info = new String(infoChars);
-      try {
-        value = (int) info.charAt(0);
-      } catch (StringIndexOutOfBoundsException e2) {
-        try {
-          char[] infoChars2 = new char[info.length()];
-          info.getChars(0, info.length(), infoChars2, 0);
-          info = new String(infoChars2);
-          value = (int) info.charAt(0);
-        } catch (StringIndexOutOfBoundsException | ArrayIndexOutOfBoundsException e3) {
-          throw new IllegalStateException(
-              String.format(
-                  "Failed parsing '%s' with charArray.length of %d", info, infoChars.length),
-              e3);
-        }
-      }
-    }
-    int position = 1;
-
-    if (value < 0xD800) {
-      flags = value;
-    } else {
-      int result = value & 0x1FFF;
-      int shift = 13;
-      while ((value = info.charAt(position++)) >= 0xD800) {
-        result |= (value & 0x1FFF) << shift;
-        shift += 13;
-      }
-      flags = result | (value << shift);
-    }
-  }
-
-  String getStringInfo() {
-    return info;
-  }
-
-  Object[] getObjects() {
-    return objects;
-  }
-
-  @Override
-  public MessageLite getDefaultInstance() {
-    return defaultInstance;
-  }
-
-  @Override
-  public ProtoSyntax getSyntax() {
-    return (flags & 0x1) == 0x1 ? ProtoSyntax.PROTO2 : ProtoSyntax.PROTO3;
-  }
-
-  @Override
-  public boolean isMessageSetWireFormat() {
-    return (flags & 0x2) == 0x2;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Reader.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Reader.java
deleted file mode 100644
index 705096f..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Reader.java
+++ /dev/null
@@ -1,379 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-
-/** A reader of fields from a serialized protobuf message. */
-// TODO(nathanmittler): Refactor to allow the reader to allocate properly sized lists.
-@ExperimentalApi
-interface Reader {
-  /** Value used to indicate that the end of input has been reached. */
-  int READ_DONE = Integer.MAX_VALUE;
-
-  /** Value used to indicate that the reader does not know the tag about the field. */
-  int TAG_UNKNOWN = 0;
-
-  boolean shouldDiscardUnknownFields();
-
-  /**
-   * Gets the field number for the current field being read.
-   *
-   * <p>TODO(liujisi): Rename it to make it more explicit about the side effect on the underlying
-   * buffer.
-   *
-   * @return the current field number or {@link #READ_DONE} if the end of input has been reached.
-   */
-  int getFieldNumber() throws IOException;
-
-  /**
-   * Gets the wire tag of the current field.
-   *
-   * @return the current wire tag or {@link #TAG_UNKNOWN} if the reader does not know the tag of the
-   *     current field.
-   */
-  int getTag();
-
-  /**
-   * Skips the current field and advances the reader to the next field.
-   *
-   * @return {@code true} if there are more fields or {@code false} if the end of input has been
-   *     reached.
-   */
-  boolean skipField() throws IOException;
-
-  /**
-   * Reads and returns the next field of type {@code DOUBLE} and advances the reader to the next
-   * field.
-   */
-  double readDouble() throws IOException;
-
-  /**
-   * Reads and returns the next field of type {@code FLOAT} and advances the reader to the next
-   * field.
-   */
-  float readFloat() throws IOException;
-
-  /**
-   * Reads and returns the next field of type {@code UINT64} and advances the reader to the next
-   * field.
-   */
-  long readUInt64() throws IOException;
-
-  /**
-   * Reads and returns the next field of type {@code INT64} and advances the reader to the next
-   * field.
-   */
-  long readInt64() throws IOException;
-
-  /**
-   * Reads and returns the next field of type {@code INT32} and advances the reader to the next
-   * field.
-   */
-  int readInt32() throws IOException;
-
-  /**
-   * Reads and returns the next field of type {@code FIXED64} and advances the reader to the next
-   * field.
-   */
-  long readFixed64() throws IOException;
-
-  /**
-   * Reads and returns the next field of type {@code FIXED32} and advances the reader to the next
-   * field.
-   */
-  int readFixed32() throws IOException;
-
-  /**
-   * Reads and returns the next field of type {@code BOOL} and advances the reader to the next
-   * field.
-   */
-  boolean readBool() throws IOException;
-
-  /**
-   * Reads and returns the next field of type {@code STRING} and advances the reader to the next
-   * field. If the stream contains malformed UTF-8, replace the offending bytes with the standard
-   * UTF-8 replacement character.
-   */
-  String readString() throws IOException;
-
-  /**
-   * Reads and returns the next field of type {@code STRING} and advances the reader to the next
-   * field. If the stream contains malformed UTF-8, throw exception {@link
-   * InvalidProtocolBufferException}.
-   */
-  String readStringRequireUtf8() throws IOException;
-
-  // TODO(yilunchong): the lack of other opinions for whether to expose this on the interface
-  <T> T readMessageBySchemaWithCheck(Schema<T> schema, ExtensionRegistryLite extensionRegistry)
-      throws IOException;
-
-  /**
-   * Reads and returns the next field of type {@code MESSAGE} and advances the reader to the next
-   * field.
-   */
-  <T> T readMessage(Class<T> clazz, ExtensionRegistryLite extensionRegistry) throws IOException;
-
-  /**
-   * Reads and returns the next field of type {@code GROUP} and advances the reader to the next
-   * field.
-   *
-   * @deprecated groups fields are deprecated.
-   */
-  @Deprecated
-  <T> T readGroup(Class<T> clazz, ExtensionRegistryLite extensionRegistry) throws IOException;
-
-  // TODO(yilunchong): the lack of other opinions for whether to expose this on the interface
-  @Deprecated
-  <T> T readGroupBySchemaWithCheck(Schema<T> schema, ExtensionRegistryLite extensionRegistry)
-      throws IOException;
-
-  /**
-   * Reads and returns the next field of type {@code BYTES} and advances the reader to the next
-   * field.
-   */
-  ByteString readBytes() throws IOException;
-
-  /**
-   * Reads and returns the next field of type {@code UINT32} and advances the reader to the next
-   * field.
-   */
-  int readUInt32() throws IOException;
-
-  /**
-   * Reads and returns the next field of type {@code ENUM} and advances the reader to the next
-   * field.
-   */
-  int readEnum() throws IOException;
-
-  /**
-   * Reads and returns the next field of type {@code SFIXED32} and advances the reader to the next
-   * field.
-   */
-  int readSFixed32() throws IOException;
-
-  /**
-   * Reads and returns the next field of type {@code SFIXED64} and advances the reader to the next
-   * field.
-   */
-  long readSFixed64() throws IOException;
-
-  /**
-   * Reads and returns the next field of type {@code SINT32} and advances the reader to the next
-   * field.
-   */
-  int readSInt32() throws IOException;
-
-  /**
-   * Reads and returns the next field of type {@code SINT64} and advances the reader to the next
-   * field.
-   */
-  long readSInt64() throws IOException;
-
-  /**
-   * Reads the next field of type {@code DOUBLE_LIST} or {@code DOUBLE_LIST_PACKED} and advances the
-   * reader to the next field.
-   *
-   * @param target the list that will receive the read values.
-   */
-  void readDoubleList(List<Double> target) throws IOException;
-
-  /**
-   * Reads the next field of type {@code FLOAT_LIST} or {@code FLOAT_LIST_PACKED} and advances the
-   * reader to the next field.
-   *
-   * @param target the list that will receive the read values.
-   */
-  void readFloatList(List<Float> target) throws IOException;
-
-  /**
-   * Reads the next field of type {@code UINT64_LIST} or {@code UINT64_LIST_PACKED} and advances the
-   * reader to the next field.
-   *
-   * @param target the list that will receive the read values.
-   */
-  void readUInt64List(List<Long> target) throws IOException;
-
-  /**
-   * Reads the next field of type {@code INT64_LIST} or {@code INT64_LIST_PACKED} and advances the
-   * reader to the next field.
-   *
-   * @param target the list that will receive the read values.
-   */
-  void readInt64List(List<Long> target) throws IOException;
-
-  /**
-   * Reads the next field of type {@code INT32_LIST} or {@code INT32_LIST_PACKED} and advances the
-   * reader to the next field.
-   *
-   * @param target the list that will receive the read values.
-   */
-  void readInt32List(List<Integer> target) throws IOException;
-
-  /**
-   * Reads the next field of type {@code FIXED64_LIST} or {@code FIXED64_LIST_PACKED} and advances
-   * the reader to the next field.
-   *
-   * @param target the list that will receive the read values.
-   */
-  void readFixed64List(List<Long> target) throws IOException;
-
-  /**
-   * Reads the next field of type {@code FIXED32_LIST} or {@code FIXED32_LIST_PACKED} and advances
-   * the reader to the next field.
-   *
-   * @param target the list that will receive the read values.
-   */
-  void readFixed32List(List<Integer> target) throws IOException;
-
-  /**
-   * Reads the next field of type {@code BOOL_LIST} or {@code BOOL_LIST_PACKED} and advances the
-   * reader to the next field.
-   *
-   * @param target the list that will receive the read values.
-   */
-  void readBoolList(List<Boolean> target) throws IOException;
-
-  /**
-   * Reads the next field of type {@code STRING_LIST} and advances the reader to the next field.
-   *
-   * @param target the list that will receive the read values.
-   */
-  void readStringList(List<String> target) throws IOException;
-
-  /**
-   * Reads the next field of type {@code STRING_LIST} and advances the reader to the next field. If
-   * the stream contains malformed UTF-8, throw exception {@link InvalidProtocolBufferException}.
-   *
-   * @param target the list that will receive the read values.
-   */
-  void readStringListRequireUtf8(List<String> target) throws IOException;
-
-  /**
-   * Reads the next field of type {@code MESSAGE_LIST} and advances the reader to the next field.
-   *
-   * @param target the list that will receive the read values.
-   * @param targetType the type of the elements stored in the {@code target} list.
-   */
-  <T> void readMessageList(
-      List<T> target, Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException;
-
-  <T> void readMessageList(
-      List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry)
-      throws IOException;
-
-  /**
-   * Reads the next field of type {@code GROUP_LIST} and advances the reader to the next field.
-   *
-   * @param target the list that will receive the read values.
-   * @param targetType the type of the elements stored in the {@code target} list.
-   * @deprecated groups fields are deprecated.
-   */
-  @Deprecated
-  <T> void readGroupList(
-      List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry)
-      throws IOException;
-
-  @Deprecated
-  <T> void readGroupList(
-      List<T> target, Schema<T> targetType, ExtensionRegistryLite extensionRegistry)
-      throws IOException;
-
-  /**
-   * Reads the next field of type {@code BYTES_LIST} and advances the reader to the next field.
-   *
-   * @param target the list that will receive the read values.
-   */
-  void readBytesList(List<ByteString> target) throws IOException;
-
-  /**
-   * Reads the next field of type {@code UINT32_LIST} or {@code UINT32_LIST_PACKED} and advances the
-   * reader to the next field.
-   *
-   * @param target the list that will receive the read values.
-   */
-  void readUInt32List(List<Integer> target) throws IOException;
-
-  /**
-   * Reads the next field of type {@code ENUM_LIST} or {@code ENUM_LIST_PACKED} and advances the
-   * reader to the next field.
-   *
-   * @param target the list that will receive the read values.
-   */
-  void readEnumList(List<Integer> target) throws IOException;
-
-  /**
-   * Reads the next field of type {@code SFIXED32_LIST} or {@code SFIXED32_LIST_PACKED} and advances
-   * the reader to the next field.
-   *
-   * @param target the list that will receive the read values.
-   */
-  void readSFixed32List(List<Integer> target) throws IOException;
-
-  /**
-   * Reads the next field of type {@code SFIXED64_LIST} or {@code SFIXED64_LIST_PACKED} and advances
-   * the reader to the next field.
-   *
-   * @param target the list that will receive the read values.
-   */
-  void readSFixed64List(List<Long> target) throws IOException;
-
-  /**
-   * Reads the next field of type {@code SINT32_LIST} or {@code SINT32_LIST_PACKED} and advances the
-   * reader to the next field.
-   *
-   * @param target the list that will receive the read values.
-   */
-  void readSInt32List(List<Integer> target) throws IOException;
-
-  /**
-   * Reads the next field of type {@code SINT64_LIST} or {@code SINT64_LIST_PACKED} and advances the
-   * reader to the next field.
-   *
-   * @param target the list that will receive the read values.
-   */
-  void readSInt64List(List<Long> target) throws IOException;
-
-  /**
-   * Reads the next field of type {@code MAP} and advances the reader to the next field.
-   *
-   * @param target the mutable map that will receive the read values.
-   * @param mapDefaultEntry the default entry of the map field.
-   * @param extensionRegistry the extension registry for parsing message value fields.
-   */
-  <K, V> void readMap(
-      Map<K, V> target,
-      MapEntryLite.Metadata<K, V> mapDefaultEntry,
-      ExtensionRegistryLite extensionRegistry)
-      throws IOException;
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/RopeByteString.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/RopeByteString.java
deleted file mode 100644
index f584164..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/RopeByteString.java
+++ /dev/null
@@ -1,972 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InvalidObjectException;
-import java.io.ObjectInputStream;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-/**
- * Class to represent {@code ByteStrings} formed by concatenation of other ByteStrings, without
- * copying the data in the pieces. The concatenation is represented as a tree whose leaf nodes are
- * each a {@link com.google.protobuf.ByteString.LeafByteString}.
- *
- * <p>Most of the operation here is inspired by the now-famous paper <a
- * href="https://web.archive.org/web/20060202015456/http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol25/issue12/spe986.pdf">
- * BAP95 </a> Ropes: an Alternative to Strings hans-j. boehm, russ atkinson and michael plass
- *
- * <p>The algorithms described in the paper have been implemented for character strings in {@code
- * com.google.common.string.Rope} and in the c++ class {@code cord.cc}.
- *
- * <p>Fundamentally the Rope algorithm represents the collection of pieces as a binary tree. BAP95
- * uses a Fibonacci bound relating depth to a minimum sequence length, sequences that are too short
- * relative to their depth cause a tree rebalance. More precisely, a tree of depth d is "balanced"
- * in the terminology of BAP95 if its length is at least F(d+2), where F(n) is the n-th Fibonacci
- * number. Thus for depths 0, 1, 2, 3, 4, 5,... we have minimum lengths 1, 2, 3, 5, 8, 13,...
- *
- * @author carlanton@google.com (Carl Haverl)
- */
-final class RopeByteString extends ByteString {
-
-  /**
-   * BAP95. Let Fn be the nth Fibonacci number. A {@link RopeByteString} of depth n is "balanced",
-   * i.e flat enough, if its length is at least Fn+2, e.g. a "balanced" {@link RopeByteString} of
-   * depth 1 must have length at least 2, of depth 4 must have length >= 8, etc.
-   *
-   * <p>There's nothing special about using the Fibonacci numbers for this, but they are a
-   * reasonable sequence for encapsulating the idea that we are OK with longer strings being encoded
-   * in deeper binary trees.
-   *
-   * <p>For 32-bit integers, this array has length 46.
-   *
-   * <p>The correctness of this constant array is validated in tests.
-   */
-  static final int[] minLengthByDepth = {
-    1,
-    1,
-    2,
-    3,
-    5,
-    8,
-    13,
-    21,
-    34,
-    55,
-    89,
-    144,
-    233,
-    377,
-    610,
-    987,
-    1597,
-    2584,
-    4181,
-    6765,
-    10946,
-    17711,
-    28657,
-    46368,
-    75025,
-    121393,
-    196418,
-    317811,
-    514229,
-    832040,
-    1346269,
-    2178309,
-    3524578,
-    5702887,
-    9227465,
-    14930352,
-    24157817,
-    39088169,
-    63245986,
-    102334155,
-    165580141,
-    267914296,
-    433494437,
-    701408733,
-    1134903170,
-    1836311903,
-    Integer.MAX_VALUE
-  };
-
-  private final int totalLength;
-  private final ByteString left;
-  private final ByteString right;
-  private final int leftLength;
-  private final int treeDepth;
-
-  /**
-   * Create a new RopeByteString, which can be thought of as a new tree node, by recording
-   * references to the two given strings.
-   *
-   * @param left string on the left of this node, should have {@code size() > 0}
-   * @param right string on the right of this node, should have {@code size() > 0}
-   */
-  private RopeByteString(ByteString left, ByteString right) {
-    this.left = left;
-    this.right = right;
-    leftLength = left.size();
-    totalLength = leftLength + right.size();
-    treeDepth = Math.max(left.getTreeDepth(), right.getTreeDepth()) + 1;
-  }
-
-  /**
-   * Concatenate the given strings while performing various optimizations to slow the growth rate of
-   * tree depth and tree node count. The result is either a {@link
-   * com.google.protobuf.ByteString.LeafByteString} or a {@link RopeByteString} depending on which
-   * optimizations, if any, were applied.
-   *
-   * <p>Small pieces of length less than {@link ByteString#CONCATENATE_BY_COPY_SIZE} may be copied
-   * by value here, as in BAP95. Large pieces are referenced without copy.
-   *
-   * @param left string on the left
-   * @param right string on the right
-   * @return concatenation representing the same sequence as the given strings
-   */
-  static ByteString concatenate(ByteString left, ByteString right) {
-    if (right.size() == 0) {
-      return left;
-    }
-
-    if (left.size() == 0) {
-      return right;
-    }
-
-    final int newLength = left.size() + right.size();
-    if (newLength < ByteString.CONCATENATE_BY_COPY_SIZE) {
-      // Optimization from BAP95: For short (leaves in paper, but just short
-      // here) total length, do a copy of data to a new leaf.
-      return concatenateBytes(left, right);
-    }
-
-    if (left instanceof RopeByteString) {
-      final RopeByteString leftRope = (RopeByteString) left;
-      if (leftRope.right.size() + right.size() < CONCATENATE_BY_COPY_SIZE) {
-        // Optimization from BAP95: As an optimization of the case where the
-        // ByteString is constructed by repeated concatenate, recognize the case
-        // where a short string is concatenated to a left-hand node whose
-        // right-hand branch is short.  In the paper this applies to leaves, but
-        // we just look at the length here. This has the advantage of shedding
-        // references to unneeded data when substrings have been taken.
-        //
-        // When we recognize this case, we do a copy of the data and create a
-        // new parent node so that the depth of the result is the same as the
-        // given left tree.
-        ByteString newRight = concatenateBytes(leftRope.right, right);
-        return new RopeByteString(leftRope.left, newRight);
-      }
-
-      if (leftRope.left.getTreeDepth() > leftRope.right.getTreeDepth()
-          && leftRope.getTreeDepth() > right.getTreeDepth()) {
-        // Typically for concatenate-built strings the left-side is deeper than
-        // the right.  This is our final attempt to concatenate without
-        // increasing the tree depth.  We'll redo the node on the RHS.  This
-        // is yet another optimization for building the string by repeatedly
-        // concatenating on the right.
-        ByteString newRight = new RopeByteString(leftRope.right, right);
-        return new RopeByteString(leftRope.left, newRight);
-      }
-    }
-
-    // Fine, we'll add a node and increase the tree depth--unless we rebalance ;^)
-    int newDepth = Math.max(left.getTreeDepth(), right.getTreeDepth()) + 1;
-    if (newLength >= minLength(newDepth)) {
-      // The tree is shallow enough, so don't rebalance
-      return new RopeByteString(left, right);
-    }
-
-    return new Balancer().balance(left, right);
-  }
-
-  /**
-   * Concatenates two strings by copying data values. This is called in a few cases in order to
-   * reduce the growth of the number of tree nodes.
-   *
-   * @param left string on the left
-   * @param right string on the right
-   * @return string formed by copying data bytes
-   */
-  private static ByteString concatenateBytes(ByteString left, ByteString right) {
-    int leftSize = left.size();
-    int rightSize = right.size();
-    byte[] bytes = new byte[leftSize + rightSize];
-    left.copyTo(bytes, 0, 0, leftSize);
-    right.copyTo(bytes, 0, leftSize, rightSize);
-    return ByteString.wrap(bytes); // Constructor wraps bytes
-  }
-
-  /**
-   * Create a new RopeByteString for testing only while bypassing all the defenses of {@link
-   * #concatenate(ByteString, ByteString)}. This allows testing trees of specific structure. We are
-   * also able to insert empty leaves, though these are dis-allowed, so that we can make sure the
-   * implementation can withstand their presence.
-   *
-   * @param left string on the left of this node
-   * @param right string on the right of this node
-   * @return an unsafe instance for testing only
-   */
-  static RopeByteString newInstanceForTest(ByteString left, ByteString right) {
-    return new RopeByteString(left, right);
-  }
-
-  /**
-   * Returns the minimum length for which a tree of the given depth is considered balanced according
-   * to BAP95, which means the tree is flat-enough with respect to the bounds. Defaults to {@code
-   * Integer.MAX_VALUE} if {@code depth >= minLengthByDepth.length} in order to avoid an {@code
-   * ArrayIndexOutOfBoundsException}.
-   *
-   * @param depth tree depth
-   * @return minimum balanced length
-   */
-  static int minLength(int depth) {
-    if (depth >= minLengthByDepth.length) {
-      return Integer.MAX_VALUE;
-    }
-    return minLengthByDepth[depth];
-  }
-
-  /**
-   * Gets the byte at the given index. Throws {@link ArrayIndexOutOfBoundsException} for
-   * backwards-compatibility reasons although it would more properly be {@link
-   * IndexOutOfBoundsException}.
-   *
-   * @param index index of byte
-   * @return the value
-   * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size
-   */
-  @Override
-  public byte byteAt(int index) {
-    checkIndex(index, totalLength);
-    return internalByteAt(index);
-  }
-
-  @Override
-  byte internalByteAt(int index) {
-    // Find the relevant piece by recursive descent
-    if (index < leftLength) {
-      return left.internalByteAt(index);
-    }
-
-    return right.internalByteAt(index - leftLength);
-  }
-
-  @Override
-  public int size() {
-    return totalLength;
-  }
-
-  @Override
-  public ByteIterator iterator() {
-    return new AbstractByteIterator() {
-      final PieceIterator pieces = new PieceIterator(RopeByteString.this);
-      ByteIterator current = nextPiece();
-
-      private ByteIterator nextPiece() {
-        // NOTE: PieceIterator is guaranteed to return non-empty pieces, so this method will always
-        // return non-empty iterators (or null)
-        return pieces.hasNext() ? pieces.next().iterator() : null;
-      }
-
-      @Override
-      public boolean hasNext() {
-        return current != null;
-      }
-
-      @Override
-      public byte nextByte() {
-        if (current == null) {
-          throw new NoSuchElementException();
-        }
-        byte b = current.nextByte();
-        if (!current.hasNext()) {
-          current = nextPiece();
-        }
-        return b;
-      }
-    };
-  }
-
-  // =================================================================
-  // Pieces
-
-  @Override
-  protected int getTreeDepth() {
-    return treeDepth;
-  }
-
-  /**
-   * Determines if the tree is balanced according to BAP95, which means the tree is flat-enough with
-   * respect to the bounds. Note that this definition of balanced is one where sub-trees of balanced
-   * trees are not necessarily balanced.
-   *
-   * @return true if the tree is balanced
-   */
-  @Override
-  protected boolean isBalanced() {
-    return totalLength >= minLength(treeDepth);
-  }
-
-  /**
-   * Takes a substring of this one. This involves recursive descent along the left and right edges
-   * of the substring, and referencing any wholly contained segments in between. Any leaf nodes
-   * entirely uninvolved in the substring will not be referenced by the substring.
-   *
-   * <p>Substrings of {@code length < 2} should result in at most a single recursive call chain,
-   * terminating at a leaf node. Thus the result will be a {@link
-   * com.google.protobuf.ByteString.LeafByteString}.
-   *
-   * @param beginIndex start at this index
-   * @param endIndex the last character is the one before this index
-   * @return substring leaf node or tree
-   */
-  @Override
-  public ByteString substring(int beginIndex, int endIndex) {
-    final int length = checkRange(beginIndex, endIndex, totalLength);
-
-    if (length == 0) {
-      // Empty substring
-      return ByteString.EMPTY;
-    }
-
-    if (length == totalLength) {
-      // The whole string
-      return this;
-    }
-
-    // Proper substring
-    if (endIndex <= leftLength) {
-      // Substring on the left
-      return left.substring(beginIndex, endIndex);
-    }
-
-    if (beginIndex >= leftLength) {
-      // Substring on the right
-      return right.substring(beginIndex - leftLength, endIndex - leftLength);
-    }
-
-    // Split substring
-    ByteString leftSub = left.substring(beginIndex);
-    ByteString rightSub = right.substring(0, endIndex - leftLength);
-    // Intentionally not rebalancing, since in many cases these two
-    // substrings will already be less deep than the top-level
-    // RopeByteString we're taking a substring of.
-    return new RopeByteString(leftSub, rightSub);
-  }
-
-  // =================================================================
-  // ByteString -> byte[]
-
-  @Override
-  protected void copyToInternal(
-      byte[] target, int sourceOffset, int targetOffset, int numberToCopy) {
-    if (sourceOffset + numberToCopy <= leftLength) {
-      left.copyToInternal(target, sourceOffset, targetOffset, numberToCopy);
-    } else if (sourceOffset >= leftLength) {
-      right.copyToInternal(target, sourceOffset - leftLength, targetOffset, numberToCopy);
-    } else {
-      int leftLength = this.leftLength - sourceOffset;
-      left.copyToInternal(target, sourceOffset, targetOffset, leftLength);
-      right.copyToInternal(target, 0, targetOffset + leftLength, numberToCopy - leftLength);
-    }
-  }
-
-  @Override
-  public void copyTo(ByteBuffer target) {
-    left.copyTo(target);
-    right.copyTo(target);
-  }
-
-  @Override
-  public ByteBuffer asReadOnlyByteBuffer() {
-    ByteBuffer byteBuffer = ByteBuffer.wrap(toByteArray());
-    return byteBuffer.asReadOnlyBuffer();
-  }
-
-  @Override
-  public List<ByteBuffer> asReadOnlyByteBufferList() {
-    // Walk through the list of LeafByteString's that make up this
-    // rope, and add each one as a read-only ByteBuffer.
-    List<ByteBuffer> result = new ArrayList<ByteBuffer>();
-    PieceIterator pieces = new PieceIterator(this);
-    while (pieces.hasNext()) {
-      LeafByteString byteString = pieces.next();
-      result.add(byteString.asReadOnlyByteBuffer());
-    }
-    return result;
-  }
-
-  @Override
-  public void writeTo(OutputStream outputStream) throws IOException {
-    left.writeTo(outputStream);
-    right.writeTo(outputStream);
-  }
-
-  @Override
-  void writeToInternal(OutputStream out, int sourceOffset, int numberToWrite) throws IOException {
-    if (sourceOffset + numberToWrite <= leftLength) {
-      left.writeToInternal(out, sourceOffset, numberToWrite);
-    } else if (sourceOffset >= leftLength) {
-      right.writeToInternal(out, sourceOffset - leftLength, numberToWrite);
-    } else {
-      int numberToWriteInLeft = leftLength - sourceOffset;
-      left.writeToInternal(out, sourceOffset, numberToWriteInLeft);
-      right.writeToInternal(out, 0, numberToWrite - numberToWriteInLeft);
-    }
-  }
-
-  @Override
-  void writeTo(ByteOutput output) throws IOException {
-    left.writeTo(output);
-    right.writeTo(output);
-  }
-
-  @Override
-  void writeToReverse(ByteOutput output) throws IOException {
-    right.writeToReverse(output);
-    left.writeToReverse(output);
-  }
-
-  @Override
-  protected String toStringInternal(Charset charset) {
-    return new String(toByteArray(), charset);
-  }
-
-  // =================================================================
-  // UTF-8 decoding
-
-  @Override
-  public boolean isValidUtf8() {
-    int leftPartial = left.partialIsValidUtf8(Utf8.COMPLETE, 0, leftLength);
-    int state = right.partialIsValidUtf8(leftPartial, 0, right.size());
-    return state == Utf8.COMPLETE;
-  }
-
-  @Override
-  protected int partialIsValidUtf8(int state, int offset, int length) {
-    int toIndex = offset + length;
-    if (toIndex <= leftLength) {
-      return left.partialIsValidUtf8(state, offset, length);
-    } else if (offset >= leftLength) {
-      return right.partialIsValidUtf8(state, offset - leftLength, length);
-    } else {
-      int leftLength = this.leftLength - offset;
-      int leftPartial = left.partialIsValidUtf8(state, offset, leftLength);
-      return right.partialIsValidUtf8(leftPartial, 0, length - leftLength);
-    }
-  }
-
-  // =================================================================
-  // equals() and hashCode()
-
-  @Override
-  public boolean equals(Object other) {
-    if (other == this) {
-      return true;
-    }
-    if (!(other instanceof ByteString)) {
-      return false;
-    }
-
-    ByteString otherByteString = (ByteString) other;
-    if (totalLength != otherByteString.size()) {
-      return false;
-    }
-    if (totalLength == 0) {
-      return true;
-    }
-
-    // You don't really want to be calling equals on long strings, but since
-    // we cache the hashCode, we effectively cache inequality. We use the cached
-    // hashCode if it's already computed.  It's arguable we should compute the
-    // hashCode here, and if we're going to be testing a bunch of byteStrings,
-    // it might even make sense.
-    int thisHash = peekCachedHashCode();
-    int thatHash = otherByteString.peekCachedHashCode();
-    if (thisHash != 0 && thatHash != 0 && thisHash != thatHash) {
-      return false;
-    }
-
-    return equalsFragments(otherByteString);
-  }
-
-  /**
-   * Determines if this string is equal to another of the same length by iterating over the leaf
-   * nodes. On each step of the iteration, the overlapping segments of the leaves are compared.
-   *
-   * @param other string of the same length as this one
-   * @return true if the values of this string equals the value of the given one
-   */
-  private boolean equalsFragments(ByteString other) {
-    int thisOffset = 0;
-    Iterator<LeafByteString> thisIter = new PieceIterator(this);
-    LeafByteString thisString = thisIter.next();
-
-    int thatOffset = 0;
-    Iterator<LeafByteString> thatIter = new PieceIterator(other);
-    LeafByteString thatString = thatIter.next();
-
-    int pos = 0;
-    while (true) {
-      int thisRemaining = thisString.size() - thisOffset;
-      int thatRemaining = thatString.size() - thatOffset;
-      int bytesToCompare = Math.min(thisRemaining, thatRemaining);
-
-      // At least one of the offsets will be zero
-      boolean stillEqual =
-          (thisOffset == 0)
-              ? thisString.equalsRange(thatString, thatOffset, bytesToCompare)
-              : thatString.equalsRange(thisString, thisOffset, bytesToCompare);
-      if (!stillEqual) {
-        return false;
-      }
-
-      pos += bytesToCompare;
-      if (pos >= totalLength) {
-        if (pos == totalLength) {
-          return true;
-        }
-        throw new IllegalStateException();
-      }
-      // We always get to the end of at least one of the pieces
-      if (bytesToCompare == thisRemaining) { // If reached end of this
-        thisOffset = 0;
-        thisString = thisIter.next();
-      } else {
-        thisOffset += bytesToCompare;
-      }
-      if (bytesToCompare == thatRemaining) { // If reached end of that
-        thatOffset = 0;
-        thatString = thatIter.next();
-      } else {
-        thatOffset += bytesToCompare;
-      }
-    }
-  }
-
-  @Override
-  protected int partialHash(int h, int offset, int length) {
-    int toIndex = offset + length;
-    if (toIndex <= leftLength) {
-      return left.partialHash(h, offset, length);
-    } else if (offset >= leftLength) {
-      return right.partialHash(h, offset - leftLength, length);
-    } else {
-      int leftLength = this.leftLength - offset;
-      int leftPartial = left.partialHash(h, offset, leftLength);
-      return right.partialHash(leftPartial, 0, length - leftLength);
-    }
-  }
-
-  // =================================================================
-  // Input stream
-
-  @Override
-  public CodedInputStream newCodedInput() {
-    // Passing along direct references to internal ByteBuffers can support more efficient parsing
-    // via aliasing in CodedInputStream for users who wish to use it.
-    //
-    // Otherwise we force data copies, both in copying as an input stream and in buffering in the
-    // CodedInputSteam.
-    return CodedInputStream.newInstance(asReadOnlyByteBufferList(), /* bufferIsImmutable= */ true);
-  }
-
-  @Override
-  public InputStream newInput() {
-    return new RopeInputStream();
-  }
-
-  /**
-   * This class implements the balancing algorithm of BAP95. In the paper the authors use an array
-   * to keep track of pieces, while here we use a stack. The tree is balanced by traversing subtrees
-   * in left to right order, and the stack always contains the part of the string we've traversed so
-   * far.
-   *
-   * <p>One surprising aspect of the algorithm is the result of balancing is not necessarily
-   * balanced, though it is nearly balanced. For details, see BAP95.
-   */
-  private static class Balancer {
-    // Stack containing the part of the string, starting from the left, that
-    // we've already traversed.  The final string should be the equivalent of
-    // concatenating the strings on the stack from bottom to top.
-    private final ArrayDeque<ByteString> prefixesStack = new ArrayDeque<>();
-
-    private ByteString balance(ByteString left, ByteString right) {
-      doBalance(left);
-      doBalance(right);
-
-      // Sweep stack to gather the result
-      ByteString partialString = prefixesStack.pop();
-      while (!prefixesStack.isEmpty()) {
-        ByteString newLeft = prefixesStack.pop();
-        partialString = new RopeByteString(newLeft, partialString);
-      }
-      // We should end up with a RopeByteString since at a minimum we will
-      // create one from concatenating left and right
-      return partialString;
-    }
-
-    private void doBalance(ByteString root) {
-      // BAP95: Insert balanced subtrees whole. This means the result might not
-      // be balanced, leading to repeated rebalancings on concatenate. However,
-      // these rebalancings are shallow due to ignoring balanced subtrees, and
-      // relatively few calls to insert() result.
-      if (root.isBalanced()) {
-        insert(root);
-      } else if (root instanceof RopeByteString) {
-        RopeByteString rbs = (RopeByteString) root;
-        doBalance(rbs.left);
-        doBalance(rbs.right);
-      } else {
-        throw new IllegalArgumentException(
-            "Has a new type of ByteString been created? Found " + root.getClass());
-      }
-    }
-
-    /**
-     * Push a string on the balance stack (BAP95). BAP95 uses an array and calls the elements in the
-     * array 'bins'. We instead use a stack, so the 'bins' of lengths are represented by differences
-     * between the elements of minLengthByDepth.
-     *
-     * <p>If the length bin for our string, and all shorter length bins, are empty, we just push it
-     * on the stack. Otherwise, we need to start concatenating, putting the given string in the
-     * "middle" and continuing until we land in an empty length bin that matches the length of our
-     * concatenation.
-     *
-     * @param byteString string to place on the balance stack
-     */
-    private void insert(ByteString byteString) {
-      int depthBin = getDepthBinForLength(byteString.size());
-      int binEnd = minLength(depthBin + 1);
-
-      // BAP95: Concatenate all trees occupying bins representing the length of
-      // our new piece or of shorter pieces, to the extent that is possible.
-      // The goal is to clear the bin which our piece belongs in, but that may
-      // not be entirely possible if there aren't enough longer bins occupied.
-      if (prefixesStack.isEmpty() || prefixesStack.peek().size() >= binEnd) {
-        prefixesStack.push(byteString);
-      } else {
-        int binStart = minLength(depthBin);
-
-        // Concatenate the subtrees of shorter length
-        ByteString newTree = prefixesStack.pop();
-        while (!prefixesStack.isEmpty() && prefixesStack.peek().size() < binStart) {
-          ByteString left = prefixesStack.pop();
-          newTree = new RopeByteString(left, newTree);
-        }
-
-        // Concatenate the given string
-        newTree = new RopeByteString(newTree, byteString);
-
-        // Continue concatenating until we land in an empty bin
-        while (!prefixesStack.isEmpty()) {
-          depthBin = getDepthBinForLength(newTree.size());
-          binEnd = minLength(depthBin + 1);
-          if (prefixesStack.peek().size() < binEnd) {
-            ByteString left = prefixesStack.pop();
-            newTree = new RopeByteString(left, newTree);
-          } else {
-            break;
-          }
-        }
-        prefixesStack.push(newTree);
-      }
-    }
-
-    private int getDepthBinForLength(int length) {
-      int depth = Arrays.binarySearch(minLengthByDepth, length);
-      if (depth < 0) {
-        // It wasn't an exact match, so convert to the index of the containing
-        // fragment, which is one less even than the insertion point.
-        int insertionPoint = -(depth + 1);
-        depth = insertionPoint - 1;
-      }
-
-      return depth;
-    }
-  }
-
-  /**
-   * This class is a continuable tree traversal, which keeps the state information which would exist
-   * on the stack in a recursive traversal instead on a stack of "Bread Crumbs". The maximum depth
-   * of the stack in this iterator is the same as the depth of the tree being traversed.
-   *
-   * <p>This iterator is used to implement {@link RopeByteString#equalsFragments(ByteString)}.
-   */
-  private static final class PieceIterator implements Iterator<LeafByteString> {
-    private final ArrayDeque<RopeByteString> breadCrumbs;
-    private LeafByteString next;
-
-    private PieceIterator(ByteString root) {
-      if (root instanceof RopeByteString) {
-        RopeByteString rbs = (RopeByteString) root;
-        breadCrumbs = new ArrayDeque<>(rbs.getTreeDepth());
-        breadCrumbs.push(rbs);
-        next = getLeafByLeft(rbs.left);
-      } else {
-        breadCrumbs = null;
-        next = (LeafByteString) root;
-      }
-    }
-
-    private LeafByteString getLeafByLeft(ByteString root) {
-      ByteString pos = root;
-      while (pos instanceof RopeByteString) {
-        RopeByteString rbs = (RopeByteString) pos;
-        breadCrumbs.push(rbs);
-        pos = rbs.left;
-      }
-      return (LeafByteString) pos;
-    }
-
-    private LeafByteString getNextNonEmptyLeaf() {
-      while (true) {
-        // Almost always, we go through this loop exactly once.  However, if
-        // we discover an empty string in the rope, we toss it and try again.
-        if (breadCrumbs == null || breadCrumbs.isEmpty()) {
-          return null;
-        } else {
-          LeafByteString result = getLeafByLeft(breadCrumbs.pop().right);
-          if (!result.isEmpty()) {
-            return result;
-          }
-        }
-      }
-    }
-
-    @Override
-    public boolean hasNext() {
-      return next != null;
-    }
-
-    /**
-     * Returns the next item and advances one {@link com.google.protobuf.ByteString.LeafByteString}.
-     *
-     * @return next non-empty LeafByteString or {@code null}
-     */
-    @Override
-    public LeafByteString next() {
-      if (next == null) {
-        throw new NoSuchElementException();
-      }
-      LeafByteString result = next;
-      next = getNextNonEmptyLeaf();
-      return result;
-    }
-
-    @Override
-    public void remove() {
-      throw new UnsupportedOperationException();
-    }
-  }
-
-  // =================================================================
-  // Serializable
-
-  private static final long serialVersionUID = 1L;
-
-  Object writeReplace() {
-    return ByteString.wrap(toByteArray());
-  }
-
-  private void readObject(@SuppressWarnings("unused") ObjectInputStream in) throws IOException {
-    throw new InvalidObjectException("RopeByteStream instances are not to be serialized directly");
-  }
-
-  /** This class is the {@link RopeByteString} equivalent for {@link ByteArrayInputStream}. */
-  private class RopeInputStream extends InputStream {
-    // Iterates through the pieces of the rope
-    private PieceIterator pieceIterator;
-    // The current piece
-    private LeafByteString currentPiece;
-    // The size of the current piece
-    private int currentPieceSize;
-    // The index of the next byte to read in the current piece
-    private int currentPieceIndex;
-    // The offset of the start of the current piece in the rope byte string
-    private int currentPieceOffsetInRope;
-    // Offset in the buffer at which user called mark();
-    private int mark;
-
-    public RopeInputStream() {
-      initialize();
-    }
-
-    /**
-     * Reads up to {@code len} bytes of data into array {@code b}.
-     *
-     * <p>Note that {@link InputStream#read(byte[], int, int)} and {@link
-     * ByteArrayInputStream#read(byte[], int, int)} behave inconsistently when reading 0 bytes at
-     * EOF; the interface defines the return value to be 0 and the latter returns -1. We use the
-     * latter behavior so that all ByteString streams are consistent.
-     *
-     * @return -1 if at EOF, otherwise the actual number of bytes read.
-     */
-    @Override
-    public int read(byte[] b, int offset, int length) {
-      if (b == null) {
-        throw new NullPointerException();
-      } else if (offset < 0 || length < 0 || length > b.length - offset) {
-        throw new IndexOutOfBoundsException();
-      }
-      int bytesRead = readSkipInternal(b, offset, length);
-      if (bytesRead == 0 && (length > 0 || availableInternal() == 0)) {
-        // Modeling ByteArrayInputStream.read(byte[], int, int) behavior noted above:
-        // It's ok to read 0 bytes on purpose (length == 0) from a stream that isn't at EOF.
-        // It's not ok to try to read bytes (even 0 bytes) from a stream that is at EOF.
-        return -1;
-      } else {
-        return bytesRead;
-      }
-    }
-
-    @Override
-    public long skip(long length) {
-      if (length < 0) {
-        throw new IndexOutOfBoundsException();
-      } else if (length > Integer.MAX_VALUE) {
-        length = Integer.MAX_VALUE;
-      }
-      return readSkipInternal(null, 0, (int) length);
-    }
-
-    /**
-     * Internal implementation of read and skip. If b != null, then read the next {@code length}
-     * bytes into the buffer {@code b} at offset {@code offset}. If b == null, then skip the next
-     * {@code length} bytes.
-     *
-     * <p>This method assumes that all error checking has already happened.
-     *
-     * <p>Returns the actual number of bytes read or skipped.
-     */
-    private int readSkipInternal(byte[] b, int offset, int length) {
-      int bytesRemaining = length;
-      while (bytesRemaining > 0) {
-        advanceIfCurrentPieceFullyRead();
-        if (currentPiece == null) {
-          break;
-        } else {
-          // Copy the bytes from this piece.
-          int currentPieceRemaining = currentPieceSize - currentPieceIndex;
-          int count = Math.min(currentPieceRemaining, bytesRemaining);
-          if (b != null) {
-            currentPiece.copyTo(b, currentPieceIndex, offset, count);
-            offset += count;
-          }
-          currentPieceIndex += count;
-          bytesRemaining -= count;
-        }
-      }
-      // Return the number of bytes read.
-      return length - bytesRemaining;
-    }
-
-    @Override
-    public int read() throws IOException {
-      advanceIfCurrentPieceFullyRead();
-      if (currentPiece == null) {
-        return -1;
-      } else {
-        return currentPiece.byteAt(currentPieceIndex++) & 0xFF;
-      }
-    }
-
-    @Override
-    public int available() throws IOException {
-      return availableInternal();
-    }
-
-    @Override
-    public boolean markSupported() {
-      return true;
-    }
-
-    @Override
-    public void mark(int readAheadLimit) {
-      // Set the mark to our position in the byte string
-      mark = currentPieceOffsetInRope + currentPieceIndex;
-    }
-
-    @Override
-    public synchronized void reset() {
-      // Just reinitialize and skip the specified number of bytes.
-      initialize();
-      readSkipInternal(null, 0, mark);
-    }
-
-    /** Common initialization code used by both the constructor and reset() */
-    private void initialize() {
-      pieceIterator = new PieceIterator(RopeByteString.this);
-      currentPiece = pieceIterator.next();
-      currentPieceSize = currentPiece.size();
-      currentPieceIndex = 0;
-      currentPieceOffsetInRope = 0;
-    }
-
-    /**
-     * Skips to the next piece if we have read all the data in the current piece. Sets currentPiece
-     * to null if we have reached the end of the input.
-     */
-    private void advanceIfCurrentPieceFullyRead() {
-      if (currentPiece != null && currentPieceIndex == currentPieceSize) {
-        // Generally, we can only go through this loop at most once, since
-        // empty strings can't end up in a rope.  But better to test.
-        currentPieceOffsetInRope += currentPieceSize;
-        currentPieceIndex = 0;
-        if (pieceIterator.hasNext()) {
-          currentPiece = pieceIterator.next();
-          currentPieceSize = currentPiece.size();
-        } else {
-          currentPiece = null;
-          currentPieceSize = 0;
-        }
-      }
-    }
-
-    /** Computes the number of bytes still available to read. */
-    private int availableInternal() {
-      int bytesRead = currentPieceOffsetInRope + currentPieceIndex;
-      return RopeByteString.this.size() - bytesRead;
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Schema.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Schema.java
deleted file mode 100644
index d0e1e26..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Schema.java
+++ /dev/null
@@ -1,85 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import com.google.protobuf.ArrayDecoders.Registers;
-import java.io.IOException;
-
-/**
- * A runtime schema for a single protobuf message. A schema provides operations on message instances
- * such as serialization/deserialization.
- */
-@ExperimentalApi
-interface Schema<T> {
-  /** Writes the given message to the target {@link Writer}. */
-  void writeTo(T message, Writer writer) throws IOException;
-
-  /**
-   * Reads fields from the given {@link Reader} and merges them into the message. It doesn't make
-   * the message immutable after parsing is done. To make the message immutable, use {@link
-   * #makeImmutable}.
-   */
-  void mergeFrom(T message, Reader reader, ExtensionRegistryLite extensionRegistry)
-      throws IOException;
-
-  /**
-   * Like the above but parses from a byte[] without extensions. Entry point of fast path. Note that
-   * this method may throw IndexOutOfBoundsException if the input data is not valid protobuf wire
-   * format. Protobuf public API methods should catch and convert that exception to
-   * InvalidProtocolBufferException.
-   */
-  void mergeFrom(T message, byte[] data, int position, int limit, Registers registers)
-      throws IOException;
-
-  /** Marks repeated/map/extension/unknown fields as immutable. */
-  void makeImmutable(T message);
-
-  /** Checks whether all required fields are set. */
-  boolean isInitialized(T message);
-
-  /** Creates a new instance of the message class. */
-  T newInstance();
-
-  /** Determine of the two messages are equal. */
-  boolean equals(T message, T other);
-
-  /** Compute a hashCode for the message. */
-  int hashCode(T message);
-
-  /**
-   * Merge values from {@code other} into {@code message}. This method doesn't make the message
-   * immutable. To make the message immutable after merging, use {@link #makeImmutable}.
-   */
-  void mergeFrom(T message, T other);
-
-  /** Compute the serialized size of the message. */
-  int getSerializedSize(T message);
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/SchemaFactory.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/SchemaFactory.java
deleted file mode 100644
index cf38dd6..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/SchemaFactory.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-/** A factory that manufactures {@link Schema} instances for protobuf messages. */
-@ExperimentalApi
-interface SchemaFactory {
-  /** Creates a schema instance for the given protobuf message type. */
-  <T> Schema<T> createSchema(Class<T> messageType);
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/SchemaUtil.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/SchemaUtil.java
deleted file mode 100644
index 4c8bb06..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/SchemaUtil.java
+++ /dev/null
@@ -1,991 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import com.google.protobuf.FieldSet.FieldDescriptorLite;
-import com.google.protobuf.Internal.EnumLiteMap;
-import com.google.protobuf.Internal.EnumVerifier;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.util.Iterator;
-import java.util.List;
-import java.util.RandomAccess;
-
-/** Helper methods used by schemas. */
-@ExperimentalApi
-final class SchemaUtil {
-  private static final Class<?> GENERATED_MESSAGE_CLASS = getGeneratedMessageClass();
-  private static final UnknownFieldSchema<?, ?> PROTO2_UNKNOWN_FIELD_SET_SCHEMA =
-      getUnknownFieldSetSchema(false);
-  private static final UnknownFieldSchema<?, ?> PROTO3_UNKNOWN_FIELD_SET_SCHEMA =
-      getUnknownFieldSetSchema(true);
-  private static final UnknownFieldSchema<?, ?> UNKNOWN_FIELD_SET_LITE_SCHEMA =
-      new UnknownFieldSetLiteSchema();
-
-  private static final int DEFAULT_LOOK_UP_START_NUMBER = 40;
-
-  private SchemaUtil() {}
-
-  /**
-   * Requires that the given message extend {@link com.google.protobuf.GeneratedMessageV3} or {@link
-   * GeneratedMessageLite}.
-   */
-  public static void requireGeneratedMessage(Class<?> messageType) {
-    if (!GeneratedMessageLite.class.isAssignableFrom(messageType)
-        && GENERATED_MESSAGE_CLASS != null
-        && !GENERATED_MESSAGE_CLASS.isAssignableFrom(messageType)) {
-      throw new IllegalArgumentException(
-          "Message classes must extend GeneratedMessage or GeneratedMessageLite");
-    }
-  }
-
-  public static void writeDouble(int fieldNumber, double value, Writer writer) throws IOException {
-    if (Double.compare(value, 0.0) != 0) {
-      writer.writeDouble(fieldNumber, value);
-    }
-  }
-
-  public static void writeFloat(int fieldNumber, float value, Writer writer) throws IOException {
-    if (Float.compare(value, 0.0f) != 0) {
-      writer.writeFloat(fieldNumber, value);
-    }
-  }
-
-  public static void writeInt64(int fieldNumber, long value, Writer writer) throws IOException {
-    if (value != 0) {
-      writer.writeInt64(fieldNumber, value);
-    }
-  }
-
-  public static void writeUInt64(int fieldNumber, long value, Writer writer) throws IOException {
-    if (value != 0) {
-      writer.writeUInt64(fieldNumber, value);
-    }
-  }
-
-  public static void writeSInt64(int fieldNumber, long value, Writer writer) throws IOException {
-    if (value != 0) {
-      writer.writeSInt64(fieldNumber, value);
-    }
-  }
-
-  public static void writeFixed64(int fieldNumber, long value, Writer writer) throws IOException {
-    if (value != 0) {
-      writer.writeFixed64(fieldNumber, value);
-    }
-  }
-
-  public static void writeSFixed64(int fieldNumber, long value, Writer writer) throws IOException {
-    if (value != 0) {
-      writer.writeSFixed64(fieldNumber, value);
-    }
-  }
-
-  public static void writeInt32(int fieldNumber, int value, Writer writer) throws IOException {
-    if (value != 0) {
-      writer.writeInt32(fieldNumber, value);
-    }
-  }
-
-  public static void writeUInt32(int fieldNumber, int value, Writer writer) throws IOException {
-    if (value != 0) {
-      writer.writeUInt32(fieldNumber, value);
-    }
-  }
-
-  public static void writeSInt32(int fieldNumber, int value, Writer writer) throws IOException {
-    if (value != 0) {
-      writer.writeSInt32(fieldNumber, value);
-    }
-  }
-
-  public static void writeFixed32(int fieldNumber, int value, Writer writer) throws IOException {
-    if (value != 0) {
-      writer.writeFixed32(fieldNumber, value);
-    }
-  }
-
-  public static void writeSFixed32(int fieldNumber, int value, Writer writer) throws IOException {
-    if (value != 0) {
-      writer.writeSFixed32(fieldNumber, value);
-    }
-  }
-
-  public static void writeEnum(int fieldNumber, int value, Writer writer) throws IOException {
-    if (value != 0) {
-      writer.writeEnum(fieldNumber, value);
-    }
-  }
-
-  public static void writeBool(int fieldNumber, boolean value, Writer writer) throws IOException {
-    if (value) {
-      writer.writeBool(fieldNumber, true);
-    }
-  }
-
-  public static void writeString(int fieldNumber, Object value, Writer writer) throws IOException {
-    if (value instanceof String) {
-      writeStringInternal(fieldNumber, (String) value, writer);
-    } else {
-      writeBytes(fieldNumber, (ByteString) value, writer);
-    }
-  }
-
-  private static void writeStringInternal(int fieldNumber, String value, Writer writer)
-      throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeString(fieldNumber, value);
-    }
-  }
-
-  public static void writeBytes(int fieldNumber, ByteString value, Writer writer)
-      throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeBytes(fieldNumber, value);
-    }
-  }
-
-  public static void writeMessage(int fieldNumber, Object value, Writer writer) throws IOException {
-    if (value != null) {
-      writer.writeMessage(fieldNumber, value);
-    }
-  }
-
-  public static void writeDoubleList(
-      int fieldNumber, List<Double> value, Writer writer, boolean packed) throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeDoubleList(fieldNumber, value, packed);
-    }
-  }
-
-  public static void writeFloatList(
-      int fieldNumber, List<Float> value, Writer writer, boolean packed) throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeFloatList(fieldNumber, value, packed);
-    }
-  }
-
-  public static void writeInt64List(
-      int fieldNumber, List<Long> value, Writer writer, boolean packed) throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeInt64List(fieldNumber, value, packed);
-    }
-  }
-
-  public static void writeUInt64List(
-      int fieldNumber, List<Long> value, Writer writer, boolean packed) throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeUInt64List(fieldNumber, value, packed);
-    }
-  }
-
-  public static void writeSInt64List(
-      int fieldNumber, List<Long> value, Writer writer, boolean packed) throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeSInt64List(fieldNumber, value, packed);
-    }
-  }
-
-  public static void writeFixed64List(
-      int fieldNumber, List<Long> value, Writer writer, boolean packed) throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeFixed64List(fieldNumber, value, packed);
-    }
-  }
-
-  public static void writeSFixed64List(
-      int fieldNumber, List<Long> value, Writer writer, boolean packed) throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeSFixed64List(fieldNumber, value, packed);
-    }
-  }
-
-  public static void writeInt32List(
-      int fieldNumber, List<Integer> value, Writer writer, boolean packed) throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeInt32List(fieldNumber, value, packed);
-    }
-  }
-
-  public static void writeUInt32List(
-      int fieldNumber, List<Integer> value, Writer writer, boolean packed) throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeUInt32List(fieldNumber, value, packed);
-    }
-  }
-
-  public static void writeSInt32List(
-      int fieldNumber, List<Integer> value, Writer writer, boolean packed) throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeSInt32List(fieldNumber, value, packed);
-    }
-  }
-
-  public static void writeFixed32List(
-      int fieldNumber, List<Integer> value, Writer writer, boolean packed) throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeFixed32List(fieldNumber, value, packed);
-    }
-  }
-
-  public static void writeSFixed32List(
-      int fieldNumber, List<Integer> value, Writer writer, boolean packed) throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeSFixed32List(fieldNumber, value, packed);
-    }
-  }
-
-  public static void writeEnumList(
-      int fieldNumber, List<Integer> value, Writer writer, boolean packed) throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeEnumList(fieldNumber, value, packed);
-    }
-  }
-
-  public static void writeBoolList(
-      int fieldNumber, List<Boolean> value, Writer writer, boolean packed) throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeBoolList(fieldNumber, value, packed);
-    }
-  }
-
-  public static void writeStringList(int fieldNumber, List<String> value, Writer writer)
-      throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeStringList(fieldNumber, value);
-    }
-  }
-
-  public static void writeBytesList(int fieldNumber, List<ByteString> value, Writer writer)
-      throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeBytesList(fieldNumber, value);
-    }
-  }
-
-  public static void writeMessageList(int fieldNumber, List<?> value, Writer writer)
-      throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeMessageList(fieldNumber, value);
-    }
-  }
-
-  public static void writeMessageList(int fieldNumber, List<?> value, Writer writer, Schema schema)
-      throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeMessageList(fieldNumber, value, schema);
-    }
-  }
-
-  public static void writeLazyFieldList(int fieldNumber, List<?> value, Writer writer)
-      throws IOException {
-    if (value != null && !value.isEmpty()) {
-      for (Object item : value) {
-        ((LazyFieldLite) item).writeTo(writer, fieldNumber);
-      }
-    }
-  }
-
-  public static void writeGroupList(int fieldNumber, List<?> value, Writer writer)
-      throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeGroupList(fieldNumber, value);
-    }
-  }
-
-  public static void writeGroupList(int fieldNumber, List<?> value, Writer writer, Schema schema)
-      throws IOException {
-    if (value != null && !value.isEmpty()) {
-      writer.writeGroupList(fieldNumber, value, schema);
-    }
-  }
-
-  static int computeSizeInt64ListNoTag(List<Long> list) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-
-    int size = 0;
-
-    if (list instanceof LongArrayList) {
-      final LongArrayList primitiveList = (LongArrayList) list;
-      for (int i = 0; i < length; i++) {
-        size += CodedOutputStream.computeInt64SizeNoTag(primitiveList.getLong(i));
-      }
-    } else {
-      for (int i = 0; i < length; i++) {
-        size += CodedOutputStream.computeInt64SizeNoTag(list.get(i));
-      }
-    }
-    return size;
-  }
-
-  static int computeSizeInt64List(int fieldNumber, List<Long> list, boolean packed) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-    int size = computeSizeInt64ListNoTag(list);
-
-    if (packed) {
-      return CodedOutputStream.computeTagSize(fieldNumber)
-          + CodedOutputStream.computeLengthDelimitedFieldSize(size);
-    } else {
-      return size + (list.size() * CodedOutputStream.computeTagSize(fieldNumber));
-    }
-  }
-
-  static int computeSizeUInt64ListNoTag(List<Long> list) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-
-    int size = 0;
-
-    if (list instanceof LongArrayList) {
-      final LongArrayList primitiveList = (LongArrayList) list;
-      for (int i = 0; i < length; i++) {
-        size += CodedOutputStream.computeUInt64SizeNoTag(primitiveList.getLong(i));
-      }
-    } else {
-      for (int i = 0; i < length; i++) {
-        size += CodedOutputStream.computeUInt64SizeNoTag(list.get(i));
-      }
-    }
-    return size;
-  }
-
-  static int computeSizeUInt64List(int fieldNumber, List<Long> list, boolean packed) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-    int size = computeSizeUInt64ListNoTag(list);
-
-    if (packed) {
-      return CodedOutputStream.computeTagSize(fieldNumber)
-          + CodedOutputStream.computeLengthDelimitedFieldSize(size);
-    } else {
-      return size + (length * CodedOutputStream.computeTagSize(fieldNumber));
-    }
-  }
-
-  static int computeSizeSInt64ListNoTag(List<Long> list) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-
-    int size = 0;
-
-    if (list instanceof LongArrayList) {
-      final LongArrayList primitiveList = (LongArrayList) list;
-      for (int i = 0; i < length; i++) {
-        size += CodedOutputStream.computeSInt64SizeNoTag(primitiveList.getLong(i));
-      }
-    } else {
-      for (int i = 0; i < length; i++) {
-        size += CodedOutputStream.computeSInt64SizeNoTag(list.get(i));
-      }
-    }
-    return size;
-  }
-
-  static int computeSizeSInt64List(int fieldNumber, List<Long> list, boolean packed) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-    int size = computeSizeSInt64ListNoTag(list);
-
-    if (packed) {
-      return CodedOutputStream.computeTagSize(fieldNumber)
-          + CodedOutputStream.computeLengthDelimitedFieldSize(size);
-    } else {
-      return size + (length * CodedOutputStream.computeTagSize(fieldNumber));
-    }
-  }
-
-  static int computeSizeEnumListNoTag(List<Integer> list) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-
-    int size = 0;
-
-    if (list instanceof IntArrayList) {
-      final IntArrayList primitiveList = (IntArrayList) list;
-      for (int i = 0; i < length; i++) {
-        size += CodedOutputStream.computeEnumSizeNoTag(primitiveList.getInt(i));
-      }
-    } else {
-      for (int i = 0; i < length; i++) {
-        size += CodedOutputStream.computeEnumSizeNoTag(list.get(i));
-      }
-    }
-    return size;
-  }
-
-  static int computeSizeEnumList(int fieldNumber, List<Integer> list, boolean packed) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-    int size = computeSizeEnumListNoTag(list);
-
-    if (packed) {
-      return CodedOutputStream.computeTagSize(fieldNumber)
-          + CodedOutputStream.computeLengthDelimitedFieldSize(size);
-    } else {
-      return size + (length * CodedOutputStream.computeTagSize(fieldNumber));
-    }
-  }
-
-  static int computeSizeInt32ListNoTag(List<Integer> list) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-
-    int size = 0;
-
-    if (list instanceof IntArrayList) {
-      final IntArrayList primitiveList = (IntArrayList) list;
-      for (int i = 0; i < length; i++) {
-        size += CodedOutputStream.computeInt32SizeNoTag(primitiveList.getInt(i));
-      }
-    } else {
-      for (int i = 0; i < length; i++) {
-        size += CodedOutputStream.computeInt32SizeNoTag(list.get(i));
-      }
-    }
-    return size;
-  }
-
-  static int computeSizeInt32List(int fieldNumber, List<Integer> list, boolean packed) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-    int size = computeSizeInt32ListNoTag(list);
-
-    if (packed) {
-      return CodedOutputStream.computeTagSize(fieldNumber)
-          + CodedOutputStream.computeLengthDelimitedFieldSize(size);
-    } else {
-      return size + (length * CodedOutputStream.computeTagSize(fieldNumber));
-    }
-  }
-
-  static int computeSizeUInt32ListNoTag(List<Integer> list) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-
-    int size = 0;
-
-    if (list instanceof IntArrayList) {
-      final IntArrayList primitiveList = (IntArrayList) list;
-      for (int i = 0; i < length; i++) {
-        size += CodedOutputStream.computeUInt32SizeNoTag(primitiveList.getInt(i));
-      }
-    } else {
-      for (int i = 0; i < length; i++) {
-        size += CodedOutputStream.computeUInt32SizeNoTag(list.get(i));
-      }
-    }
-    return size;
-  }
-
-  static int computeSizeUInt32List(int fieldNumber, List<Integer> list, boolean packed) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-    int size = computeSizeUInt32ListNoTag(list);
-
-    if (packed) {
-      return CodedOutputStream.computeTagSize(fieldNumber)
-          + CodedOutputStream.computeLengthDelimitedFieldSize(size);
-    } else {
-      return size + (length * CodedOutputStream.computeTagSize(fieldNumber));
-    }
-  }
-
-  static int computeSizeSInt32ListNoTag(List<Integer> list) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-
-    int size = 0;
-
-    if (list instanceof IntArrayList) {
-      final IntArrayList primitiveList = (IntArrayList) list;
-      for (int i = 0; i < length; i++) {
-        size += CodedOutputStream.computeSInt32SizeNoTag(primitiveList.getInt(i));
-      }
-    } else {
-      for (int i = 0; i < length; i++) {
-        size += CodedOutputStream.computeSInt32SizeNoTag(list.get(i));
-      }
-    }
-    return size;
-  }
-
-  static int computeSizeSInt32List(int fieldNumber, List<Integer> list, boolean packed) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-
-    int size = computeSizeSInt32ListNoTag(list);
-
-    if (packed) {
-      return CodedOutputStream.computeTagSize(fieldNumber)
-          + CodedOutputStream.computeLengthDelimitedFieldSize(size);
-    } else {
-      return size + (length * CodedOutputStream.computeTagSize(fieldNumber));
-    }
-  }
-
-  static int computeSizeFixed32ListNoTag(List<?> list) {
-    return list.size() * WireFormat.FIXED32_SIZE;
-  }
-
-  static int computeSizeFixed32List(int fieldNumber, List<?> list, boolean packed) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-    if (packed) {
-      int dataSize = length * WireFormat.FIXED32_SIZE;
-      return CodedOutputStream.computeTagSize(fieldNumber)
-          + CodedOutputStream.computeLengthDelimitedFieldSize(dataSize);
-    } else {
-      return length * CodedOutputStream.computeFixed32Size(fieldNumber, 0);
-    }
-  }
-
-  static int computeSizeFixed64ListNoTag(List<?> list) {
-    return list.size() * WireFormat.FIXED64_SIZE;
-  }
-
-  static int computeSizeFixed64List(int fieldNumber, List<?> list, boolean packed) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-    if (packed) {
-      final int dataSize = length * WireFormat.FIXED64_SIZE;
-      return CodedOutputStream.computeTagSize(fieldNumber)
-          + CodedOutputStream.computeLengthDelimitedFieldSize(dataSize);
-    } else {
-      return length * CodedOutputStream.computeFixed64Size(fieldNumber, 0);
-    }
-  }
-
-  static int computeSizeBoolListNoTag(List<?> list) {
-    // bools are 1 byte varints
-    return list.size();
-  }
-
-  static int computeSizeBoolList(int fieldNumber, List<?> list, boolean packed) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-    if (packed) {
-      // bools are 1 byte varints
-      return CodedOutputStream.computeTagSize(fieldNumber)
-          + CodedOutputStream.computeLengthDelimitedFieldSize(length);
-    } else {
-      return length * CodedOutputStream.computeBoolSize(fieldNumber, true);
-    }
-  }
-
-  static int computeSizeStringList(int fieldNumber, List<?> list) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-    int size = length * CodedOutputStream.computeTagSize(fieldNumber);
-    if (list instanceof LazyStringList) {
-      LazyStringList lazyList = ((LazyStringList) list);
-      for (int i = 0; i < length; i++) {
-        Object value = lazyList.getRaw(i);
-        if (value instanceof ByteString) {
-          size += CodedOutputStream.computeBytesSizeNoTag((ByteString) value);
-        } else {
-          size += CodedOutputStream.computeStringSizeNoTag((String) value);
-        }
-      }
-    } else {
-      for (int i = 0; i < length; i++) {
-        Object value = list.get(i);
-        if (value instanceof ByteString) {
-          size += CodedOutputStream.computeBytesSizeNoTag((ByteString) value);
-        } else {
-          size += CodedOutputStream.computeStringSizeNoTag((String) value);
-        }
-      }
-    }
-    return size;
-  }
-
-  static int computeSizeMessage(int fieldNumber, Object value, Schema schema) {
-    if (value instanceof LazyFieldLite) {
-      return CodedOutputStream.computeLazyFieldSize(fieldNumber, (LazyFieldLite) value);
-    } else {
-      return CodedOutputStream.computeMessageSize(fieldNumber, (MessageLite) value, schema);
-    }
-  }
-
-  static int computeSizeMessageList(int fieldNumber, List<?> list) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-    int size = length * CodedOutputStream.computeTagSize(fieldNumber);
-    for (int i = 0; i < length; i++) {
-      Object value = list.get(i);
-      if (value instanceof LazyFieldLite) {
-        size += CodedOutputStream.computeLazyFieldSizeNoTag((LazyFieldLite) value);
-      } else {
-        size += CodedOutputStream.computeMessageSizeNoTag((MessageLite) value);
-      }
-    }
-    return size;
-  }
-
-  static int computeSizeMessageList(int fieldNumber, List<?> list, Schema schema) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-    int size = length * CodedOutputStream.computeTagSize(fieldNumber);
-    for (int i = 0; i < length; i++) {
-      Object value = list.get(i);
-      if (value instanceof LazyFieldLite) {
-        size += CodedOutputStream.computeLazyFieldSizeNoTag((LazyFieldLite) value);
-      } else {
-        size += CodedOutputStream.computeMessageSizeNoTag((MessageLite) value, schema);
-      }
-    }
-    return size;
-  }
-
-  static int computeSizeByteStringList(int fieldNumber, List<ByteString> list) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-    int size = length * CodedOutputStream.computeTagSize(fieldNumber);
-    for (int i = 0; i < list.size(); i++) {
-      size += CodedOutputStream.computeBytesSizeNoTag(list.get(i));
-    }
-    return size;
-  }
-
-  static int computeSizeGroupList(int fieldNumber, List<MessageLite> list) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-    int size = 0;
-    for (int i = 0; i < length; i++) {
-      size += CodedOutputStream.computeGroupSize(fieldNumber, list.get(i));
-    }
-    return size;
-  }
-
-  static int computeSizeGroupList(int fieldNumber, List<MessageLite> list, Schema schema) {
-    final int length = list.size();
-    if (length == 0) {
-      return 0;
-    }
-    int size = 0;
-    for (int i = 0; i < length; i++) {
-      size += CodedOutputStream.computeGroupSize(fieldNumber, list.get(i), schema);
-    }
-    return size;
-  }
-
-  /**
-   * Determines whether to issue tableswitch or lookupswitch for the mergeFrom method.
-   *
-   * @see #shouldUseTableSwitch(int, int, int)
-   */
-  public static boolean shouldUseTableSwitch(FieldInfo[] fields) {
-    // Determine whether to issue a tableswitch or a lookupswitch
-    // instruction.
-    if (fields.length == 0) {
-      return false;
-    }
-
-    int lo = fields[0].getFieldNumber();
-    int hi = fields[fields.length - 1].getFieldNumber();
-    return shouldUseTableSwitch(lo, hi, fields.length);
-  }
-
-  /**
-   * Determines whether to issue tableswitch or lookupswitch for the mergeFrom method. This is based
-   * on the <a href=
-   * "http://hg.openjdk.java.net/jdk8/jdk8/langtools/file/30db5e0aaf83/src/share/classes/com/sun/tools/javac/jvm/Gen.java#l1159">
-   * logic in the JDK</a>.
-   *
-   * @param lo the lowest fieldNumber contained within the message.
-   * @param hi the highest fieldNumber contained within the message.
-   * @param numFields the total number of fields in the message.
-   * @return {@code true} if tableswitch should be used, rather than lookupswitch.
-   */
-  public static boolean shouldUseTableSwitch(int lo, int hi, int numFields) {
-    if (hi < DEFAULT_LOOK_UP_START_NUMBER) {
-      return true;
-    }
-    long tableSpaceCost = ((long) hi - lo + 1); // words
-    long tableTimeCost = 3; // comparisons
-    long lookupSpaceCost = 3 + 2 * (long) numFields;
-    long lookupTimeCost = 3 + (long) numFields;
-    return tableSpaceCost + 3 * tableTimeCost <= lookupSpaceCost + 3 * lookupTimeCost;
-  }
-
-  public static UnknownFieldSchema<?, ?> proto2UnknownFieldSetSchema() {
-    return PROTO2_UNKNOWN_FIELD_SET_SCHEMA;
-  }
-
-  public static UnknownFieldSchema<?, ?> proto3UnknownFieldSetSchema() {
-    return PROTO3_UNKNOWN_FIELD_SET_SCHEMA;
-  }
-
-  public static UnknownFieldSchema<?, ?> unknownFieldSetLiteSchema() {
-    return UNKNOWN_FIELD_SET_LITE_SCHEMA;
-  }
-
-  private static UnknownFieldSchema<?, ?> getUnknownFieldSetSchema(boolean proto3) {
-    try {
-      Class<?> clz = getUnknownFieldSetSchemaClass();
-      if (clz == null) {
-        return null;
-      }
-      return (UnknownFieldSchema) clz.getConstructor(boolean.class).newInstance(proto3);
-    } catch (Throwable t) {
-      return null;
-    }
-  }
-
-  private static Class<?> getGeneratedMessageClass() {
-    try {
-      return Class.forName("com.google.protobuf.GeneratedMessageV3");
-    } catch (Throwable e) {
-      return null;
-    }
-  }
-
-  private static Class<?> getUnknownFieldSetSchemaClass() {
-    try {
-      return Class.forName("com.google.protobuf.UnknownFieldSetSchema");
-    } catch (Throwable e) {
-      return null;
-    }
-  }
-
-  static Object getMapDefaultEntry(Class<?> clazz, String name) {
-    try {
-      Class<?> holder =
-          Class.forName(clazz.getName() + "$" + toCamelCase(name, true) + "DefaultEntryHolder");
-      Field[] fields = holder.getDeclaredFields();
-      if (fields.length != 1) {
-        throw new IllegalStateException(
-            "Unable to look up map field default entry holder class for "
-                + name
-                + " in "
-                + clazz.getName());
-      }
-      return UnsafeUtil.getStaticObject(fields[0]);
-    } catch (Throwable t) {
-      throw new RuntimeException(t);
-    }
-  }
-
-  static String toCamelCase(String name, boolean capNext) {
-    StringBuilder sb = new StringBuilder();
-    for (int i = 0; i < name.length(); ++i) {
-      char c = name.charAt(i);
-      // Matches protoc field name function:
-      if ('a' <= c && c <= 'z') {
-        if (capNext) {
-          sb.append((char) (c + ('A' - 'a')));
-        } else {
-          sb.append(c);
-        }
-        capNext = false;
-      } else if ('A' <= c && c <= 'Z') {
-        if (i == 0 && !capNext) {
-          // Force first letter to lower-case unless explicitly told to capitalize it.
-          sb.append((char) (c - ('A' - 'a')));
-        } else {
-          sb.append(c);
-        }
-        capNext = false;
-      } else if ('0' <= c && c <= '9') {
-        sb.append(c);
-        capNext = true;
-      } else {
-        capNext = true;
-      }
-    }
-    return sb.toString();
-  }
-
-  /** Returns true if both are null or both are {@link Object#equals}. */
-  static boolean safeEquals(Object a, Object b) {
-    return a == b || (a != null && a.equals(b));
-  }
-
-  static <T> void mergeMap(MapFieldSchema mapFieldSchema, T message, T o, long offset) {
-    Object merged =
-        mapFieldSchema.mergeFrom(
-            UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(o, offset));
-    UnsafeUtil.putObject(message, offset, merged);
-  }
-
-  static <T, FT extends FieldDescriptorLite<FT>> void mergeExtensions(
-      ExtensionSchema<FT> schema, T message, T other) {
-    FieldSet<FT> otherExtensions = schema.getExtensions(other);
-    if (!otherExtensions.isEmpty()) {
-      FieldSet<FT> messageExtensions = schema.getMutableExtensions(message);
-      messageExtensions.mergeFrom(otherExtensions);
-    }
-  }
-
-  static <T, UT, UB> void mergeUnknownFields(
-      UnknownFieldSchema<UT, UB> schema, T message, T other) {
-    UT messageUnknowns = schema.getFromMessage(message);
-    UT otherUnknowns = schema.getFromMessage(other);
-    UT merged = schema.merge(messageUnknowns, otherUnknowns);
-    schema.setToMessage(message, merged);
-  }
-
-  /** Filters unrecognized enum values in a list. */
-  static <UT, UB> UB filterUnknownEnumList(
-      int number,
-      List<Integer> enumList,
-      EnumLiteMap<?> enumMap,
-      UB unknownFields,
-      UnknownFieldSchema<UT, UB> unknownFieldSchema) {
-    if (enumMap == null) {
-      return unknownFields;
-    }
-    // TODO(dweis): Specialize for IntArrayList to avoid boxing.
-    if (enumList instanceof RandomAccess) {
-      int writePos = 0;
-      int size = enumList.size();
-      for (int readPos = 0; readPos < size; ++readPos) {
-        int enumValue = enumList.get(readPos);
-        if (enumMap.findValueByNumber(enumValue) != null) {
-          if (readPos != writePos) {
-            enumList.set(writePos, enumValue);
-          }
-          ++writePos;
-        } else {
-          unknownFields = storeUnknownEnum(number, enumValue, unknownFields, unknownFieldSchema);
-        }
-      }
-      if (writePos != size) {
-        enumList.subList(writePos, size).clear();
-      }
-    } else {
-      for (Iterator<Integer> it = enumList.iterator(); it.hasNext(); ) {
-        int enumValue = it.next();
-        if (enumMap.findValueByNumber(enumValue) == null) {
-          unknownFields = storeUnknownEnum(number, enumValue, unknownFields, unknownFieldSchema);
-          it.remove();
-        }
-      }
-    }
-    return unknownFields;
-  }
-
-  /** Filters unrecognized enum values in a list. */
-  static <UT, UB> UB filterUnknownEnumList(
-      int number,
-      List<Integer> enumList,
-      EnumVerifier enumVerifier,
-      UB unknownFields,
-      UnknownFieldSchema<UT, UB> unknownFieldSchema) {
-    if (enumVerifier == null) {
-      return unknownFields;
-    }
-    // TODO(dweis): Specialize for IntArrayList to avoid boxing.
-    if (enumList instanceof RandomAccess) {
-      int writePos = 0;
-      int size = enumList.size();
-      for (int readPos = 0; readPos < size; ++readPos) {
-        int enumValue = enumList.get(readPos);
-        if (enumVerifier.isInRange(enumValue)) {
-          if (readPos != writePos) {
-            enumList.set(writePos, enumValue);
-          }
-          ++writePos;
-        } else {
-          unknownFields = storeUnknownEnum(number, enumValue, unknownFields, unknownFieldSchema);
-        }
-      }
-      if (writePos != size) {
-        enumList.subList(writePos, size).clear();
-      }
-    } else {
-      for (Iterator<Integer> it = enumList.iterator(); it.hasNext(); ) {
-        int enumValue = it.next();
-        if (!enumVerifier.isInRange(enumValue)) {
-          unknownFields = storeUnknownEnum(number, enumValue, unknownFields, unknownFieldSchema);
-          it.remove();
-        }
-      }
-    }
-    return unknownFields;
-  }
-
-  /** Stores an unrecognized enum value as an unknown value. */
-  static <UT, UB> UB storeUnknownEnum(
-      int number, int enumValue, UB unknownFields, UnknownFieldSchema<UT, UB> unknownFieldSchema) {
-    if (unknownFields == null) {
-      unknownFields = unknownFieldSchema.newBuilder();
-    }
-    unknownFieldSchema.addVarint(unknownFields, number, enumValue);
-    return unknownFields;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/SmallSortedMap.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/SmallSortedMap.java
deleted file mode 100644
index 546e56e..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/SmallSortedMap.java
+++ /dev/null
@@ -1,712 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.util.AbstractMap;
-import java.util.AbstractSet;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-/**
- * A custom map implementation from FieldDescriptor to Object optimized to minimize the number of
- * memory allocations for instances with a small number of mappings. The implementation stores the
- * first {@code k} mappings in an array for a configurable value of {@code k}, allowing direct
- * access to the corresponding {@code Entry}s without the need to create an Iterator. The remaining
- * entries are stored in an overflow map. Iteration over the entries in the map should be done as
- * follows:
- *
- * <pre>{@code
- * for (int i = 0; i < fieldMap.getNumArrayEntries(); i++) {
- *   process(fieldMap.getArrayEntryAt(i));
- * }
- * for (Map.Entry<K, V> entry : fieldMap.getOverflowEntries()) {
- *   process(entry);
- * }
- * }</pre>
- *
- * The resulting iteration is in order of ascending field tag number. The object returned by {@link
- * #entrySet()} adheres to the same contract but is less efficient as it necessarily involves
- * creating an object for iteration.
- *
- * <p>The tradeoff for this memory efficiency is that the worst case running time of the {@code
- * put()} operation is {@code O(k + lg n)}, which happens when entries are added in descending
- * order. {@code k} should be chosen such that it covers enough common cases without adversely
- * affecting larger maps. In practice, the worst case scenario does not happen for extensions
- * because extension fields are serialized and deserialized in order of ascending tag number, but
- * the worst case scenario can happen for DynamicMessages.
- *
- * <p>The running time for all other operations is similar to that of {@code TreeMap}.
- *
- * <p>Instances are not thread-safe until {@link #makeImmutable()} is called, after which any
- * modifying operation will result in an {@link UnsupportedOperationException}.
- *
- * @author darick@google.com Darick Tong
- */
-// This class is final for all intents and purposes because the constructor is
-// private. However, the FieldDescriptor-specific logic is encapsulated in
-// a subclass to aid testability of the core logic.
-class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
-
-  /**
-   * Creates a new instance for mapping FieldDescriptors to their values. The {@link
-   * #makeImmutable()} implementation will convert the List values of any repeated fields to
-   * unmodifiable lists.
-   *
-   * @param arraySize The size of the entry array containing the lexicographically smallest
-   *     mappings.
-   */
-  static <FieldDescriptorType extends FieldSet.FieldDescriptorLite<FieldDescriptorType>>
-      SmallSortedMap<FieldDescriptorType, Object> newFieldMap(int arraySize) {
-    return new SmallSortedMap<FieldDescriptorType, Object>(arraySize) {
-      @Override
-      @SuppressWarnings("unchecked")
-      public void makeImmutable() {
-        if (!isImmutable()) {
-          for (int i = 0; i < getNumArrayEntries(); i++) {
-            final Map.Entry<FieldDescriptorType, Object> entry = getArrayEntryAt(i);
-            if (entry.getKey().isRepeated()) {
-              final List value = (List) entry.getValue();
-              entry.setValue(Collections.unmodifiableList(value));
-            }
-          }
-          for (Map.Entry<FieldDescriptorType, Object> entry : getOverflowEntries()) {
-            if (entry.getKey().isRepeated()) {
-              final List value = (List) entry.getValue();
-              entry.setValue(Collections.unmodifiableList(value));
-            }
-          }
-        }
-        super.makeImmutable();
-      }
-    };
-  }
-
-  /**
-   * Creates a new instance for testing.
-   *
-   * @param arraySize The size of the entry array containing the lexicographically smallest
-   *     mappings.
-   */
-  static <K extends Comparable<K>, V> SmallSortedMap<K, V> newInstanceForTest(int arraySize) {
-    return new SmallSortedMap<K, V>(arraySize);
-  }
-
-  private final int maxArraySize;
-  // The "entry array" is actually a List because generic arrays are not
-  // allowed. ArrayList also nicely handles the entry shifting on inserts and
-  // removes.
-  private List<Entry> entryList;
-  private Map<K, V> overflowEntries;
-  private boolean isImmutable;
-  // The EntrySet is a stateless view of the Map. It's initialized the first
-  // time it is requested and reused henceforth.
-  private volatile EntrySet lazyEntrySet;
-  private Map<K, V> overflowEntriesDescending;
-  private volatile DescendingEntrySet lazyDescendingEntrySet;
-
-  /**
-   * @code arraySize Size of the array in which the lexicographically smallest mappings are stored.
-   *     (i.e. the {@code k} referred to in the class documentation).
-   */
-  private SmallSortedMap(int arraySize) {
-    this.maxArraySize = arraySize;
-    this.entryList = Collections.emptyList();
-    this.overflowEntries = Collections.emptyMap();
-    this.overflowEntriesDescending = Collections.emptyMap();
-  }
-
-  /** Make this map immutable from this point forward. */
-  public void makeImmutable() {
-    if (!isImmutable) {
-      // Note: There's no need to wrap the entryList in an unmodifiableList
-      // because none of the list's accessors are exposed. The iterator() of
-      // overflowEntries, on the other hand, is exposed so it must be made
-      // unmodifiable.
-      overflowEntries =
-          overflowEntries.isEmpty()
-              ? Collections.<K, V>emptyMap()
-              : Collections.unmodifiableMap(overflowEntries);
-      overflowEntriesDescending =
-          overflowEntriesDescending.isEmpty()
-              ? Collections.<K, V>emptyMap()
-              : Collections.unmodifiableMap(overflowEntriesDescending);
-      isImmutable = true;
-    }
-  }
-
-  /** @return Whether {@link #makeImmutable()} has been called. */
-  public boolean isImmutable() {
-    return isImmutable;
-  }
-
-  /** @return The number of entries in the entry array. */
-  public int getNumArrayEntries() {
-    return entryList.size();
-  }
-
-  /** @return The array entry at the given {@code index}. */
-  public Map.Entry<K, V> getArrayEntryAt(int index) {
-    return entryList.get(index);
-  }
-
-  /** @return There number of overflow entries. */
-  public int getNumOverflowEntries() {
-    return overflowEntries.size();
-  }
-
-  /** @return An iterable over the overflow entries. */
-  public Iterable<Map.Entry<K, V>> getOverflowEntries() {
-    return overflowEntries.isEmpty()
-        ? EmptySet.<Map.Entry<K, V>>iterable()
-        : overflowEntries.entrySet();
-  }
-
-  Iterable<Map.Entry<K, V>> getOverflowEntriesDescending() {
-    return overflowEntriesDescending.isEmpty()
-        ? EmptySet.<Map.Entry<K, V>>iterable()
-        : overflowEntriesDescending.entrySet();
-  }
-
-  @Override
-  public int size() {
-    return entryList.size() + overflowEntries.size();
-  }
-
-  /**
-   * The implementation throws a {@code ClassCastException} if o is not an object of type {@code K}.
-   *
-   * <p>{@inheritDoc}
-   */
-  @Override
-  public boolean containsKey(Object o) {
-    @SuppressWarnings("unchecked")
-    final K key = (K) o;
-    return binarySearchInArray(key) >= 0 || overflowEntries.containsKey(key);
-  }
-
-  /**
-   * The implementation throws a {@code ClassCastException} if o is not an object of type {@code K}.
-   *
-   * <p>{@inheritDoc}
-   */
-  @Override
-  public V get(Object o) {
-    @SuppressWarnings("unchecked")
-    final K key = (K) o;
-    final int index = binarySearchInArray(key);
-    if (index >= 0) {
-      return entryList.get(index).getValue();
-    }
-    return overflowEntries.get(key);
-  }
-
-  @Override
-  public V put(K key, V value) {
-    checkMutable();
-    final int index = binarySearchInArray(key);
-    if (index >= 0) {
-      // Replace existing array entry.
-      return entryList.get(index).setValue(value);
-    }
-    ensureEntryArrayMutable();
-    final int insertionPoint = -(index + 1);
-    if (insertionPoint >= maxArraySize) {
-      // Put directly in overflow.
-      return getOverflowEntriesMutable().put(key, value);
-    }
-    // Insert new Entry in array.
-    if (entryList.size() == maxArraySize) {
-      // Shift the last array entry into overflow.
-      final Entry lastEntryInArray = entryList.remove(maxArraySize - 1);
-      getOverflowEntriesMutable().put(lastEntryInArray.getKey(), lastEntryInArray.getValue());
-    }
-    entryList.add(insertionPoint, new Entry(key, value));
-    return null;
-  }
-
-  @Override
-  public void clear() {
-    checkMutable();
-    if (!entryList.isEmpty()) {
-      entryList.clear();
-    }
-    if (!overflowEntries.isEmpty()) {
-      overflowEntries.clear();
-    }
-  }
-
-  /**
-   * The implementation throws a {@code ClassCastException} if o is not an object of type {@code K}.
-   *
-   * <p>{@inheritDoc}
-   */
-  @Override
-  public V remove(Object o) {
-    checkMutable();
-    @SuppressWarnings("unchecked")
-    final K key = (K) o;
-    final int index = binarySearchInArray(key);
-    if (index >= 0) {
-      return removeArrayEntryAt(index);
-    }
-    // overflowEntries might be Collections.unmodifiableMap(), so only
-    // call remove() if it is non-empty.
-    if (overflowEntries.isEmpty()) {
-      return null;
-    } else {
-      return overflowEntries.remove(key);
-    }
-  }
-
-  private V removeArrayEntryAt(int index) {
-    checkMutable();
-    final V removed = entryList.remove(index).getValue();
-    if (!overflowEntries.isEmpty()) {
-      // Shift the first entry in the overflow to be the last entry in the
-      // array.
-      final Iterator<Map.Entry<K, V>> iterator = getOverflowEntriesMutable().entrySet().iterator();
-      entryList.add(new Entry(iterator.next()));
-      iterator.remove();
-    }
-    return removed;
-  }
-
-  /**
-   * @param key The key to find in the entry array.
-   * @return The returned integer position follows the same semantics as the value returned by
-   *     {@link java.util.Arrays#binarySearch()}.
-   */
-  private int binarySearchInArray(K key) {
-    int left = 0;
-    int right = entryList.size() - 1;
-
-    // Optimization: For the common case in which entries are added in
-    // ascending tag order, check the largest element in the array before
-    // doing a full binary search.
-    if (right >= 0) {
-      int cmp = key.compareTo(entryList.get(right).getKey());
-      if (cmp > 0) {
-        return -(right + 2); // Insert point is after "right".
-      } else if (cmp == 0) {
-        return right;
-      }
-    }
-
-    while (left <= right) {
-      int mid = (left + right) / 2;
-      int cmp = key.compareTo(entryList.get(mid).getKey());
-      if (cmp < 0) {
-        right = mid - 1;
-      } else if (cmp > 0) {
-        left = mid + 1;
-      } else {
-        return mid;
-      }
-    }
-    return -(left + 1);
-  }
-
-  /**
-   * Similar to the AbstractMap implementation of {@code keySet()} and {@code values()}, the entry
-   * set is created the first time this method is called, and returned in response to all subsequent
-   * calls.
-   *
-   * <p>{@inheritDoc}
-   */
-  @Override
-  public Set<Map.Entry<K, V>> entrySet() {
-    if (lazyEntrySet == null) {
-      lazyEntrySet = new EntrySet();
-    }
-    return lazyEntrySet;
-  }
-
-  Set<Map.Entry<K, V>> descendingEntrySet() {
-    if (lazyDescendingEntrySet == null) {
-      lazyDescendingEntrySet = new DescendingEntrySet();
-    }
-    return lazyDescendingEntrySet;
-  }
-
-  /** @throws UnsupportedOperationException if {@link #makeImmutable()} has has been called. */
-  private void checkMutable() {
-    if (isImmutable) {
-      throw new UnsupportedOperationException();
-    }
-  }
-
-  /**
-   * @return a {@link SortedMap} to which overflow entries mappings can be added or removed.
-   * @throws UnsupportedOperationException if {@link #makeImmutable()} has been called.
-   */
-  @SuppressWarnings("unchecked")
-  private SortedMap<K, V> getOverflowEntriesMutable() {
-    checkMutable();
-    if (overflowEntries.isEmpty() && !(overflowEntries instanceof TreeMap)) {
-      overflowEntries = new TreeMap<K, V>();
-      overflowEntriesDescending = ((TreeMap<K, V>) overflowEntries).descendingMap();
-    }
-    return (SortedMap<K, V>) overflowEntries;
-  }
-
-  /** Lazily creates the entry list. Any code that adds to the list must first call this method. */
-  private void ensureEntryArrayMutable() {
-    checkMutable();
-    if (entryList.isEmpty() && !(entryList instanceof ArrayList)) {
-      entryList = new ArrayList<Entry>(maxArraySize);
-    }
-  }
-
-  /**
-   * Entry implementation that implements Comparable in order to support binary search within the
-   * entry array. Also checks mutability in {@link #setValue()}.
-   */
-  private class Entry implements Map.Entry<K, V>, Comparable<Entry> {
-
-    private final K key;
-    private V value;
-
-    Entry(Map.Entry<K, V> copy) {
-      this(copy.getKey(), copy.getValue());
-    }
-
-    Entry(K key, V value) {
-      this.key = key;
-      this.value = value;
-    }
-
-    @Override
-    public K getKey() {
-      return key;
-    }
-
-    @Override
-    public V getValue() {
-      return value;
-    }
-
-    @Override
-    public int compareTo(Entry other) {
-      return getKey().compareTo(other.getKey());
-    }
-
-    @Override
-    public V setValue(V newValue) {
-      checkMutable();
-      final V oldValue = this.value;
-      this.value = newValue;
-      return oldValue;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-      if (o == this) {
-        return true;
-      }
-      if (!(o instanceof Map.Entry)) {
-        return false;
-      }
-      @SuppressWarnings("unchecked")
-      Map.Entry<?, ?> other = (Map.Entry<?, ?>) o;
-      return equals(key, other.getKey()) && equals(value, other.getValue());
-    }
-
-    @Override
-    public int hashCode() {
-      return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode());
-    }
-
-    @Override
-    public String toString() {
-      return key + "=" + value;
-    }
-
-    /** equals() that handles null values. */
-    private boolean equals(Object o1, Object o2) {
-      return o1 == null ? o2 == null : o1.equals(o2);
-    }
-  }
-
-  /** Stateless view of the entries in the field map. */
-  private class EntrySet extends AbstractSet<Map.Entry<K, V>> {
-
-    @Override
-    public Iterator<Map.Entry<K, V>> iterator() {
-      return new EntryIterator();
-    }
-
-    @Override
-    public int size() {
-      return SmallSortedMap.this.size();
-    }
-
-    /**
-     * Throws a {@link ClassCastException} if o is not of the expected type.
-     *
-     * <p>{@inheritDoc}
-     */
-    @Override
-    public boolean contains(Object o) {
-      @SuppressWarnings("unchecked")
-      final Map.Entry<K, V> entry = (Map.Entry<K, V>) o;
-      final V existing = get(entry.getKey());
-      final V value = entry.getValue();
-      return existing == value || (existing != null && existing.equals(value));
-    }
-
-    @Override
-    public boolean add(Map.Entry<K, V> entry) {
-      if (!contains(entry)) {
-        put(entry.getKey(), entry.getValue());
-        return true;
-      }
-      return false;
-    }
-
-    /**
-     * Throws a {@link ClassCastException} if o is not of the expected type.
-     *
-     * <p>{@inheritDoc}
-     */
-    @Override
-    public boolean remove(Object o) {
-      @SuppressWarnings("unchecked")
-      final Map.Entry<K, V> entry = (Map.Entry<K, V>) o;
-      if (contains(entry)) {
-        SmallSortedMap.this.remove(entry.getKey());
-        return true;
-      }
-      return false;
-    }
-
-    @Override
-    public void clear() {
-      SmallSortedMap.this.clear();
-    }
-  }
-
-  private class DescendingEntrySet extends EntrySet {
-    @Override
-    public Iterator<java.util.Map.Entry<K, V>> iterator() {
-      return new DescendingEntryIterator();
-    }
-  }
-
-  /**
-   * Iterator implementation that switches from the entry array to the overflow entries
-   * appropriately.
-   */
-  private class EntryIterator implements Iterator<Map.Entry<K, V>> {
-
-    private int pos = -1;
-    private boolean nextCalledBeforeRemove;
-    private Iterator<Map.Entry<K, V>> lazyOverflowIterator;
-
-    @Override
-    public boolean hasNext() {
-      return (pos + 1) < entryList.size()
-          || (!overflowEntries.isEmpty() && getOverflowIterator().hasNext());
-    }
-
-    @Override
-    public Map.Entry<K, V> next() {
-      nextCalledBeforeRemove = true;
-      // Always increment pos so that we know whether the last returned value
-      // was from the array or from overflow.
-      if (++pos < entryList.size()) {
-        return entryList.get(pos);
-      }
-      return getOverflowIterator().next();
-    }
-
-    @Override
-    public void remove() {
-      if (!nextCalledBeforeRemove) {
-        throw new IllegalStateException("remove() was called before next()");
-      }
-      nextCalledBeforeRemove = false;
-      checkMutable();
-
-      if (pos < entryList.size()) {
-        removeArrayEntryAt(pos--);
-      } else {
-        getOverflowIterator().remove();
-      }
-    }
-
-    /**
-     * It is important to create the overflow iterator only after the array entries have been
-     * iterated over because the overflow entry set changes when the client calls remove() on the
-     * array entries, which invalidates any existing iterators.
-     */
-    private Iterator<Map.Entry<K, V>> getOverflowIterator() {
-      if (lazyOverflowIterator == null) {
-        lazyOverflowIterator = overflowEntries.entrySet().iterator();
-      }
-      return lazyOverflowIterator;
-    }
-  }
-
-  /**
-   * Reverse Iterator implementation that switches from the entry array to the overflow entries
-   * appropriately.
-   */
-  private class DescendingEntryIterator implements Iterator<Map.Entry<K, V>> {
-
-    private int pos = entryList.size();
-    private Iterator<Map.Entry<K, V>> lazyOverflowIterator;
-
-    @Override
-    public boolean hasNext() {
-      return (pos > 0 && pos <= entryList.size()) || getOverflowIterator().hasNext();
-    }
-
-    @Override
-    public Map.Entry<K, V> next() {
-      if (getOverflowIterator().hasNext()) {
-        return getOverflowIterator().next();
-      }
-      return entryList.get(--pos);
-    }
-
-    @Override
-    public void remove() {
-      throw new UnsupportedOperationException();
-    }
-
-    /**
-     * It is important to create the overflow iterator only after the array entries have been
-     * iterated over because the overflow entry set changes when the client calls remove() on the
-     * array entries, which invalidates any existing iterators.
-     */
-    private Iterator<Map.Entry<K, V>> getOverflowIterator() {
-      if (lazyOverflowIterator == null) {
-        lazyOverflowIterator = overflowEntriesDescending.entrySet().iterator();
-      }
-      return lazyOverflowIterator;
-    }
-  }
-
-  /**
-   * Helper class that holds immutable instances of an Iterable/Iterator that we return when the
-   * overflow entries is empty. This eliminates the creation of an Iterator object when there is
-   * nothing to iterate over.
-   */
-  private static class EmptySet {
-
-    private static final Iterator<Object> ITERATOR =
-        new Iterator<Object>() {
-          @Override
-          public boolean hasNext() {
-            return false;
-          }
-
-          @Override
-          public Object next() {
-            throw new NoSuchElementException();
-          }
-
-          @Override
-          public void remove() {
-            throw new UnsupportedOperationException();
-          }
-        };
-
-    private static final Iterable<Object> ITERABLE =
-        new Iterable<Object>() {
-          @Override
-          public Iterator<Object> iterator() {
-            return ITERATOR;
-          }
-        };
-
-    @SuppressWarnings("unchecked")
-    static <T> Iterable<T> iterable() {
-      return (Iterable<T>) ITERABLE;
-    }
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-
-    if (!(o instanceof SmallSortedMap)) {
-      return super.equals(o);
-    }
-
-    SmallSortedMap<?, ?> other = (SmallSortedMap<?, ?>) o;
-    final int size = size();
-    if (size != other.size()) {
-      return false;
-    }
-
-    // Best effort try to avoid allocating an entry set.
-    final int numArrayEntries = getNumArrayEntries();
-    if (numArrayEntries != other.getNumArrayEntries()) {
-      return entrySet().equals(other.entrySet());
-    }
-
-    for (int i = 0; i < numArrayEntries; i++) {
-      if (!getArrayEntryAt(i).equals(other.getArrayEntryAt(i))) {
-        return false;
-      }
-    }
-
-    if (numArrayEntries != size) {
-      return overflowEntries.equals(other.overflowEntries);
-    }
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int h = 0;
-    final int listSize = getNumArrayEntries();
-    for (int i = 0; i < listSize; i++) {
-      h += entryList.get(i).hashCode();
-    }
-    // Avoid the iterator allocation if possible.
-    if (getNumOverflowEntries() > 0) {
-      h += overflowEntries.hashCode();
-    }
-    return h;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/SourceContext.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/SourceContext.java
deleted file mode 100644
index e92d326..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/SourceContext.java
+++ /dev/null
@@ -1,341 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/source_context.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * `SourceContext` represents information about the source of a
- * protobuf element, like the file in which it is defined.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.SourceContext}
- */
-public  final class SourceContext extends
-    com.google.protobuf.GeneratedMessageLite<
-        SourceContext, SourceContext.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.SourceContext)
-    SourceContextOrBuilder {
-  private SourceContext() {
-    fileName_ = "";
-  }
-  public static final int FILE_NAME_FIELD_NUMBER = 1;
-  private java.lang.String fileName_;
-  /**
-   * <pre>
-   * The path-qualified name of the .proto file that contained the associated
-   * protobuf element.  For example: `"google/protobuf/source_context.proto"`.
-   * </pre>
-   *
-   * <code>string file_name = 1;</code>
-   * @return The fileName.
-   */
-  @java.lang.Override
-  public java.lang.String getFileName() {
-    return fileName_;
-  }
-  /**
-   * <pre>
-   * The path-qualified name of the .proto file that contained the associated
-   * protobuf element.  For example: `"google/protobuf/source_context.proto"`.
-   * </pre>
-   *
-   * <code>string file_name = 1;</code>
-   * @return The bytes for fileName.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getFileNameBytes() {
-    return com.google.protobuf.ByteString.copyFromUtf8(fileName_);
-  }
-  /**
-   * <pre>
-   * The path-qualified name of the .proto file that contained the associated
-   * protobuf element.  For example: `"google/protobuf/source_context.proto"`.
-   * </pre>
-   *
-   * <code>string file_name = 1;</code>
-   * @param value The fileName to set.
-   */
-  private void setFileName(
-      java.lang.String value) {
-    value.getClass();
-  
-    fileName_ = value;
-  }
-  /**
-   * <pre>
-   * The path-qualified name of the .proto file that contained the associated
-   * protobuf element.  For example: `"google/protobuf/source_context.proto"`.
-   * </pre>
-   *
-   * <code>string file_name = 1;</code>
-   */
-  private void clearFileName() {
-    
-    fileName_ = getDefaultInstance().getFileName();
-  }
-  /**
-   * <pre>
-   * The path-qualified name of the .proto file that contained the associated
-   * protobuf element.  For example: `"google/protobuf/source_context.proto"`.
-   * </pre>
-   *
-   * <code>string file_name = 1;</code>
-   * @param value The bytes for fileName to set.
-   */
-  private void setFileNameBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    fileName_ = value.toStringUtf8();
-    
-  }
-
-  public static com.google.protobuf.SourceContext parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.SourceContext parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.SourceContext parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.SourceContext parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.SourceContext parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.SourceContext parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.SourceContext parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.SourceContext parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.SourceContext parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.SourceContext parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.SourceContext parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.SourceContext parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.SourceContext prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * `SourceContext` represents information about the source of a
-   * protobuf element, like the file in which it is defined.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.SourceContext}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.SourceContext, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.SourceContext)
-      com.google.protobuf.SourceContextOrBuilder {
-    // Construct using com.google.protobuf.SourceContext.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * The path-qualified name of the .proto file that contained the associated
-     * protobuf element.  For example: `"google/protobuf/source_context.proto"`.
-     * </pre>
-     *
-     * <code>string file_name = 1;</code>
-     * @return The fileName.
-     */
-    @java.lang.Override
-    public java.lang.String getFileName() {
-      return instance.getFileName();
-    }
-    /**
-     * <pre>
-     * The path-qualified name of the .proto file that contained the associated
-     * protobuf element.  For example: `"google/protobuf/source_context.proto"`.
-     * </pre>
-     *
-     * <code>string file_name = 1;</code>
-     * @return The bytes for fileName.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getFileNameBytes() {
-      return instance.getFileNameBytes();
-    }
-    /**
-     * <pre>
-     * The path-qualified name of the .proto file that contained the associated
-     * protobuf element.  For example: `"google/protobuf/source_context.proto"`.
-     * </pre>
-     *
-     * <code>string file_name = 1;</code>
-     * @param value The fileName to set.
-     * @return This builder for chaining.
-     */
-    public Builder setFileName(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.setFileName(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The path-qualified name of the .proto file that contained the associated
-     * protobuf element.  For example: `"google/protobuf/source_context.proto"`.
-     * </pre>
-     *
-     * <code>string file_name = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearFileName() {
-      copyOnWrite();
-      instance.clearFileName();
-      return this;
-    }
-    /**
-     * <pre>
-     * The path-qualified name of the .proto file that contained the associated
-     * protobuf element.  For example: `"google/protobuf/source_context.proto"`.
-     * </pre>
-     *
-     * <code>string file_name = 1;</code>
-     * @param value The bytes for fileName to set.
-     * @return This builder for chaining.
-     */
-    public Builder setFileNameBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setFileNameBytes(value);
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.SourceContext)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.SourceContext();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "fileName_",
-          };
-          java.lang.String info =
-              "\u0000\u0001\u0000\u0000\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u0208";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.SourceContext> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.SourceContext.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.SourceContext>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.SourceContext)
-  private static final com.google.protobuf.SourceContext DEFAULT_INSTANCE;
-  static {
-    SourceContext defaultInstance = new SourceContext();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      SourceContext.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.SourceContext getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<SourceContext> PARSER;
-
-  public static com.google.protobuf.Parser<SourceContext> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/SourceContextOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/SourceContextOrBuilder.java
deleted file mode 100644
index 7307307..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/SourceContextOrBuilder.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/source_context.proto
-
-package com.google.protobuf;
-
-public interface SourceContextOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.SourceContext)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * The path-qualified name of the .proto file that contained the associated
-   * protobuf element.  For example: `"google/protobuf/source_context.proto"`.
-   * </pre>
-   *
-   * <code>string file_name = 1;</code>
-   * @return The fileName.
-   */
-  java.lang.String getFileName();
-  /**
-   * <pre>
-   * The path-qualified name of the .proto file that contained the associated
-   * protobuf element.  For example: `"google/protobuf/source_context.proto"`.
-   * </pre>
-   *
-   * <code>string file_name = 1;</code>
-   * @return The bytes for fileName.
-   */
-  com.google.protobuf.ByteString
-      getFileNameBytes();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/SourceContextProto.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/SourceContextProto.java
deleted file mode 100644
index 71ca660..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/SourceContextProto.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/source_context.proto
-
-package com.google.protobuf;
-
-public final class SourceContextProto {
-  private SourceContextProto() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/StringValue.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/StringValue.java
deleted file mode 100644
index 6404629..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/StringValue.java
+++ /dev/null
@@ -1,335 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/wrappers.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * Wrapper message for `string`.
- * The JSON representation for `StringValue` is JSON string.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.StringValue}
- */
-public  final class StringValue extends
-    com.google.protobuf.GeneratedMessageLite<
-        StringValue, StringValue.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.StringValue)
-    StringValueOrBuilder {
-  private StringValue() {
-    value_ = "";
-  }
-  public static final int VALUE_FIELD_NUMBER = 1;
-  private java.lang.String value_;
-  /**
-   * <pre>
-   * The string value.
-   * </pre>
-   *
-   * <code>string value = 1;</code>
-   * @return The value.
-   */
-  @java.lang.Override
-  public java.lang.String getValue() {
-    return value_;
-  }
-  /**
-   * <pre>
-   * The string value.
-   * </pre>
-   *
-   * <code>string value = 1;</code>
-   * @return The bytes for value.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getValueBytes() {
-    return com.google.protobuf.ByteString.copyFromUtf8(value_);
-  }
-  /**
-   * <pre>
-   * The string value.
-   * </pre>
-   *
-   * <code>string value = 1;</code>
-   * @param value The value to set.
-   */
-  private void setValue(
-      java.lang.String value) {
-    value.getClass();
-  
-    value_ = value;
-  }
-  /**
-   * <pre>
-   * The string value.
-   * </pre>
-   *
-   * <code>string value = 1;</code>
-   */
-  private void clearValue() {
-    
-    value_ = getDefaultInstance().getValue();
-  }
-  /**
-   * <pre>
-   * The string value.
-   * </pre>
-   *
-   * <code>string value = 1;</code>
-   * @param value The bytes for value to set.
-   */
-  private void setValueBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    value_ = value.toStringUtf8();
-    
-  }
-
-  public static com.google.protobuf.StringValue parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.StringValue parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.StringValue parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.StringValue parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.StringValue parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.StringValue parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.StringValue parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.StringValue parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.StringValue parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.StringValue parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.StringValue parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.StringValue parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.StringValue prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * Wrapper message for `string`.
-   * The JSON representation for `StringValue` is JSON string.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.StringValue}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.StringValue, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.StringValue)
-      com.google.protobuf.StringValueOrBuilder {
-    // Construct using com.google.protobuf.StringValue.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * The string value.
-     * </pre>
-     *
-     * <code>string value = 1;</code>
-     * @return The value.
-     */
-    @java.lang.Override
-    public java.lang.String getValue() {
-      return instance.getValue();
-    }
-    /**
-     * <pre>
-     * The string value.
-     * </pre>
-     *
-     * <code>string value = 1;</code>
-     * @return The bytes for value.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getValueBytes() {
-      return instance.getValueBytes();
-    }
-    /**
-     * <pre>
-     * The string value.
-     * </pre>
-     *
-     * <code>string value = 1;</code>
-     * @param value The value to set.
-     * @return This builder for chaining.
-     */
-    public Builder setValue(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.setValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The string value.
-     * </pre>
-     *
-     * <code>string value = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearValue() {
-      copyOnWrite();
-      instance.clearValue();
-      return this;
-    }
-    /**
-     * <pre>
-     * The string value.
-     * </pre>
-     *
-     * <code>string value = 1;</code>
-     * @param value The bytes for value to set.
-     * @return This builder for chaining.
-     */
-    public Builder setValueBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setValueBytes(value);
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.StringValue)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.StringValue();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "value_",
-          };
-          java.lang.String info =
-              "\u0000\u0001\u0000\u0000\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u0208";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.StringValue> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.StringValue.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.StringValue>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.StringValue)
-  private static final com.google.protobuf.StringValue DEFAULT_INSTANCE;
-  static {
-    StringValue defaultInstance = new StringValue();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      StringValue.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.StringValue getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  public static com.google.protobuf.StringValue of(java.lang.String value) {
-    return newBuilder().setValue(value).build();
-  }
-
-  private static volatile com.google.protobuf.Parser<StringValue> PARSER;
-
-  public static com.google.protobuf.Parser<StringValue> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/StringValueOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/StringValueOrBuilder.java
deleted file mode 100644
index 3c53a2a..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/StringValueOrBuilder.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/wrappers.proto
-
-package com.google.protobuf;
-
-public interface StringValueOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.StringValue)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * The string value.
-   * </pre>
-   *
-   * <code>string value = 1;</code>
-   * @return The value.
-   */
-  java.lang.String getValue();
-  /**
-   * <pre>
-   * The string value.
-   * </pre>
-   *
-   * <code>string value = 1;</code>
-   * @return The bytes for value.
-   */
-  com.google.protobuf.ByteString
-      getValueBytes();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Struct.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Struct.java
deleted file mode 100644
index eb1ca16..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Struct.java
+++ /dev/null
@@ -1,444 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/struct.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * `Struct` represents a structured data value, consisting of fields
- * which map to dynamically typed values. In some languages, `Struct`
- * might be supported by a native representation. For example, in
- * scripting languages like JS a struct is represented as an
- * object. The details of that representation are described together
- * with the proto support for the language.
- * The JSON representation for `Struct` is JSON object.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.Struct}
- */
-public  final class Struct extends
-    com.google.protobuf.GeneratedMessageLite<
-        Struct, Struct.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.Struct)
-    StructOrBuilder {
-  private Struct() {
-  }
-  public static final int FIELDS_FIELD_NUMBER = 1;
-  private static final class FieldsDefaultEntryHolder {
-    static final com.google.protobuf.MapEntryLite<
-        java.lang.String, com.google.protobuf.Value> defaultEntry =
-            com.google.protobuf.MapEntryLite
-            .<java.lang.String, com.google.protobuf.Value>newDefaultInstance(
-                com.google.protobuf.WireFormat.FieldType.STRING,
-                "",
-                com.google.protobuf.WireFormat.FieldType.MESSAGE,
-                com.google.protobuf.Value.getDefaultInstance());
-  }
-  private com.google.protobuf.MapFieldLite<
-      java.lang.String, com.google.protobuf.Value> fields_ =
-          com.google.protobuf.MapFieldLite.emptyMapField();
-  private com.google.protobuf.MapFieldLite<java.lang.String, com.google.protobuf.Value>
-  internalGetFields() {
-    return fields_;
-  }
-  private com.google.protobuf.MapFieldLite<java.lang.String, com.google.protobuf.Value>
-  internalGetMutableFields() {
-    if (!fields_.isMutable()) {
-      fields_ = fields_.mutableCopy();
-    }
-    return fields_;
-  }
-  @java.lang.Override
-
-  public int getFieldsCount() {
-    return internalGetFields().size();
-  }
-  /**
-   * <pre>
-   * Unordered map of dynamically typed values.
-   * </pre>
-   *
-   * <code>map&lt;string, .google.protobuf.Value&gt; fields = 1;</code>
-   */
-  @java.lang.Override
-
-  public boolean containsFields(
-      java.lang.String key) {
-    key.getClass();
-    return internalGetFields().containsKey(key);
-  }
-  /**
-   * Use {@link #getFieldsMap()} instead.
-   */
-  @java.lang.Override
-  @java.lang.Deprecated
-  public java.util.Map<java.lang.String, com.google.protobuf.Value> getFields() {
-    return getFieldsMap();
-  }
-  /**
-   * <pre>
-   * Unordered map of dynamically typed values.
-   * </pre>
-   *
-   * <code>map&lt;string, .google.protobuf.Value&gt; fields = 1;</code>
-   */
-  @java.lang.Override
-
-  public java.util.Map<java.lang.String, com.google.protobuf.Value> getFieldsMap() {
-    return java.util.Collections.unmodifiableMap(
-        internalGetFields());
-  }
-  /**
-   * <pre>
-   * Unordered map of dynamically typed values.
-   * </pre>
-   *
-   * <code>map&lt;string, .google.protobuf.Value&gt; fields = 1;</code>
-   */
-  @java.lang.Override
-
-  public com.google.protobuf.Value getFieldsOrDefault(
-      java.lang.String key,
-      com.google.protobuf.Value defaultValue) {
-    key.getClass();
-    java.util.Map<java.lang.String, com.google.protobuf.Value> map =
-        internalGetFields();
-    return map.containsKey(key) ? map.get(key) : defaultValue;
-  }
-  /**
-   * <pre>
-   * Unordered map of dynamically typed values.
-   * </pre>
-   *
-   * <code>map&lt;string, .google.protobuf.Value&gt; fields = 1;</code>
-   */
-  @java.lang.Override
-
-  public com.google.protobuf.Value getFieldsOrThrow(
-      java.lang.String key) {
-    key.getClass();
-    java.util.Map<java.lang.String, com.google.protobuf.Value> map =
-        internalGetFields();
-    if (!map.containsKey(key)) {
-      throw new java.lang.IllegalArgumentException();
-    }
-    return map.get(key);
-  }
-  /**
-   * <pre>
-   * Unordered map of dynamically typed values.
-   * </pre>
-   *
-   * <code>map&lt;string, .google.protobuf.Value&gt; fields = 1;</code>
-   */
-  private java.util.Map<java.lang.String, com.google.protobuf.Value>
-  getMutableFieldsMap() {
-    return internalGetMutableFields();
-  }
-
-  public static com.google.protobuf.Struct parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Struct parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Struct parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Struct parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Struct parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Struct parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Struct parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Struct parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Struct parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Struct parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Struct parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Struct parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.Struct prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * `Struct` represents a structured data value, consisting of fields
-   * which map to dynamically typed values. In some languages, `Struct`
-   * might be supported by a native representation. For example, in
-   * scripting languages like JS a struct is represented as an
-   * object. The details of that representation are described together
-   * with the proto support for the language.
-   * The JSON representation for `Struct` is JSON object.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.Struct}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.Struct, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.Struct)
-      com.google.protobuf.StructOrBuilder {
-    // Construct using com.google.protobuf.Struct.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    @java.lang.Override
-
-    public int getFieldsCount() {
-      return instance.getFieldsMap().size();
-    }
-    /**
-     * <pre>
-     * Unordered map of dynamically typed values.
-     * </pre>
-     *
-     * <code>map&lt;string, .google.protobuf.Value&gt; fields = 1;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsFields(
-        java.lang.String key) {
-      key.getClass();
-      return instance.getFieldsMap().containsKey(key);
-    }
-
-    public Builder clearFields() {
-      copyOnWrite();
-      instance.getMutableFieldsMap().clear();
-      return this;
-    }
-    /**
-     * <pre>
-     * Unordered map of dynamically typed values.
-     * </pre>
-     *
-     * <code>map&lt;string, .google.protobuf.Value&gt; fields = 1;</code>
-     */
-
-    public Builder removeFields(
-        java.lang.String key) {
-      key.getClass();
-      copyOnWrite();
-      instance.getMutableFieldsMap().remove(key);
-      return this;
-    }
-    /**
-     * Use {@link #getFieldsMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.String, com.google.protobuf.Value> getFields() {
-      return getFieldsMap();
-    }
-    /**
-     * <pre>
-     * Unordered map of dynamically typed values.
-     * </pre>
-     *
-     * <code>map&lt;string, .google.protobuf.Value&gt; fields = 1;</code>
-     */
-    @java.lang.Override
-    public java.util.Map<java.lang.String, com.google.protobuf.Value> getFieldsMap() {
-      return java.util.Collections.unmodifiableMap(
-          instance.getFieldsMap());
-    }
-    /**
-     * <pre>
-     * Unordered map of dynamically typed values.
-     * </pre>
-     *
-     * <code>map&lt;string, .google.protobuf.Value&gt; fields = 1;</code>
-     */
-    @java.lang.Override
-
-    public com.google.protobuf.Value getFieldsOrDefault(
-        java.lang.String key,
-        com.google.protobuf.Value defaultValue) {
-      key.getClass();
-      java.util.Map<java.lang.String, com.google.protobuf.Value> map =
-          instance.getFieldsMap();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <pre>
-     * Unordered map of dynamically typed values.
-     * </pre>
-     *
-     * <code>map&lt;string, .google.protobuf.Value&gt; fields = 1;</code>
-     */
-    @java.lang.Override
-
-    public com.google.protobuf.Value getFieldsOrThrow(
-        java.lang.String key) {
-      key.getClass();
-      java.util.Map<java.lang.String, com.google.protobuf.Value> map =
-          instance.getFieldsMap();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <pre>
-     * Unordered map of dynamically typed values.
-     * </pre>
-     *
-     * <code>map&lt;string, .google.protobuf.Value&gt; fields = 1;</code>
-     */
-    public Builder putFields(
-        java.lang.String key,
-        com.google.protobuf.Value value) {
-      key.getClass();
-      value.getClass();
-      copyOnWrite();
-      instance.getMutableFieldsMap().put(key, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Unordered map of dynamically typed values.
-     * </pre>
-     *
-     * <code>map&lt;string, .google.protobuf.Value&gt; fields = 1;</code>
-     */
-    public Builder putAllFields(
-        java.util.Map<java.lang.String, com.google.protobuf.Value> values) {
-      copyOnWrite();
-      instance.getMutableFieldsMap().putAll(values);
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.Struct)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.Struct();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "fields_",
-            FieldsDefaultEntryHolder.defaultEntry,
-          };
-          java.lang.String info =
-              "\u0000\u0001\u0000\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u00012";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.Struct> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.Struct.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.Struct>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.Struct)
-  private static final com.google.protobuf.Struct DEFAULT_INSTANCE;
-  static {
-    Struct defaultInstance = new Struct();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      Struct.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.Struct getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<Struct> PARSER;
-
-  public static com.google.protobuf.Parser<Struct> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/StructOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/StructOrBuilder.java
deleted file mode 100644
index ea54f7b..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/StructOrBuilder.java
+++ /dev/null
@@ -1,63 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/struct.proto
-
-package com.google.protobuf;
-
-public interface StructOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.Struct)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * Unordered map of dynamically typed values.
-   * </pre>
-   *
-   * <code>map&lt;string, .google.protobuf.Value&gt; fields = 1;</code>
-   */
-  int getFieldsCount();
-  /**
-   * <pre>
-   * Unordered map of dynamically typed values.
-   * </pre>
-   *
-   * <code>map&lt;string, .google.protobuf.Value&gt; fields = 1;</code>
-   */
-  boolean containsFields(
-      java.lang.String key);
-  /**
-   * Use {@link #getFieldsMap()} instead.
-   */
-  @java.lang.Deprecated
-  java.util.Map<java.lang.String, com.google.protobuf.Value>
-  getFields();
-  /**
-   * <pre>
-   * Unordered map of dynamically typed values.
-   * </pre>
-   *
-   * <code>map&lt;string, .google.protobuf.Value&gt; fields = 1;</code>
-   */
-  java.util.Map<java.lang.String, com.google.protobuf.Value>
-  getFieldsMap();
-  /**
-   * <pre>
-   * Unordered map of dynamically typed values.
-   * </pre>
-   *
-   * <code>map&lt;string, .google.protobuf.Value&gt; fields = 1;</code>
-   */
-
-  com.google.protobuf.Value getFieldsOrDefault(
-      java.lang.String key,
-      com.google.protobuf.Value defaultValue);
-  /**
-   * <pre>
-   * Unordered map of dynamically typed values.
-   * </pre>
-   *
-   * <code>map&lt;string, .google.protobuf.Value&gt; fields = 1;</code>
-   */
-
-  com.google.protobuf.Value getFieldsOrThrow(
-      java.lang.String key);
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/StructProto.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/StructProto.java
deleted file mode 100644
index be854cd..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/StructProto.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/struct.proto
-
-package com.google.protobuf;
-
-public final class StructProto {
-  private StructProto() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/StructuralMessageInfo.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/StructuralMessageInfo.java
deleted file mode 100644
index a32b143..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/StructuralMessageInfo.java
+++ /dev/null
@@ -1,167 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.Internal.checkNotNull;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Information for the layout of a protobuf message class. This describes all of the fields
- * contained within a message.
- */
-@ExperimentalApi
-final class StructuralMessageInfo implements MessageInfo {
-  private final ProtoSyntax syntax;
-  private final boolean messageSetWireFormat;
-  private final int[] checkInitialized;
-  private final FieldInfo[] fields;
-  private final MessageLite defaultInstance;
-
-  /**
-   * Constructor.
-   *
-   * @param checkInitialized fields to check in isInitialized().
-   * @param fields the set of fields for the message, in field number order.
-   */
-  StructuralMessageInfo(
-      ProtoSyntax syntax,
-      boolean messageSetWireFormat,
-      int[] checkInitialized,
-      FieldInfo[] fields,
-      Object defaultInstance) {
-    this.syntax = syntax;
-    this.messageSetWireFormat = messageSetWireFormat;
-    this.checkInitialized = checkInitialized;
-    this.fields = fields;
-    this.defaultInstance = (MessageLite) checkNotNull(defaultInstance, "defaultInstance");
-  }
-
-  /** Gets the syntax for the message (e.g. PROTO2, PROTO3). */
-  @Override
-  public ProtoSyntax getSyntax() {
-    return syntax;
-  }
-
-  /** Indicates whether or not the message should be represented with message set wire format. */
-  @Override
-  public boolean isMessageSetWireFormat() {
-    return messageSetWireFormat;
-  }
-
-  /** An array of field numbers that need to be checked for isInitialized(). */
-  public int[] getCheckInitialized() {
-    return checkInitialized;
-  }
-
-  /**
-   * Gets the information for all fields within this message, sorted in ascending order by their
-   * field number.
-   */
-  public FieldInfo[] getFields() {
-    return fields;
-  }
-
-  @Override
-  public MessageLite getDefaultInstance() {
-    return defaultInstance;
-  }
-
-  /** Helper method for creating a new builder for {@link MessageInfo}. */
-  public static Builder newBuilder() {
-    return new Builder();
-  }
-
-  /** Helper method for creating a new builder for {@link MessageInfo}. */
-  public static Builder newBuilder(int numFields) {
-    return new Builder(numFields);
-  }
-
-  /** A builder of {@link MessageInfo} instances. */
-  public static final class Builder {
-    private final List<FieldInfo> fields;
-    private ProtoSyntax syntax;
-    private boolean wasBuilt;
-    private boolean messageSetWireFormat;
-    private int[] checkInitialized = null;
-    private Object defaultInstance;
-
-    public Builder() {
-      fields = new ArrayList<FieldInfo>();
-    }
-
-    public Builder(int numFields) {
-      fields = new ArrayList<FieldInfo>(numFields);
-    }
-
-    public void withDefaultInstance(Object defaultInstance) {
-      this.defaultInstance = defaultInstance;
-    }
-
-    public void withSyntax(ProtoSyntax syntax) {
-      this.syntax = checkNotNull(syntax, "syntax");
-    }
-
-    public void withMessageSetWireFormat(boolean messageSetWireFormat) {
-      this.messageSetWireFormat = messageSetWireFormat;
-    }
-
-    public void withCheckInitialized(int[] checkInitialized) {
-      this.checkInitialized = checkInitialized;
-    }
-
-    public void withField(FieldInfo field) {
-      if (wasBuilt) {
-        throw new IllegalStateException("Builder can only build once");
-      }
-      fields.add(field);
-    }
-
-    public StructuralMessageInfo build() {
-      if (wasBuilt) {
-        throw new IllegalStateException("Builder can only build once");
-      }
-      if (syntax == null) {
-        throw new IllegalStateException("Must specify a proto syntax");
-      }
-      wasBuilt = true;
-      Collections.sort(fields);
-      return new StructuralMessageInfo(
-          syntax,
-          messageSetWireFormat,
-          checkInitialized,
-          fields.toArray(new FieldInfo[0]),
-          defaultInstance);
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Syntax.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Syntax.java
deleted file mode 100644
index 62c425a..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Syntax.java
+++ /dev/null
@@ -1,114 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/type.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * The syntax in which a protocol buffer element is defined.
- * </pre>
- *
- * Protobuf enum {@code google.protobuf.Syntax}
- */
-public enum Syntax
-    implements com.google.protobuf.Internal.EnumLite {
-  /**
-   * <pre>
-   * Syntax `proto2`.
-   * </pre>
-   *
-   * <code>SYNTAX_PROTO2 = 0;</code>
-   */
-  SYNTAX_PROTO2(0),
-  /**
-   * <pre>
-   * Syntax `proto3`.
-   * </pre>
-   *
-   * <code>SYNTAX_PROTO3 = 1;</code>
-   */
-  SYNTAX_PROTO3(1),
-  UNRECOGNIZED(-1),
-  ;
-
-  /**
-   * <pre>
-   * Syntax `proto2`.
-   * </pre>
-   *
-   * <code>SYNTAX_PROTO2 = 0;</code>
-   */
-  public static final int SYNTAX_PROTO2_VALUE = 0;
-  /**
-   * <pre>
-   * Syntax `proto3`.
-   * </pre>
-   *
-   * <code>SYNTAX_PROTO3 = 1;</code>
-   */
-  public static final int SYNTAX_PROTO3_VALUE = 1;
-
-
-  @java.lang.Override
-  public final int getNumber() {
-    if (this == UNRECOGNIZED) {
-      throw new java.lang.IllegalArgumentException(
-          "Can't get the number of an unknown enum value.");
-    }
-    return value;
-  }
-
-  /**
-   * @param value The number of the enum to look for.
-   * @return The enum associated with the given number.
-   * @deprecated Use {@link #forNumber(int)} instead.
-   */
-  @java.lang.Deprecated
-  public static Syntax valueOf(int value) {
-    return forNumber(value);
-  }
-
-  public static Syntax forNumber(int value) {
-    switch (value) {
-      case 0: return SYNTAX_PROTO2;
-      case 1: return SYNTAX_PROTO3;
-      default: return null;
-    }
-  }
-
-  public static com.google.protobuf.Internal.EnumLiteMap<Syntax>
-      internalGetValueMap() {
-    return internalValueMap;
-  }
-  private static final com.google.protobuf.Internal.EnumLiteMap<
-      Syntax> internalValueMap =
-        new com.google.protobuf.Internal.EnumLiteMap<Syntax>() {
-          @java.lang.Override
-          public Syntax findValueByNumber(int number) {
-            return Syntax.forNumber(number);
-          }
-        };
-
-  public static com.google.protobuf.Internal.EnumVerifier 
-      internalGetVerifier() {
-    return SyntaxVerifier.INSTANCE;
-  }
-
-  private static final class SyntaxVerifier implements 
-       com.google.protobuf.Internal.EnumVerifier { 
-          static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new SyntaxVerifier();
-          @java.lang.Override
-          public boolean isInRange(int number) {
-            return Syntax.forNumber(number) != null;
-          }
-        };
-
-  private final int value;
-
-  private Syntax(int value) {
-    this.value = value;
-  }
-
-  // @@protoc_insertion_point(enum_scope:google.protobuf.Syntax)
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/TextFormatEscaper.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/TextFormatEscaper.java
deleted file mode 100644
index 2501ec9..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/TextFormatEscaper.java
+++ /dev/null
@@ -1,152 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-/** Provide text format escaping support for proto2 instances. */
-final class TextFormatEscaper {
-  private TextFormatEscaper() {}
-
-  private interface ByteSequence {
-    int size();
-
-    byte byteAt(int offset);
-  }
-
-  /**
-   * Escapes bytes in the format used in protocol buffer text format, which is the same as the
-   * format used for C string literals. All bytes that are not printable 7-bit ASCII characters are
-   * escaped, as well as backslash, single-quote, and double-quote characters. Characters for which
-   * no defined short-hand escape sequence is defined will be escaped using 3-digit octal sequences.
-   */
-  static String escapeBytes(final ByteSequence input) {
-    final StringBuilder builder = new StringBuilder(input.size());
-    for (int i = 0; i < input.size(); i++) {
-      final byte b = input.byteAt(i);
-      switch (b) {
-          // Java does not recognize \a or \v, apparently.
-        case 0x07:
-          builder.append("\\a");
-          break;
-        case '\b':
-          builder.append("\\b");
-          break;
-        case '\f':
-          builder.append("\\f");
-          break;
-        case '\n':
-          builder.append("\\n");
-          break;
-        case '\r':
-          builder.append("\\r");
-          break;
-        case '\t':
-          builder.append("\\t");
-          break;
-        case 0x0b:
-          builder.append("\\v");
-          break;
-        case '\\':
-          builder.append("\\\\");
-          break;
-        case '\'':
-          builder.append("\\\'");
-          break;
-        case '"':
-          builder.append("\\\"");
-          break;
-        default:
-          // Only ASCII characters between 0x20 (space) and 0x7e (tilde) are
-          // printable.  Other byte values must be escaped.
-          if (b >= 0x20 && b <= 0x7e) {
-            builder.append((char) b);
-          } else {
-            builder.append('\\');
-            builder.append((char) ('0' + ((b >>> 6) & 3)));
-            builder.append((char) ('0' + ((b >>> 3) & 7)));
-            builder.append((char) ('0' + (b & 7)));
-          }
-          break;
-      }
-    }
-    return builder.toString();
-  }
-
-  /**
-   * Escapes bytes in the format used in protocol buffer text format, which is the same as the
-   * format used for C string literals. All bytes that are not printable 7-bit ASCII characters are
-   * escaped, as well as backslash, single-quote, and double-quote characters. Characters for which
-   * no defined short-hand escape sequence is defined will be escaped using 3-digit octal sequences.
-   */
-  static String escapeBytes(final ByteString input) {
-    return escapeBytes(
-        new ByteSequence() {
-          @Override
-          public int size() {
-            return input.size();
-          }
-
-          @Override
-          public byte byteAt(int offset) {
-            return input.byteAt(offset);
-          }
-        });
-  }
-
-  /** Like {@link #escapeBytes(ByteString)}, but used for byte array. */
-  static String escapeBytes(final byte[] input) {
-    return escapeBytes(
-        new ByteSequence() {
-          @Override
-          public int size() {
-            return input.length;
-          }
-
-          @Override
-          public byte byteAt(int offset) {
-            return input[offset];
-          }
-        });
-  }
-
-  /**
-   * Like {@link #escapeBytes(ByteString)}, but escapes a text string. Non-ASCII characters are
-   * first encoded as UTF-8, then each byte is escaped individually as a 3-digit octal escape. Yes,
-   * it's weird.
-   */
-  static String escapeText(final String input) {
-    return escapeBytes(ByteString.copyFromUtf8(input));
-  }
-
-  /** Escape double quotes and backslashes in a String for unicode output of a message. */
-  static String escapeDoubleQuotesAndBackslashes(final String input) {
-    return input.replace("\\", "\\\\").replace("\"", "\\\"");
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Timestamp.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Timestamp.java
deleted file mode 100644
index ca7313b..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Timestamp.java
+++ /dev/null
@@ -1,510 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/timestamp.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * A Timestamp represents a point in time independent of any time zone or local
- * calendar, encoded as a count of seconds and fractions of seconds at
- * nanosecond resolution. The count is relative to an epoch at UTC midnight on
- * January 1, 1970, in the proleptic Gregorian calendar which extends the
- * Gregorian calendar backwards to year one.
- * All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap
- * second table is needed for interpretation, using a [24-hour linear
- * smear](https://developers.google.com/time/smear).
- * The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By
- * restricting to that range, we ensure that we can convert to and from [RFC
- * 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings.
- * # Examples
- * Example 1: Compute Timestamp from POSIX `time()`.
- *     Timestamp timestamp;
- *     timestamp.set_seconds(time(NULL));
- *     timestamp.set_nanos(0);
- * Example 2: Compute Timestamp from POSIX `gettimeofday()`.
- *     struct timeval tv;
- *     gettimeofday(&amp;tv, NULL);
- *     Timestamp timestamp;
- *     timestamp.set_seconds(tv.tv_sec);
- *     timestamp.set_nanos(tv.tv_usec * 1000);
- * Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
- *     FILETIME ft;
- *     GetSystemTimeAsFileTime(&amp;ft);
- *     UINT64 ticks = (((UINT64)ft.dwHighDateTime) &lt;&lt; 32) | ft.dwLowDateTime;
- *     // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
- *     // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
- *     Timestamp timestamp;
- *     timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
- *     timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
- * Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
- *     long millis = System.currentTimeMillis();
- *     Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
- *         .setNanos((int) ((millis % 1000) * 1000000)).build();
- * Example 5: Compute Timestamp from Java `Instant.now()`.
- *     Instant now = Instant.now();
- *     Timestamp timestamp =
- *         Timestamp.newBuilder().setSeconds(now.getEpochSecond())
- *             .setNanos(now.getNano()).build();
- * Example 6: Compute Timestamp from current time in Python.
- *     timestamp = Timestamp()
- *     timestamp.GetCurrentTime()
- * # JSON Mapping
- * In JSON format, the Timestamp type is encoded as a string in the
- * [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
- * format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
- * where {year} is always expressed using four digits while {month}, {day},
- * {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
- * seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
- * are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
- * is required. A proto3 JSON serializer should always use UTC (as indicated by
- * "Z") when printing the Timestamp type and a proto3 JSON parser should be
- * able to accept both UTC and other timezones (as indicated by an offset).
- * For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
- * 01:30 UTC on January 15, 2017.
- * In JavaScript, one can convert a Date object to this format using the
- * standard
- * [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
- * method. In Python, a standard `datetime.datetime` object can be converted
- * to this format using
- * [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with
- * the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use
- * the Joda Time's [`ISODateTimeFormat.dateTime()`](
- * http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D
- * ) to obtain a formatter capable of generating timestamps in this format.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.Timestamp}
- */
-public  final class Timestamp extends
-    com.google.protobuf.GeneratedMessageLite<
-        Timestamp, Timestamp.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.Timestamp)
-    TimestampOrBuilder {
-  private Timestamp() {
-  }
-  public static final int SECONDS_FIELD_NUMBER = 1;
-  private long seconds_;
-  /**
-   * <pre>
-   * Represents seconds of UTC time since Unix epoch
-   * 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
-   * 9999-12-31T23:59:59Z inclusive.
-   * </pre>
-   *
-   * <code>int64 seconds = 1;</code>
-   * @return The seconds.
-   */
-  @java.lang.Override
-  public long getSeconds() {
-    return seconds_;
-  }
-  /**
-   * <pre>
-   * Represents seconds of UTC time since Unix epoch
-   * 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
-   * 9999-12-31T23:59:59Z inclusive.
-   * </pre>
-   *
-   * <code>int64 seconds = 1;</code>
-   * @param value The seconds to set.
-   */
-  private void setSeconds(long value) {
-    
-    seconds_ = value;
-  }
-  /**
-   * <pre>
-   * Represents seconds of UTC time since Unix epoch
-   * 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
-   * 9999-12-31T23:59:59Z inclusive.
-   * </pre>
-   *
-   * <code>int64 seconds = 1;</code>
-   */
-  private void clearSeconds() {
-    
-    seconds_ = 0L;
-  }
-
-  public static final int NANOS_FIELD_NUMBER = 2;
-  private int nanos_;
-  /**
-   * <pre>
-   * Non-negative fractions of a second at nanosecond resolution. Negative
-   * second values with fractions must still have non-negative nanos values
-   * that count forward in time. Must be from 0 to 999,999,999
-   * inclusive.
-   * </pre>
-   *
-   * <code>int32 nanos = 2;</code>
-   * @return The nanos.
-   */
-  @java.lang.Override
-  public int getNanos() {
-    return nanos_;
-  }
-  /**
-   * <pre>
-   * Non-negative fractions of a second at nanosecond resolution. Negative
-   * second values with fractions must still have non-negative nanos values
-   * that count forward in time. Must be from 0 to 999,999,999
-   * inclusive.
-   * </pre>
-   *
-   * <code>int32 nanos = 2;</code>
-   * @param value The nanos to set.
-   */
-  private void setNanos(int value) {
-    
-    nanos_ = value;
-  }
-  /**
-   * <pre>
-   * Non-negative fractions of a second at nanosecond resolution. Negative
-   * second values with fractions must still have non-negative nanos values
-   * that count forward in time. Must be from 0 to 999,999,999
-   * inclusive.
-   * </pre>
-   *
-   * <code>int32 nanos = 2;</code>
-   */
-  private void clearNanos() {
-    
-    nanos_ = 0;
-  }
-
-  public static com.google.protobuf.Timestamp parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Timestamp parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Timestamp parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Timestamp parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Timestamp parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Timestamp parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Timestamp parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Timestamp parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Timestamp parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Timestamp parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Timestamp parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Timestamp parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.Timestamp prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * A Timestamp represents a point in time independent of any time zone or local
-   * calendar, encoded as a count of seconds and fractions of seconds at
-   * nanosecond resolution. The count is relative to an epoch at UTC midnight on
-   * January 1, 1970, in the proleptic Gregorian calendar which extends the
-   * Gregorian calendar backwards to year one.
-   * All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap
-   * second table is needed for interpretation, using a [24-hour linear
-   * smear](https://developers.google.com/time/smear).
-   * The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By
-   * restricting to that range, we ensure that we can convert to and from [RFC
-   * 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings.
-   * # Examples
-   * Example 1: Compute Timestamp from POSIX `time()`.
-   *     Timestamp timestamp;
-   *     timestamp.set_seconds(time(NULL));
-   *     timestamp.set_nanos(0);
-   * Example 2: Compute Timestamp from POSIX `gettimeofday()`.
-   *     struct timeval tv;
-   *     gettimeofday(&amp;tv, NULL);
-   *     Timestamp timestamp;
-   *     timestamp.set_seconds(tv.tv_sec);
-   *     timestamp.set_nanos(tv.tv_usec * 1000);
-   * Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
-   *     FILETIME ft;
-   *     GetSystemTimeAsFileTime(&amp;ft);
-   *     UINT64 ticks = (((UINT64)ft.dwHighDateTime) &lt;&lt; 32) | ft.dwLowDateTime;
-   *     // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
-   *     // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
-   *     Timestamp timestamp;
-   *     timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
-   *     timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
-   * Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
-   *     long millis = System.currentTimeMillis();
-   *     Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
-   *         .setNanos((int) ((millis % 1000) * 1000000)).build();
-   * Example 5: Compute Timestamp from Java `Instant.now()`.
-   *     Instant now = Instant.now();
-   *     Timestamp timestamp =
-   *         Timestamp.newBuilder().setSeconds(now.getEpochSecond())
-   *             .setNanos(now.getNano()).build();
-   * Example 6: Compute Timestamp from current time in Python.
-   *     timestamp = Timestamp()
-   *     timestamp.GetCurrentTime()
-   * # JSON Mapping
-   * In JSON format, the Timestamp type is encoded as a string in the
-   * [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
-   * format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
-   * where {year} is always expressed using four digits while {month}, {day},
-   * {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
-   * seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
-   * are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
-   * is required. A proto3 JSON serializer should always use UTC (as indicated by
-   * "Z") when printing the Timestamp type and a proto3 JSON parser should be
-   * able to accept both UTC and other timezones (as indicated by an offset).
-   * For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
-   * 01:30 UTC on January 15, 2017.
-   * In JavaScript, one can convert a Date object to this format using the
-   * standard
-   * [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
-   * method. In Python, a standard `datetime.datetime` object can be converted
-   * to this format using
-   * [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with
-   * the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use
-   * the Joda Time's [`ISODateTimeFormat.dateTime()`](
-   * http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D
-   * ) to obtain a formatter capable of generating timestamps in this format.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.Timestamp}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.Timestamp, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.Timestamp)
-      com.google.protobuf.TimestampOrBuilder {
-    // Construct using com.google.protobuf.Timestamp.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * Represents seconds of UTC time since Unix epoch
-     * 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
-     * 9999-12-31T23:59:59Z inclusive.
-     * </pre>
-     *
-     * <code>int64 seconds = 1;</code>
-     * @return The seconds.
-     */
-    @java.lang.Override
-    public long getSeconds() {
-      return instance.getSeconds();
-    }
-    /**
-     * <pre>
-     * Represents seconds of UTC time since Unix epoch
-     * 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
-     * 9999-12-31T23:59:59Z inclusive.
-     * </pre>
-     *
-     * <code>int64 seconds = 1;</code>
-     * @param value The seconds to set.
-     * @return This builder for chaining.
-     */
-    public Builder setSeconds(long value) {
-      copyOnWrite();
-      instance.setSeconds(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Represents seconds of UTC time since Unix epoch
-     * 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
-     * 9999-12-31T23:59:59Z inclusive.
-     * </pre>
-     *
-     * <code>int64 seconds = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearSeconds() {
-      copyOnWrite();
-      instance.clearSeconds();
-      return this;
-    }
-
-    /**
-     * <pre>
-     * Non-negative fractions of a second at nanosecond resolution. Negative
-     * second values with fractions must still have non-negative nanos values
-     * that count forward in time. Must be from 0 to 999,999,999
-     * inclusive.
-     * </pre>
-     *
-     * <code>int32 nanos = 2;</code>
-     * @return The nanos.
-     */
-    @java.lang.Override
-    public int getNanos() {
-      return instance.getNanos();
-    }
-    /**
-     * <pre>
-     * Non-negative fractions of a second at nanosecond resolution. Negative
-     * second values with fractions must still have non-negative nanos values
-     * that count forward in time. Must be from 0 to 999,999,999
-     * inclusive.
-     * </pre>
-     *
-     * <code>int32 nanos = 2;</code>
-     * @param value The nanos to set.
-     * @return This builder for chaining.
-     */
-    public Builder setNanos(int value) {
-      copyOnWrite();
-      instance.setNanos(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Non-negative fractions of a second at nanosecond resolution. Negative
-     * second values with fractions must still have non-negative nanos values
-     * that count forward in time. Must be from 0 to 999,999,999
-     * inclusive.
-     * </pre>
-     *
-     * <code>int32 nanos = 2;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearNanos() {
-      copyOnWrite();
-      instance.clearNanos();
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.Timestamp)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.Timestamp();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "seconds_",
-            "nanos_",
-          };
-          java.lang.String info =
-              "\u0000\u0002\u0000\u0000\u0001\u0002\u0002\u0000\u0000\u0000\u0001\u0002\u0002\u0004" +
-              "";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.Timestamp> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.Timestamp.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.Timestamp>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.Timestamp)
-  private static final com.google.protobuf.Timestamp DEFAULT_INSTANCE;
-  static {
-    Timestamp defaultInstance = new Timestamp();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      Timestamp.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.Timestamp getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<Timestamp> PARSER;
-
-  public static com.google.protobuf.Parser<Timestamp> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/TimestampOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/TimestampOrBuilder.java
deleted file mode 100644
index 7876182..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/TimestampOrBuilder.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/timestamp.proto
-
-package com.google.protobuf;
-
-public interface TimestampOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.Timestamp)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * Represents seconds of UTC time since Unix epoch
-   * 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
-   * 9999-12-31T23:59:59Z inclusive.
-   * </pre>
-   *
-   * <code>int64 seconds = 1;</code>
-   * @return The seconds.
-   */
-  long getSeconds();
-
-  /**
-   * <pre>
-   * Non-negative fractions of a second at nanosecond resolution. Negative
-   * second values with fractions must still have non-negative nanos values
-   * that count forward in time. Must be from 0 to 999,999,999
-   * inclusive.
-   * </pre>
-   *
-   * <code>int32 nanos = 2;</code>
-   * @return The nanos.
-   */
-  int getNanos();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/TimestampProto.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/TimestampProto.java
deleted file mode 100644
index 9c99eea..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/TimestampProto.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/timestamp.proto
-
-package com.google.protobuf;
-
-public final class TimestampProto {
-  private TimestampProto() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Type.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Type.java
deleted file mode 100644
index e87dfea..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Type.java
+++ /dev/null
@@ -1,1438 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/type.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * A protocol buffer message type.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.Type}
- */
-public  final class Type extends
-    com.google.protobuf.GeneratedMessageLite<
-        Type, Type.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.Type)
-    TypeOrBuilder {
-  private Type() {
-    name_ = "";
-    fields_ = emptyProtobufList();
-    oneofs_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    options_ = emptyProtobufList();
-  }
-  public static final int NAME_FIELD_NUMBER = 1;
-  private java.lang.String name_;
-  /**
-   * <pre>
-   * The fully qualified message name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The name.
-   */
-  @java.lang.Override
-  public java.lang.String getName() {
-    return name_;
-  }
-  /**
-   * <pre>
-   * The fully qualified message name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The bytes for name.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getNameBytes() {
-    return com.google.protobuf.ByteString.copyFromUtf8(name_);
-  }
-  /**
-   * <pre>
-   * The fully qualified message name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @param value The name to set.
-   */
-  private void setName(
-      java.lang.String value) {
-    value.getClass();
-  
-    name_ = value;
-  }
-  /**
-   * <pre>
-   * The fully qualified message name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   */
-  private void clearName() {
-    
-    name_ = getDefaultInstance().getName();
-  }
-  /**
-   * <pre>
-   * The fully qualified message name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @param value The bytes for name to set.
-   */
-  private void setNameBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    name_ = value.toStringUtf8();
-    
-  }
-
-  public static final int FIELDS_FIELD_NUMBER = 2;
-  private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Field> fields_;
-  /**
-   * <pre>
-   * The list of fields.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Field fields = 2;</code>
-   */
-  @java.lang.Override
-  public java.util.List<com.google.protobuf.Field> getFieldsList() {
-    return fields_;
-  }
-  /**
-   * <pre>
-   * The list of fields.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Field fields = 2;</code>
-   */
-  public java.util.List<? extends com.google.protobuf.FieldOrBuilder> 
-      getFieldsOrBuilderList() {
-    return fields_;
-  }
-  /**
-   * <pre>
-   * The list of fields.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Field fields = 2;</code>
-   */
-  @java.lang.Override
-  public int getFieldsCount() {
-    return fields_.size();
-  }
-  /**
-   * <pre>
-   * The list of fields.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Field fields = 2;</code>
-   */
-  @java.lang.Override
-  public com.google.protobuf.Field getFields(int index) {
-    return fields_.get(index);
-  }
-  /**
-   * <pre>
-   * The list of fields.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Field fields = 2;</code>
-   */
-  public com.google.protobuf.FieldOrBuilder getFieldsOrBuilder(
-      int index) {
-    return fields_.get(index);
-  }
-  private void ensureFieldsIsMutable() {
-    com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Field> tmp = fields_;
-    if (!tmp.isModifiable()) {
-      fields_ =
-          com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-     }
-  }
-
-  /**
-   * <pre>
-   * The list of fields.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Field fields = 2;</code>
-   */
-  private void setFields(
-      int index, com.google.protobuf.Field value) {
-    value.getClass();
-  ensureFieldsIsMutable();
-    fields_.set(index, value);
-  }
-  /**
-   * <pre>
-   * The list of fields.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Field fields = 2;</code>
-   */
-  private void addFields(com.google.protobuf.Field value) {
-    value.getClass();
-  ensureFieldsIsMutable();
-    fields_.add(value);
-  }
-  /**
-   * <pre>
-   * The list of fields.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Field fields = 2;</code>
-   */
-  private void addFields(
-      int index, com.google.protobuf.Field value) {
-    value.getClass();
-  ensureFieldsIsMutable();
-    fields_.add(index, value);
-  }
-  /**
-   * <pre>
-   * The list of fields.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Field fields = 2;</code>
-   */
-  private void addAllFields(
-      java.lang.Iterable<? extends com.google.protobuf.Field> values) {
-    ensureFieldsIsMutable();
-    com.google.protobuf.AbstractMessageLite.addAll(
-        values, fields_);
-  }
-  /**
-   * <pre>
-   * The list of fields.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Field fields = 2;</code>
-   */
-  private void clearFields() {
-    fields_ = emptyProtobufList();
-  }
-  /**
-   * <pre>
-   * The list of fields.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Field fields = 2;</code>
-   */
-  private void removeFields(int index) {
-    ensureFieldsIsMutable();
-    fields_.remove(index);
-  }
-
-  public static final int ONEOFS_FIELD_NUMBER = 3;
-  private com.google.protobuf.Internal.ProtobufList<java.lang.String> oneofs_;
-  /**
-   * <pre>
-   * The list of types appearing in `oneof` definitions in this type.
-   * </pre>
-   *
-   * <code>repeated string oneofs = 3;</code>
-   * @return A list containing the oneofs.
-   */
-  @java.lang.Override
-  public java.util.List<java.lang.String> getOneofsList() {
-    return oneofs_;
-  }
-  /**
-   * <pre>
-   * The list of types appearing in `oneof` definitions in this type.
-   * </pre>
-   *
-   * <code>repeated string oneofs = 3;</code>
-   * @return The count of oneofs.
-   */
-  @java.lang.Override
-  public int getOneofsCount() {
-    return oneofs_.size();
-  }
-  /**
-   * <pre>
-   * The list of types appearing in `oneof` definitions in this type.
-   * </pre>
-   *
-   * <code>repeated string oneofs = 3;</code>
-   * @param index The index of the element to return.
-   * @return The oneofs at the given index.
-   */
-  @java.lang.Override
-  public java.lang.String getOneofs(int index) {
-    return oneofs_.get(index);
-  }
-  /**
-   * <pre>
-   * The list of types appearing in `oneof` definitions in this type.
-   * </pre>
-   *
-   * <code>repeated string oneofs = 3;</code>
-   * @param index The index of the value to return.
-   * @return The bytes of the oneofs at the given index.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getOneofsBytes(int index) {
-    return com.google.protobuf.ByteString.copyFromUtf8(
-        oneofs_.get(index));
-  }
-  private void ensureOneofsIsMutable() {
-    com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-        oneofs_;  if (!tmp.isModifiable()) {
-      oneofs_ =
-          com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-     }
-  }
-  /**
-   * <pre>
-   * The list of types appearing in `oneof` definitions in this type.
-   * </pre>
-   *
-   * <code>repeated string oneofs = 3;</code>
-   * @param index The index to set the value at.
-   * @param value The oneofs to set.
-   */
-  private void setOneofs(
-      int index, java.lang.String value) {
-    value.getClass();
-  ensureOneofsIsMutable();
-    oneofs_.set(index, value);
-  }
-  /**
-   * <pre>
-   * The list of types appearing in `oneof` definitions in this type.
-   * </pre>
-   *
-   * <code>repeated string oneofs = 3;</code>
-   * @param value The oneofs to add.
-   */
-  private void addOneofs(
-      java.lang.String value) {
-    value.getClass();
-  ensureOneofsIsMutable();
-    oneofs_.add(value);
-  }
-  /**
-   * <pre>
-   * The list of types appearing in `oneof` definitions in this type.
-   * </pre>
-   *
-   * <code>repeated string oneofs = 3;</code>
-   * @param values The oneofs to add.
-   */
-  private void addAllOneofs(
-      java.lang.Iterable<java.lang.String> values) {
-    ensureOneofsIsMutable();
-    com.google.protobuf.AbstractMessageLite.addAll(
-        values, oneofs_);
-  }
-  /**
-   * <pre>
-   * The list of types appearing in `oneof` definitions in this type.
-   * </pre>
-   *
-   * <code>repeated string oneofs = 3;</code>
-   */
-  private void clearOneofs() {
-    oneofs_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-  }
-  /**
-   * <pre>
-   * The list of types appearing in `oneof` definitions in this type.
-   * </pre>
-   *
-   * <code>repeated string oneofs = 3;</code>
-   * @param value The bytes of the oneofs to add.
-   */
-  private void addOneofsBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    ensureOneofsIsMutable();
-    oneofs_.add(value.toStringUtf8());
-  }
-
-  public static final int OPTIONS_FIELD_NUMBER = 4;
-  private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Option> options_;
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 4;</code>
-   */
-  @java.lang.Override
-  public java.util.List<com.google.protobuf.Option> getOptionsList() {
-    return options_;
-  }
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 4;</code>
-   */
-  public java.util.List<? extends com.google.protobuf.OptionOrBuilder> 
-      getOptionsOrBuilderList() {
-    return options_;
-  }
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 4;</code>
-   */
-  @java.lang.Override
-  public int getOptionsCount() {
-    return options_.size();
-  }
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 4;</code>
-   */
-  @java.lang.Override
-  public com.google.protobuf.Option getOptions(int index) {
-    return options_.get(index);
-  }
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 4;</code>
-   */
-  public com.google.protobuf.OptionOrBuilder getOptionsOrBuilder(
-      int index) {
-    return options_.get(index);
-  }
-  private void ensureOptionsIsMutable() {
-    com.google.protobuf.Internal.ProtobufList<com.google.protobuf.Option> tmp = options_;
-    if (!tmp.isModifiable()) {
-      options_ =
-          com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-     }
-  }
-
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 4;</code>
-   */
-  private void setOptions(
-      int index, com.google.protobuf.Option value) {
-    value.getClass();
-  ensureOptionsIsMutable();
-    options_.set(index, value);
-  }
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 4;</code>
-   */
-  private void addOptions(com.google.protobuf.Option value) {
-    value.getClass();
-  ensureOptionsIsMutable();
-    options_.add(value);
-  }
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 4;</code>
-   */
-  private void addOptions(
-      int index, com.google.protobuf.Option value) {
-    value.getClass();
-  ensureOptionsIsMutable();
-    options_.add(index, value);
-  }
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 4;</code>
-   */
-  private void addAllOptions(
-      java.lang.Iterable<? extends com.google.protobuf.Option> values) {
-    ensureOptionsIsMutable();
-    com.google.protobuf.AbstractMessageLite.addAll(
-        values, options_);
-  }
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 4;</code>
-   */
-  private void clearOptions() {
-    options_ = emptyProtobufList();
-  }
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 4;</code>
-   */
-  private void removeOptions(int index) {
-    ensureOptionsIsMutable();
-    options_.remove(index);
-  }
-
-  public static final int SOURCE_CONTEXT_FIELD_NUMBER = 5;
-  private com.google.protobuf.SourceContext sourceContext_;
-  /**
-   * <pre>
-   * The source context.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 5;</code>
-   */
-  @java.lang.Override
-  public boolean hasSourceContext() {
-    return sourceContext_ != null;
-  }
-  /**
-   * <pre>
-   * The source context.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 5;</code>
-   */
-  @java.lang.Override
-  public com.google.protobuf.SourceContext getSourceContext() {
-    return sourceContext_ == null ? com.google.protobuf.SourceContext.getDefaultInstance() : sourceContext_;
-  }
-  /**
-   * <pre>
-   * The source context.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 5;</code>
-   */
-  private void setSourceContext(com.google.protobuf.SourceContext value) {
-    value.getClass();
-  sourceContext_ = value;
-    
-    }
-  /**
-   * <pre>
-   * The source context.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 5;</code>
-   */
-  @java.lang.SuppressWarnings({"ReferenceEquality"})
-  private void mergeSourceContext(com.google.protobuf.SourceContext value) {
-    value.getClass();
-  if (sourceContext_ != null &&
-        sourceContext_ != com.google.protobuf.SourceContext.getDefaultInstance()) {
-      sourceContext_ =
-        com.google.protobuf.SourceContext.newBuilder(sourceContext_).mergeFrom(value).buildPartial();
-    } else {
-      sourceContext_ = value;
-    }
-    
-  }
-  /**
-   * <pre>
-   * The source context.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 5;</code>
-   */
-  private void clearSourceContext() {  sourceContext_ = null;
-    
-  }
-
-  public static final int SYNTAX_FIELD_NUMBER = 6;
-  private int syntax_;
-  /**
-   * <pre>
-   * The source syntax.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 6;</code>
-   * @return The enum numeric value on the wire for syntax.
-   */
-  @java.lang.Override
-  public int getSyntaxValue() {
-    return syntax_;
-  }
-  /**
-   * <pre>
-   * The source syntax.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 6;</code>
-   * @return The syntax.
-   */
-  @java.lang.Override
-  public com.google.protobuf.Syntax getSyntax() {
-    com.google.protobuf.Syntax result = com.google.protobuf.Syntax.forNumber(syntax_);
-    return result == null ? com.google.protobuf.Syntax.UNRECOGNIZED : result;
-  }
-  /**
-   * <pre>
-   * The source syntax.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 6;</code>
-   * @param value The enum numeric value on the wire for syntax to set.
-   */
-  private void setSyntaxValue(int value) {
-      syntax_ = value;
-  }
-  /**
-   * <pre>
-   * The source syntax.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 6;</code>
-   * @param value The syntax to set.
-   */
-  private void setSyntax(com.google.protobuf.Syntax value) {
-    syntax_ = value.getNumber();
-    
-  }
-  /**
-   * <pre>
-   * The source syntax.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 6;</code>
-   */
-  private void clearSyntax() {
-    
-    syntax_ = 0;
-  }
-
-  public static com.google.protobuf.Type parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Type parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Type parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Type parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Type parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Type parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Type parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Type parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Type parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Type parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Type parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Type parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.Type prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * A protocol buffer message type.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.Type}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.Type, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.Type)
-      com.google.protobuf.TypeOrBuilder {
-    // Construct using com.google.protobuf.Type.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * The fully qualified message name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return The name.
-     */
-    @java.lang.Override
-    public java.lang.String getName() {
-      return instance.getName();
-    }
-    /**
-     * <pre>
-     * The fully qualified message name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return The bytes for name.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getNameBytes() {
-      return instance.getNameBytes();
-    }
-    /**
-     * <pre>
-     * The fully qualified message name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @param value The name to set.
-     * @return This builder for chaining.
-     */
-    public Builder setName(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.setName(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The fully qualified message name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearName() {
-      copyOnWrite();
-      instance.clearName();
-      return this;
-    }
-    /**
-     * <pre>
-     * The fully qualified message name.
-     * </pre>
-     *
-     * <code>string name = 1;</code>
-     * @param value The bytes for name to set.
-     * @return This builder for chaining.
-     */
-    public Builder setNameBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setNameBytes(value);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The list of fields.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Field fields = 2;</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.Field> getFieldsList() {
-      return java.util.Collections.unmodifiableList(
-          instance.getFieldsList());
-    }
-    /**
-     * <pre>
-     * The list of fields.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Field fields = 2;</code>
-     */
-    @java.lang.Override
-    public int getFieldsCount() {
-      return instance.getFieldsCount();
-    }/**
-     * <pre>
-     * The list of fields.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Field fields = 2;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.Field getFields(int index) {
-      return instance.getFields(index);
-    }
-    /**
-     * <pre>
-     * The list of fields.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Field fields = 2;</code>
-     */
-    public Builder setFields(
-        int index, com.google.protobuf.Field value) {
-      copyOnWrite();
-      instance.setFields(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The list of fields.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Field fields = 2;</code>
-     */
-    public Builder setFields(
-        int index, com.google.protobuf.Field.Builder builderForValue) {
-      copyOnWrite();
-      instance.setFields(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * The list of fields.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Field fields = 2;</code>
-     */
-    public Builder addFields(com.google.protobuf.Field value) {
-      copyOnWrite();
-      instance.addFields(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The list of fields.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Field fields = 2;</code>
-     */
-    public Builder addFields(
-        int index, com.google.protobuf.Field value) {
-      copyOnWrite();
-      instance.addFields(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The list of fields.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Field fields = 2;</code>
-     */
-    public Builder addFields(
-        com.google.protobuf.Field.Builder builderForValue) {
-      copyOnWrite();
-      instance.addFields(builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * The list of fields.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Field fields = 2;</code>
-     */
-    public Builder addFields(
-        int index, com.google.protobuf.Field.Builder builderForValue) {
-      copyOnWrite();
-      instance.addFields(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * The list of fields.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Field fields = 2;</code>
-     */
-    public Builder addAllFields(
-        java.lang.Iterable<? extends com.google.protobuf.Field> values) {
-      copyOnWrite();
-      instance.addAllFields(values);
-      return this;
-    }
-    /**
-     * <pre>
-     * The list of fields.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Field fields = 2;</code>
-     */
-    public Builder clearFields() {
-      copyOnWrite();
-      instance.clearFields();
-      return this;
-    }
-    /**
-     * <pre>
-     * The list of fields.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Field fields = 2;</code>
-     */
-    public Builder removeFields(int index) {
-      copyOnWrite();
-      instance.removeFields(index);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The list of types appearing in `oneof` definitions in this type.
-     * </pre>
-     *
-     * <code>repeated string oneofs = 3;</code>
-     * @return A list containing the oneofs.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String>
-        getOneofsList() {
-      return java.util.Collections.unmodifiableList(
-          instance.getOneofsList());
-    }
-    /**
-     * <pre>
-     * The list of types appearing in `oneof` definitions in this type.
-     * </pre>
-     *
-     * <code>repeated string oneofs = 3;</code>
-     * @return The count of oneofs.
-     */
-    @java.lang.Override
-    public int getOneofsCount() {
-      return instance.getOneofsCount();
-    }
-    /**
-     * <pre>
-     * The list of types appearing in `oneof` definitions in this type.
-     * </pre>
-     *
-     * <code>repeated string oneofs = 3;</code>
-     * @param index The index of the element to return.
-     * @return The oneofs at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getOneofs(int index) {
-      return instance.getOneofs(index);
-    }
-    /**
-     * <pre>
-     * The list of types appearing in `oneof` definitions in this type.
-     * </pre>
-     *
-     * <code>repeated string oneofs = 3;</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the oneofs at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOneofsBytes(int index) {
-      return instance.getOneofsBytes(index);
-    }
-    /**
-     * <pre>
-     * The list of types appearing in `oneof` definitions in this type.
-     * </pre>
-     *
-     * <code>repeated string oneofs = 3;</code>
-     * @param index The index to set the value at.
-     * @param value The oneofs to set.
-     * @return This builder for chaining.
-     */
-    public Builder setOneofs(
-        int index, java.lang.String value) {
-      copyOnWrite();
-      instance.setOneofs(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The list of types appearing in `oneof` definitions in this type.
-     * </pre>
-     *
-     * <code>repeated string oneofs = 3;</code>
-     * @param value The oneofs to add.
-     * @return This builder for chaining.
-     */
-    public Builder addOneofs(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.addOneofs(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The list of types appearing in `oneof` definitions in this type.
-     * </pre>
-     *
-     * <code>repeated string oneofs = 3;</code>
-     * @param values The oneofs to add.
-     * @return This builder for chaining.
-     */
-    public Builder addAllOneofs(
-        java.lang.Iterable<java.lang.String> values) {
-      copyOnWrite();
-      instance.addAllOneofs(values);
-      return this;
-    }
-    /**
-     * <pre>
-     * The list of types appearing in `oneof` definitions in this type.
-     * </pre>
-     *
-     * <code>repeated string oneofs = 3;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearOneofs() {
-      copyOnWrite();
-      instance.clearOneofs();
-      return this;
-    }
-    /**
-     * <pre>
-     * The list of types appearing in `oneof` definitions in this type.
-     * </pre>
-     *
-     * <code>repeated string oneofs = 3;</code>
-     * @param value The bytes of the oneofs to add.
-     * @return This builder for chaining.
-     */
-    public Builder addOneofsBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.addOneofsBytes(value);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 4;</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.Option> getOptionsList() {
-      return java.util.Collections.unmodifiableList(
-          instance.getOptionsList());
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 4;</code>
-     */
-    @java.lang.Override
-    public int getOptionsCount() {
-      return instance.getOptionsCount();
-    }/**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 4;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.Option getOptions(int index) {
-      return instance.getOptions(index);
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 4;</code>
-     */
-    public Builder setOptions(
-        int index, com.google.protobuf.Option value) {
-      copyOnWrite();
-      instance.setOptions(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 4;</code>
-     */
-    public Builder setOptions(
-        int index, com.google.protobuf.Option.Builder builderForValue) {
-      copyOnWrite();
-      instance.setOptions(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 4;</code>
-     */
-    public Builder addOptions(com.google.protobuf.Option value) {
-      copyOnWrite();
-      instance.addOptions(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 4;</code>
-     */
-    public Builder addOptions(
-        int index, com.google.protobuf.Option value) {
-      copyOnWrite();
-      instance.addOptions(index, value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 4;</code>
-     */
-    public Builder addOptions(
-        com.google.protobuf.Option.Builder builderForValue) {
-      copyOnWrite();
-      instance.addOptions(builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 4;</code>
-     */
-    public Builder addOptions(
-        int index, com.google.protobuf.Option.Builder builderForValue) {
-      copyOnWrite();
-      instance.addOptions(index,
-          builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 4;</code>
-     */
-    public Builder addAllOptions(
-        java.lang.Iterable<? extends com.google.protobuf.Option> values) {
-      copyOnWrite();
-      instance.addAllOptions(values);
-      return this;
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 4;</code>
-     */
-    public Builder clearOptions() {
-      copyOnWrite();
-      instance.clearOptions();
-      return this;
-    }
-    /**
-     * <pre>
-     * The protocol buffer options.
-     * </pre>
-     *
-     * <code>repeated .google.protobuf.Option options = 4;</code>
-     */
-    public Builder removeOptions(int index) {
-      copyOnWrite();
-      instance.removeOptions(index);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The source context.
-     * </pre>
-     *
-     * <code>.google.protobuf.SourceContext source_context = 5;</code>
-     */
-    @java.lang.Override
-    public boolean hasSourceContext() {
-      return instance.hasSourceContext();
-    }
-    /**
-     * <pre>
-     * The source context.
-     * </pre>
-     *
-     * <code>.google.protobuf.SourceContext source_context = 5;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.SourceContext getSourceContext() {
-      return instance.getSourceContext();
-    }
-    /**
-     * <pre>
-     * The source context.
-     * </pre>
-     *
-     * <code>.google.protobuf.SourceContext source_context = 5;</code>
-     */
-    public Builder setSourceContext(com.google.protobuf.SourceContext value) {
-      copyOnWrite();
-      instance.setSourceContext(value);
-      return this;
-      }
-    /**
-     * <pre>
-     * The source context.
-     * </pre>
-     *
-     * <code>.google.protobuf.SourceContext source_context = 5;</code>
-     */
-    public Builder setSourceContext(
-        com.google.protobuf.SourceContext.Builder builderForValue) {
-      copyOnWrite();
-      instance.setSourceContext(builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * The source context.
-     * </pre>
-     *
-     * <code>.google.protobuf.SourceContext source_context = 5;</code>
-     */
-    public Builder mergeSourceContext(com.google.protobuf.SourceContext value) {
-      copyOnWrite();
-      instance.mergeSourceContext(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The source context.
-     * </pre>
-     *
-     * <code>.google.protobuf.SourceContext source_context = 5;</code>
-     */
-    public Builder clearSourceContext() {  copyOnWrite();
-      instance.clearSourceContext();
-      return this;
-    }
-
-    /**
-     * <pre>
-     * The source syntax.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 6;</code>
-     * @return The enum numeric value on the wire for syntax.
-     */
-    @java.lang.Override
-    public int getSyntaxValue() {
-      return instance.getSyntaxValue();
-    }
-    /**
-     * <pre>
-     * The source syntax.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 6;</code>
-     * @param value The syntax to set.
-     * @return This builder for chaining.
-     */
-    public Builder setSyntaxValue(int value) {
-      copyOnWrite();
-      instance.setSyntaxValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The source syntax.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 6;</code>
-     * @return The syntax.
-     */
-    @java.lang.Override
-    public com.google.protobuf.Syntax getSyntax() {
-      return instance.getSyntax();
-    }
-    /**
-     * <pre>
-     * The source syntax.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 6;</code>
-     * @param value The enum numeric value on the wire for syntax to set.
-     * @return This builder for chaining.
-     */
-    public Builder setSyntax(com.google.protobuf.Syntax value) {
-      copyOnWrite();
-      instance.setSyntax(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The source syntax.
-     * </pre>
-     *
-     * <code>.google.protobuf.Syntax syntax = 6;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearSyntax() {
-      copyOnWrite();
-      instance.clearSyntax();
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.Type)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.Type();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "name_",
-            "fields_",
-            com.google.protobuf.Field.class,
-            "oneofs_",
-            "options_",
-            com.google.protobuf.Option.class,
-            "sourceContext_",
-            "syntax_",
-          };
-          java.lang.String info =
-              "\u0000\u0006\u0000\u0000\u0001\u0006\u0006\u0000\u0003\u0000\u0001\u0208\u0002\u001b" +
-              "\u0003\u021a\u0004\u001b\u0005\t\u0006\f";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.Type> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.Type.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.Type>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.Type)
-  private static final com.google.protobuf.Type DEFAULT_INSTANCE;
-  static {
-    Type defaultInstance = new Type();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      Type.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.Type getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<Type> PARSER;
-
-  public static com.google.protobuf.Parser<Type> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/TypeOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/TypeOrBuilder.java
deleted file mode 100644
index 140edf5..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/TypeOrBuilder.java
+++ /dev/null
@@ -1,160 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/type.proto
-
-package com.google.protobuf;
-
-public interface TypeOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.Type)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * The fully qualified message name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The name.
-   */
-  java.lang.String getName();
-  /**
-   * <pre>
-   * The fully qualified message name.
-   * </pre>
-   *
-   * <code>string name = 1;</code>
-   * @return The bytes for name.
-   */
-  com.google.protobuf.ByteString
-      getNameBytes();
-
-  /**
-   * <pre>
-   * The list of fields.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Field fields = 2;</code>
-   */
-  java.util.List<com.google.protobuf.Field> 
-      getFieldsList();
-  /**
-   * <pre>
-   * The list of fields.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Field fields = 2;</code>
-   */
-  com.google.protobuf.Field getFields(int index);
-  /**
-   * <pre>
-   * The list of fields.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Field fields = 2;</code>
-   */
-  int getFieldsCount();
-
-  /**
-   * <pre>
-   * The list of types appearing in `oneof` definitions in this type.
-   * </pre>
-   *
-   * <code>repeated string oneofs = 3;</code>
-   * @return A list containing the oneofs.
-   */
-  java.util.List<java.lang.String>
-      getOneofsList();
-  /**
-   * <pre>
-   * The list of types appearing in `oneof` definitions in this type.
-   * </pre>
-   *
-   * <code>repeated string oneofs = 3;</code>
-   * @return The count of oneofs.
-   */
-  int getOneofsCount();
-  /**
-   * <pre>
-   * The list of types appearing in `oneof` definitions in this type.
-   * </pre>
-   *
-   * <code>repeated string oneofs = 3;</code>
-   * @param index The index of the element to return.
-   * @return The oneofs at the given index.
-   */
-  java.lang.String getOneofs(int index);
-  /**
-   * <pre>
-   * The list of types appearing in `oneof` definitions in this type.
-   * </pre>
-   *
-   * <code>repeated string oneofs = 3;</code>
-   * @param index The index of the element to return.
-   * @return The oneofs at the given index.
-   */
-  com.google.protobuf.ByteString
-      getOneofsBytes(int index);
-
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 4;</code>
-   */
-  java.util.List<com.google.protobuf.Option> 
-      getOptionsList();
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 4;</code>
-   */
-  com.google.protobuf.Option getOptions(int index);
-  /**
-   * <pre>
-   * The protocol buffer options.
-   * </pre>
-   *
-   * <code>repeated .google.protobuf.Option options = 4;</code>
-   */
-  int getOptionsCount();
-
-  /**
-   * <pre>
-   * The source context.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 5;</code>
-   * @return Whether the sourceContext field is set.
-   */
-  boolean hasSourceContext();
-  /**
-   * <pre>
-   * The source context.
-   * </pre>
-   *
-   * <code>.google.protobuf.SourceContext source_context = 5;</code>
-   * @return The sourceContext.
-   */
-  com.google.protobuf.SourceContext getSourceContext();
-
-  /**
-   * <pre>
-   * The source syntax.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 6;</code>
-   * @return The enum numeric value on the wire for syntax.
-   */
-  int getSyntaxValue();
-  /**
-   * <pre>
-   * The source syntax.
-   * </pre>
-   *
-   * <code>.google.protobuf.Syntax syntax = 6;</code>
-   * @return The syntax.
-   */
-  com.google.protobuf.Syntax getSyntax();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/TypeProto.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/TypeProto.java
deleted file mode 100644
index 7a47de1..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/TypeProto.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/type.proto
-
-package com.google.protobuf;
-
-public final class TypeProto {
-  private TypeProto() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UInt32Value.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/UInt32Value.java
deleted file mode 100644
index 6bcbe75..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UInt32Value.java
+++ /dev/null
@@ -1,276 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/wrappers.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * Wrapper message for `uint32`.
- * The JSON representation for `UInt32Value` is JSON number.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.UInt32Value}
- */
-public  final class UInt32Value extends
-    com.google.protobuf.GeneratedMessageLite<
-        UInt32Value, UInt32Value.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.UInt32Value)
-    UInt32ValueOrBuilder {
-  private UInt32Value() {
-  }
-  public static final int VALUE_FIELD_NUMBER = 1;
-  private int value_;
-  /**
-   * <pre>
-   * The uint32 value.
-   * </pre>
-   *
-   * <code>uint32 value = 1;</code>
-   * @return The value.
-   */
-  @java.lang.Override
-  public int getValue() {
-    return value_;
-  }
-  /**
-   * <pre>
-   * The uint32 value.
-   * </pre>
-   *
-   * <code>uint32 value = 1;</code>
-   * @param value The value to set.
-   */
-  private void setValue(int value) {
-    
-    value_ = value;
-  }
-  /**
-   * <pre>
-   * The uint32 value.
-   * </pre>
-   *
-   * <code>uint32 value = 1;</code>
-   */
-  private void clearValue() {
-    
-    value_ = 0;
-  }
-
-  public static com.google.protobuf.UInt32Value parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.UInt32Value parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.UInt32Value parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.UInt32Value parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.UInt32Value parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.UInt32Value parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.UInt32Value parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.UInt32Value parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.UInt32Value parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.UInt32Value parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.UInt32Value parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.UInt32Value parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.UInt32Value prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * Wrapper message for `uint32`.
-   * The JSON representation for `UInt32Value` is JSON number.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.UInt32Value}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.UInt32Value, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.UInt32Value)
-      com.google.protobuf.UInt32ValueOrBuilder {
-    // Construct using com.google.protobuf.UInt32Value.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * The uint32 value.
-     * </pre>
-     *
-     * <code>uint32 value = 1;</code>
-     * @return The value.
-     */
-    @java.lang.Override
-    public int getValue() {
-      return instance.getValue();
-    }
-    /**
-     * <pre>
-     * The uint32 value.
-     * </pre>
-     *
-     * <code>uint32 value = 1;</code>
-     * @param value The value to set.
-     * @return This builder for chaining.
-     */
-    public Builder setValue(int value) {
-      copyOnWrite();
-      instance.setValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The uint32 value.
-     * </pre>
-     *
-     * <code>uint32 value = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearValue() {
-      copyOnWrite();
-      instance.clearValue();
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.UInt32Value)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.UInt32Value();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "value_",
-          };
-          java.lang.String info =
-              "\u0000\u0001\u0000\u0000\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u000b";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.UInt32Value> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.UInt32Value.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.UInt32Value>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.UInt32Value)
-  private static final com.google.protobuf.UInt32Value DEFAULT_INSTANCE;
-  static {
-    UInt32Value defaultInstance = new UInt32Value();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      UInt32Value.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.UInt32Value getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  public static com.google.protobuf.UInt32Value of(int value) {
-    return newBuilder().setValue(value).build();
-  }
-
-  private static volatile com.google.protobuf.Parser<UInt32Value> PARSER;
-
-  public static com.google.protobuf.Parser<UInt32Value> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UInt32ValueOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/UInt32ValueOrBuilder.java
deleted file mode 100644
index 529ed95..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UInt32ValueOrBuilder.java
+++ /dev/null
@@ -1,19 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/wrappers.proto
-
-package com.google.protobuf;
-
-public interface UInt32ValueOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.UInt32Value)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * The uint32 value.
-   * </pre>
-   *
-   * <code>uint32 value = 1;</code>
-   * @return The value.
-   */
-  int getValue();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UInt64Value.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/UInt64Value.java
deleted file mode 100644
index 17613f8..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UInt64Value.java
+++ /dev/null
@@ -1,276 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/wrappers.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * Wrapper message for `uint64`.
- * The JSON representation for `UInt64Value` is JSON string.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.UInt64Value}
- */
-public  final class UInt64Value extends
-    com.google.protobuf.GeneratedMessageLite<
-        UInt64Value, UInt64Value.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.UInt64Value)
-    UInt64ValueOrBuilder {
-  private UInt64Value() {
-  }
-  public static final int VALUE_FIELD_NUMBER = 1;
-  private long value_;
-  /**
-   * <pre>
-   * The uint64 value.
-   * </pre>
-   *
-   * <code>uint64 value = 1;</code>
-   * @return The value.
-   */
-  @java.lang.Override
-  public long getValue() {
-    return value_;
-  }
-  /**
-   * <pre>
-   * The uint64 value.
-   * </pre>
-   *
-   * <code>uint64 value = 1;</code>
-   * @param value The value to set.
-   */
-  private void setValue(long value) {
-    
-    value_ = value;
-  }
-  /**
-   * <pre>
-   * The uint64 value.
-   * </pre>
-   *
-   * <code>uint64 value = 1;</code>
-   */
-  private void clearValue() {
-    
-    value_ = 0L;
-  }
-
-  public static com.google.protobuf.UInt64Value parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.UInt64Value parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.UInt64Value parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.UInt64Value parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.UInt64Value parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.UInt64Value parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.UInt64Value parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.UInt64Value parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.UInt64Value parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.UInt64Value parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.UInt64Value parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.UInt64Value parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.UInt64Value prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * Wrapper message for `uint64`.
-   * The JSON representation for `UInt64Value` is JSON string.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.UInt64Value}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.UInt64Value, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.UInt64Value)
-      com.google.protobuf.UInt64ValueOrBuilder {
-    // Construct using com.google.protobuf.UInt64Value.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    /**
-     * <pre>
-     * The uint64 value.
-     * </pre>
-     *
-     * <code>uint64 value = 1;</code>
-     * @return The value.
-     */
-    @java.lang.Override
-    public long getValue() {
-      return instance.getValue();
-    }
-    /**
-     * <pre>
-     * The uint64 value.
-     * </pre>
-     *
-     * <code>uint64 value = 1;</code>
-     * @param value The value to set.
-     * @return This builder for chaining.
-     */
-    public Builder setValue(long value) {
-      copyOnWrite();
-      instance.setValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * The uint64 value.
-     * </pre>
-     *
-     * <code>uint64 value = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearValue() {
-      copyOnWrite();
-      instance.clearValue();
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.UInt64Value)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.UInt64Value();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "value_",
-          };
-          java.lang.String info =
-              "\u0000\u0001\u0000\u0000\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u0003";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.UInt64Value> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.UInt64Value.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.UInt64Value>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.UInt64Value)
-  private static final com.google.protobuf.UInt64Value DEFAULT_INSTANCE;
-  static {
-    UInt64Value defaultInstance = new UInt64Value();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      UInt64Value.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.UInt64Value getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  public static com.google.protobuf.UInt64Value of(long value) {
-    return newBuilder().setValue(value).build();
-  }
-
-  private static volatile com.google.protobuf.Parser<UInt64Value> PARSER;
-
-  public static com.google.protobuf.Parser<UInt64Value> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UInt64ValueOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/UInt64ValueOrBuilder.java
deleted file mode 100644
index 3baa6fe..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UInt64ValueOrBuilder.java
+++ /dev/null
@@ -1,19 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/wrappers.proto
-
-package com.google.protobuf;
-
-public interface UInt64ValueOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.UInt64Value)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * The uint64 value.
-   * </pre>
-   *
-   * <code>uint64 value = 1;</code>
-   * @return The value.
-   */
-  long getValue();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UninitializedMessageException.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/UninitializedMessageException.java
deleted file mode 100644
index c633a4e..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UninitializedMessageException.java
+++ /dev/null
@@ -1,96 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Thrown when attempting to build a protocol message that is missing required fields. This is a
- * {@code RuntimeException} because it normally represents a programming error: it happens when some
- * code which constructs a message fails to set all the fields. {@code parseFrom()} methods <b>do
- * not</b> throw this; they throw an {@link InvalidProtocolBufferException} if required fields are
- * missing, because it is not a programming error to receive an incomplete message. In other words,
- * {@code UninitializedMessageException} should never be thrown by correct code, but {@code
- * InvalidProtocolBufferException} might be.
- *
- * @author kenton@google.com Kenton Varda
- */
-public class UninitializedMessageException extends RuntimeException {
-  private static final long serialVersionUID = -7466929953374883507L;
-
-  public UninitializedMessageException(final MessageLite message) {
-    super(
-        "Message was missing required fields.  (Lite runtime could not "
-            + "determine which fields were missing).");
-    missingFields = null;
-  }
-
-  public UninitializedMessageException(final List<String> missingFields) {
-    super(buildDescription(missingFields));
-    this.missingFields = missingFields;
-  }
-
-  private final List<String> missingFields;
-
-  /**
-   * Get a list of human-readable names of required fields missing from this message. Each name is a
-   * full path to a field, e.g. "foo.bar[5].baz". Returns null if the lite runtime was used, since
-   * it lacks the ability to find missing fields.
-   */
-  public List<String> getMissingFields() {
-    return Collections.unmodifiableList(missingFields);
-  }
-
-  /**
-   * Converts this exception to an {@link InvalidProtocolBufferException}. When a parsed message is
-   * missing required fields, this should be thrown instead of {@code
-   * UninitializedMessageException}.
-   */
-  public InvalidProtocolBufferException asInvalidProtocolBufferException() {
-    return new InvalidProtocolBufferException(getMessage());
-  }
-
-  /** Construct the description string for this exception. */
-  private static String buildDescription(final List<String> missingFields) {
-    final StringBuilder description = new StringBuilder("Message missing required fields: ");
-    boolean first = true;
-    for (final String field : missingFields) {
-      if (first) {
-        first = false;
-      } else {
-        description.append(", ");
-      }
-      description.append(field);
-    }
-    return description.toString();
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UnknownFieldSchema.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/UnknownFieldSchema.java
deleted file mode 100644
index e736d5c..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UnknownFieldSchema.java
+++ /dev/null
@@ -1,133 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.io.IOException;
-
-@ExperimentalApi
-abstract class UnknownFieldSchema<T, B> {
-
-  /** Whether unknown fields should be dropped. */
-  abstract boolean shouldDiscardUnknownFields(Reader reader);
-
-  /** Adds a varint value to the unknown fields. */
-  abstract void addVarint(B fields, int number, long value);
-
-  /** Adds a fixed32 value to the unknown fields. */
-  abstract void addFixed32(B fields, int number, int value);
-
-  /** Adds a fixed64 value to the unknown fields. */
-  abstract void addFixed64(B fields, int number, long value);
-
-  /** Adds a length delimited value to the unknown fields. */
-  abstract void addLengthDelimited(B fields, int number, ByteString value);
-
-  /** Adds a group value to the unknown fields. */
-  abstract void addGroup(B fields, int number, T subFieldSet);
-
-  /** Create a new builder for unknown fields. */
-  abstract B newBuilder();
-
-  /** Returns an immutable instance of the field container. */
-  abstract T toImmutable(B fields);
-
-  /**
-   * Sets the unknown fields into the message. Caller must take care of the mutability of the
-   * fields.
-   */
-  abstract void setToMessage(Object message, T fields);
-
-  /** Get the unknown fields from the message. */
-  abstract T getFromMessage(Object message);
-
-  /** Returns a builder for unknown fields in the message. */
-  abstract B getBuilderFromMessage(Object message);
-
-  /** Sets an unknown field builder into the message. */
-  abstract void setBuilderToMessage(Object message, B builder);
-
-  /** Marks unknown fields as immutable. */
-  abstract void makeImmutable(Object message);
-
-  /** Merges one field into the unknown fields. */
-  final boolean mergeOneFieldFrom(B unknownFields, Reader reader) throws IOException {
-    int tag = reader.getTag();
-    int fieldNumber = WireFormat.getTagFieldNumber(tag);
-    switch (WireFormat.getTagWireType(tag)) {
-      case WireFormat.WIRETYPE_VARINT:
-        addVarint(unknownFields, fieldNumber, reader.readInt64());
-        return true;
-      case WireFormat.WIRETYPE_FIXED32:
-        addFixed32(unknownFields, fieldNumber, reader.readFixed32());
-        return true;
-      case WireFormat.WIRETYPE_FIXED64:
-        addFixed64(unknownFields, fieldNumber, reader.readFixed64());
-        return true;
-      case WireFormat.WIRETYPE_LENGTH_DELIMITED:
-        addLengthDelimited(unknownFields, fieldNumber, reader.readBytes());
-        return true;
-      case WireFormat.WIRETYPE_START_GROUP:
-        final B subFields = newBuilder();
-        int endGroupTag = WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
-        mergeFrom(subFields, reader);
-        if (endGroupTag != reader.getTag()) {
-          throw InvalidProtocolBufferException.invalidEndTag();
-        }
-        addGroup(unknownFields, fieldNumber, toImmutable(subFields));
-        return true;
-      case WireFormat.WIRETYPE_END_GROUP:
-        return false;
-      default:
-        throw InvalidProtocolBufferException.invalidWireType();
-    }
-  }
-
-  final void mergeFrom(B unknownFields, Reader reader) throws IOException {
-    while (true) {
-      if (reader.getFieldNumber() == Reader.READ_DONE
-          || !mergeOneFieldFrom(unknownFields, reader)) {
-        break;
-      }
-    }
-  }
-
-  abstract void writeTo(T unknownFields, Writer writer) throws IOException;
-
-  abstract void writeAsMessageSetTo(T unknownFields, Writer writer) throws IOException;
-
-  /** Merges {@code source} into {@code destination} and returns the merged instance. */
-  abstract T merge(T destination, T source);
-
-  /** Get the serialized size for message set serialization. */
-  abstract int getSerializedSizeAsMessageSet(T message);
-
-  abstract int getSerializedSize(T unknowns);
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UnknownFieldSetLite.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/UnknownFieldSetLite.java
deleted file mode 100644
index b2cb7be..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UnknownFieldSetLite.java
+++ /dev/null
@@ -1,490 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-/**
- * {@code UnknownFieldSetLite} is used to keep track of fields which were seen when parsing a
- * protocol message but whose field numbers or types are unrecognized. This most frequently occurs
- * when new fields are added to a message type and then messages containing those fields are read by
- * old software that was compiled before the new types were added.
- *
- * <p>For use by generated code only.
- *
- * @author dweis@google.com (Daniel Weis)
- */
-public final class UnknownFieldSetLite {
-
-  // Arbitrarily chosen.
-  // TODO(dweis): Tune this number?
-  private static final int MIN_CAPACITY = 8;
-
-  private static final UnknownFieldSetLite DEFAULT_INSTANCE =
-      new UnknownFieldSetLite(0, new int[0], new Object[0], /* isMutable= */ false);
-
-  /**
-   * Get an empty {@code UnknownFieldSetLite}.
-   *
-   * <p>For use by generated code only.
-   */
-  public static UnknownFieldSetLite getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  /** Returns a new mutable instance. */
-  static UnknownFieldSetLite newInstance() {
-    return new UnknownFieldSetLite();
-  }
-
-  /**
-   * Returns a mutable {@code UnknownFieldSetLite} that is the composite of {@code first} and {@code
-   * second}.
-   */
-  static UnknownFieldSetLite mutableCopyOf(UnknownFieldSetLite first, UnknownFieldSetLite second) {
-    int count = first.count + second.count;
-    int[] tags = Arrays.copyOf(first.tags, count);
-    System.arraycopy(second.tags, 0, tags, first.count, second.count);
-    Object[] objects = Arrays.copyOf(first.objects, count);
-    System.arraycopy(second.objects, 0, objects, first.count, second.count);
-    return new UnknownFieldSetLite(count, tags, objects, /* isMutable= */ true);
-  }
-
-  /** The number of elements in the set. */
-  private int count;
-
-  /** The tag numbers for the elements in the set. */
-  private int[] tags;
-
-  /** The boxed values of the elements in the set. */
-  private Object[] objects;
-
-  /** The lazily computed serialized size of the set. */
-  private int memoizedSerializedSize = -1;
-
-  /** Indicates that this object is mutable. */
-  private boolean isMutable;
-
-  /** Constructs a mutable {@code UnknownFieldSetLite}. */
-  private UnknownFieldSetLite() {
-    this(0, new int[MIN_CAPACITY], new Object[MIN_CAPACITY], /* isMutable= */ true);
-  }
-
-  /** Constructs the {@code UnknownFieldSetLite}. */
-  private UnknownFieldSetLite(int count, int[] tags, Object[] objects, boolean isMutable) {
-    this.count = count;
-    this.tags = tags;
-    this.objects = objects;
-    this.isMutable = isMutable;
-  }
-
-  /**
-   * Marks this object as immutable.
-   *
-   * <p>Future calls to methods that attempt to modify this object will throw.
-   */
-  public void makeImmutable() {
-    this.isMutable = false;
-  }
-
-  /** Throws an {@link UnsupportedOperationException} if immutable. */
-  void checkMutable() {
-    if (!isMutable) {
-      throw new UnsupportedOperationException();
-    }
-  }
-
-  /**
-   * Serializes the set and writes it to {@code output}.
-   *
-   * <p>For use by generated code only.
-   */
-  public void writeTo(CodedOutputStream output) throws IOException {
-    for (int i = 0; i < count; i++) {
-      int tag = tags[i];
-      int fieldNumber = WireFormat.getTagFieldNumber(tag);
-      switch (WireFormat.getTagWireType(tag)) {
-        case WireFormat.WIRETYPE_VARINT:
-          output.writeUInt64(fieldNumber, (Long) objects[i]);
-          break;
-        case WireFormat.WIRETYPE_FIXED32:
-          output.writeFixed32(fieldNumber, (Integer) objects[i]);
-          break;
-        case WireFormat.WIRETYPE_FIXED64:
-          output.writeFixed64(fieldNumber, (Long) objects[i]);
-          break;
-        case WireFormat.WIRETYPE_LENGTH_DELIMITED:
-          output.writeBytes(fieldNumber, (ByteString) objects[i]);
-          break;
-        case WireFormat.WIRETYPE_START_GROUP:
-          output.writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP);
-          ((UnknownFieldSetLite) objects[i]).writeTo(output);
-          output.writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
-          break;
-        default:
-          throw InvalidProtocolBufferException.invalidWireType();
-      }
-    }
-  }
-
-  /**
-   * Serializes the set and writes it to {@code output} using {@code MessageSet} wire format.
-   *
-   * <p>For use by generated code only.
-   */
-  public void writeAsMessageSetTo(CodedOutputStream output) throws IOException {
-    for (int i = 0; i < count; i++) {
-      int fieldNumber = WireFormat.getTagFieldNumber(tags[i]);
-      output.writeRawMessageSetExtension(fieldNumber, (ByteString) objects[i]);
-    }
-  }
-
-  /** Serializes the set and writes it to {@code writer} using {@code MessageSet} wire format. */
-  void writeAsMessageSetTo(Writer writer) throws IOException {
-    if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) {
-      // Write fields in descending order.
-      for (int i = count - 1; i >= 0; i--) {
-        int fieldNumber = WireFormat.getTagFieldNumber(tags[i]);
-        writer.writeMessageSetItem(fieldNumber, objects[i]);
-      }
-    } else {
-      // Write fields in ascending order.
-      for (int i = 0; i < count; i++) {
-        int fieldNumber = WireFormat.getTagFieldNumber(tags[i]);
-        writer.writeMessageSetItem(fieldNumber, objects[i]);
-      }
-    }
-  }
-
-  /** Serializes the set and writes it to {@code writer}. */
-  public void writeTo(Writer writer) throws IOException {
-    if (count == 0) {
-      return;
-    }
-
-    // TODO: tags are not sorted, so there's no write order guarantees
-    if (writer.fieldOrder() == Writer.FieldOrder.ASCENDING) {
-      for (int i = 0; i < count; ++i) {
-        writeField(tags[i], objects[i], writer);
-      }
-    } else {
-      for (int i = count - 1; i >= 0; --i) {
-        writeField(tags[i], objects[i], writer);
-      }
-    }
-  }
-
-  private static void writeField(int tag, Object object, Writer writer) throws IOException {
-    int fieldNumber = WireFormat.getTagFieldNumber(tag);
-    switch (WireFormat.getTagWireType(tag)) {
-      case WireFormat.WIRETYPE_VARINT:
-        writer.writeInt64(fieldNumber, (Long) object);
-        break;
-      case WireFormat.WIRETYPE_FIXED32:
-        writer.writeFixed32(fieldNumber, (Integer) object);
-        break;
-      case WireFormat.WIRETYPE_FIXED64:
-        writer.writeFixed64(fieldNumber, (Long) object);
-        break;
-      case WireFormat.WIRETYPE_LENGTH_DELIMITED:
-        writer.writeBytes(fieldNumber, (ByteString) object);
-        break;
-      case WireFormat.WIRETYPE_START_GROUP:
-        if (writer.fieldOrder() == Writer.FieldOrder.ASCENDING) {
-          writer.writeStartGroup(fieldNumber);
-          ((UnknownFieldSetLite) object).writeTo(writer);
-          writer.writeEndGroup(fieldNumber);
-        } else {
-          writer.writeEndGroup(fieldNumber);
-          ((UnknownFieldSetLite) object).writeTo(writer);
-          writer.writeStartGroup(fieldNumber);
-        }
-        break;
-      default:
-        // TODO(liujisi): Change writeTo to throw IOException?
-        throw new RuntimeException(InvalidProtocolBufferException.invalidWireType());
-    }
-  }
-
-  /**
-   * Get the number of bytes required to encode this field, including field number, using {@code
-   * MessageSet} wire format.
-   */
-  public int getSerializedSizeAsMessageSet() {
-    int size = memoizedSerializedSize;
-    if (size != -1) {
-      return size;
-    }
-
-    size = 0;
-    for (int i = 0; i < count; i++) {
-      int tag = tags[i];
-      int fieldNumber = WireFormat.getTagFieldNumber(tag);
-      size +=
-          CodedOutputStream.computeRawMessageSetExtensionSize(fieldNumber, (ByteString) objects[i]);
-    }
-
-    memoizedSerializedSize = size;
-
-    return size;
-  }
-
-  /**
-   * Get the number of bytes required to encode this set.
-   *
-   * <p>For use by generated code only.
-   */
-  public int getSerializedSize() {
-    int size = memoizedSerializedSize;
-    if (size != -1) {
-      return size;
-    }
-
-    size = 0;
-    for (int i = 0; i < count; i++) {
-      int tag = tags[i];
-      int fieldNumber = WireFormat.getTagFieldNumber(tag);
-      switch (WireFormat.getTagWireType(tag)) {
-        case WireFormat.WIRETYPE_VARINT:
-          size += CodedOutputStream.computeUInt64Size(fieldNumber, (Long) objects[i]);
-          break;
-        case WireFormat.WIRETYPE_FIXED32:
-          size += CodedOutputStream.computeFixed32Size(fieldNumber, (Integer) objects[i]);
-          break;
-        case WireFormat.WIRETYPE_FIXED64:
-          size += CodedOutputStream.computeFixed64Size(fieldNumber, (Long) objects[i]);
-          break;
-        case WireFormat.WIRETYPE_LENGTH_DELIMITED:
-          size += CodedOutputStream.computeBytesSize(fieldNumber, (ByteString) objects[i]);
-          break;
-        case WireFormat.WIRETYPE_START_GROUP:
-          size +=
-              CodedOutputStream.computeTagSize(fieldNumber) * 2
-                  + ((UnknownFieldSetLite) objects[i]).getSerializedSize();
-          break;
-        default:
-          throw new IllegalStateException(InvalidProtocolBufferException.invalidWireType());
-      }
-    }
-
-    memoizedSerializedSize = size;
-
-    return size;
-  }
-
-  private static boolean tagsEquals(int[] tags1, int[] tags2, int count) {
-    for (int i = 0; i < count; ++i) {
-      if (tags1[i] != tags2[i]) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  private static boolean objectsEquals(Object[] objects1, Object[] objects2, int count) {
-    for (int i = 0; i < count; ++i) {
-      if (!objects1[i].equals(objects2[i])) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    if (this == obj) {
-      return true;
-    }
-
-    if (obj == null) {
-      return false;
-    }
-
-    if (!(obj instanceof UnknownFieldSetLite)) {
-      return false;
-    }
-
-    UnknownFieldSetLite other = (UnknownFieldSetLite) obj;
-    if (count != other.count
-        || !tagsEquals(tags, other.tags, count)
-        || !objectsEquals(objects, other.objects, count)) {
-      return false;
-    }
-
-    return true;
-  }
-
-  private static int hashCode(int[] tags, int count) {
-    int hashCode = 17;
-    for (int i = 0; i < count; ++i) {
-      hashCode = 31 * hashCode + tags[i];
-    }
-    return hashCode;
-  }
-
-  private static int hashCode(Object[] objects, int count) {
-    int hashCode = 17;
-    for (int i = 0; i < count; ++i) {
-      hashCode = 31 * hashCode + objects[i].hashCode();
-    }
-    return hashCode;
-  }
-
-  @Override
-  public int hashCode() {
-    int hashCode = 17;
-
-    hashCode = 31 * hashCode + count;
-    hashCode = 31 * hashCode + hashCode(tags, count);
-    hashCode = 31 * hashCode + hashCode(objects, count);
-
-    return hashCode;
-  }
-
-  /**
-   * Prints a String representation of the unknown field set.
-   *
-   * <p>For use by generated code only.
-   *
-   * @param buffer the buffer to write to
-   * @param indent the number of spaces the fields should be indented by
-   */
-  final void printWithIndent(StringBuilder buffer, int indent) {
-    for (int i = 0; i < count; i++) {
-      int fieldNumber = WireFormat.getTagFieldNumber(tags[i]);
-      MessageLiteToString.printField(buffer, indent, String.valueOf(fieldNumber), objects[i]);
-    }
-  }
-
-  // Package private for unsafe experimental runtime.
-  void storeField(int tag, Object value) {
-    checkMutable();
-    ensureCapacity();
-
-    tags[count] = tag;
-    objects[count] = value;
-    count++;
-  }
-
-  /** Ensures that our arrays are long enough to store more metadata. */
-  private void ensureCapacity() {
-    if (count == tags.length) {
-      int increment = count < (MIN_CAPACITY / 2) ? MIN_CAPACITY : count >> 1;
-      int newLength = count + increment;
-
-      tags = Arrays.copyOf(tags, newLength);
-      objects = Arrays.copyOf(objects, newLength);
-    }
-  }
-
-  /**
-   * Parse a single field from {@code input} and merge it into this set.
-   *
-   * <p>For use by generated code only.
-   *
-   * @param tag The field's tag number, which was already parsed.
-   * @return {@code false} if the tag is an end group tag.
-   */
-  boolean mergeFieldFrom(final int tag, final CodedInputStream input) throws IOException {
-    checkMutable();
-    final int fieldNumber = WireFormat.getTagFieldNumber(tag);
-    switch (WireFormat.getTagWireType(tag)) {
-      case WireFormat.WIRETYPE_VARINT:
-        storeField(tag, input.readInt64());
-        return true;
-      case WireFormat.WIRETYPE_FIXED32:
-        storeField(tag, input.readFixed32());
-        return true;
-      case WireFormat.WIRETYPE_FIXED64:
-        storeField(tag, input.readFixed64());
-        return true;
-      case WireFormat.WIRETYPE_LENGTH_DELIMITED:
-        storeField(tag, input.readBytes());
-        return true;
-      case WireFormat.WIRETYPE_START_GROUP:
-        final UnknownFieldSetLite subFieldSet = new UnknownFieldSetLite();
-        subFieldSet.mergeFrom(input);
-        input.checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
-        storeField(tag, subFieldSet);
-        return true;
-      case WireFormat.WIRETYPE_END_GROUP:
-        return false;
-      default:
-        throw InvalidProtocolBufferException.invalidWireType();
-    }
-  }
-
-  /**
-   * Convenience method for merging a new field containing a single varint value. This is used in
-   * particular when an unknown enum value is encountered.
-   *
-   * <p>For use by generated code only.
-   */
-  UnknownFieldSetLite mergeVarintField(int fieldNumber, int value) {
-    checkMutable();
-    if (fieldNumber == 0) {
-      throw new IllegalArgumentException("Zero is not a valid field number.");
-    }
-
-    storeField(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_VARINT), (long) value);
-
-    return this;
-  }
-
-  /**
-   * Convenience method for merging a length-delimited field.
-   *
-   * <p>For use by generated code only.
-   */
-  UnknownFieldSetLite mergeLengthDelimitedField(final int fieldNumber, final ByteString value) {
-    checkMutable();
-    if (fieldNumber == 0) {
-      throw new IllegalArgumentException("Zero is not a valid field number.");
-    }
-
-    storeField(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED), value);
-
-    return this;
-  }
-
-  /** Parse an entire message from {@code input} and merge its fields into this set. */
-  private UnknownFieldSetLite mergeFrom(final CodedInputStream input) throws IOException {
-    // Ensures initialization in mergeFieldFrom.
-    while (true) {
-      final int tag = input.readTag();
-      if (tag == 0 || !mergeFieldFrom(tag, input)) {
-        break;
-      }
-    }
-    return this;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UnknownFieldSetLiteSchema.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/UnknownFieldSetLiteSchema.java
deleted file mode 100644
index ffd7232..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UnknownFieldSetLiteSchema.java
+++ /dev/null
@@ -1,140 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.io.IOException;
-
-class UnknownFieldSetLiteSchema
-    extends UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite> {
-
-  UnknownFieldSetLiteSchema() {}
-
-  @Override
-  boolean shouldDiscardUnknownFields(Reader reader) {
-    // We never drop unknown fields in lite.
-    return false;
-  }
-
-  @Override
-  UnknownFieldSetLite newBuilder() {
-    return UnknownFieldSetLite.newInstance();
-  }
-
-  @Override
-  void addVarint(UnknownFieldSetLite fields, int number, long value) {
-    fields.storeField(WireFormat.makeTag(number, WireFormat.WIRETYPE_VARINT), value);
-  }
-
-  @Override
-  void addFixed32(UnknownFieldSetLite fields, int number, int value) {
-    fields.storeField(WireFormat.makeTag(number, WireFormat.WIRETYPE_FIXED32), value);
-  }
-
-  @Override
-  void addFixed64(UnknownFieldSetLite fields, int number, long value) {
-    fields.storeField(WireFormat.makeTag(number, WireFormat.WIRETYPE_FIXED64), value);
-  }
-
-  @Override
-  void addLengthDelimited(UnknownFieldSetLite fields, int number, ByteString value) {
-    fields.storeField(WireFormat.makeTag(number, WireFormat.WIRETYPE_LENGTH_DELIMITED), value);
-  }
-
-  @Override
-  void addGroup(UnknownFieldSetLite fields, int number, UnknownFieldSetLite subFieldSet) {
-    fields.storeField(WireFormat.makeTag(number, WireFormat.WIRETYPE_START_GROUP), subFieldSet);
-  }
-
-  @Override
-  UnknownFieldSetLite toImmutable(UnknownFieldSetLite fields) {
-    fields.makeImmutable();
-    return fields;
-  }
-
-  @Override
-  void setToMessage(Object message, UnknownFieldSetLite fields) {
-    ((GeneratedMessageLite<?, ?>) message).unknownFields = fields;
-  }
-
-  @Override
-  UnknownFieldSetLite getFromMessage(Object message) {
-    return ((GeneratedMessageLite<?, ?>) message).unknownFields;
-  }
-
-  @Override
-  UnknownFieldSetLite getBuilderFromMessage(Object message) {
-    UnknownFieldSetLite unknownFields = getFromMessage(message);
-    // When parsing into a lite message object, its UnknownFieldSet is either the default instance
-    // or mutable. It can't be in a state where it's immutable but not default instance.
-    if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
-      unknownFields = UnknownFieldSetLite.newInstance();
-      setToMessage(message, unknownFields);
-    }
-    return unknownFields;
-  }
-
-  @Override
-  void setBuilderToMessage(Object message, UnknownFieldSetLite fields) {
-    setToMessage(message, fields);
-  }
-
-  @Override
-  void makeImmutable(Object message) {
-    getFromMessage(message).makeImmutable();
-  }
-
-  @Override
-  void writeTo(UnknownFieldSetLite fields, Writer writer) throws IOException {
-    fields.writeTo(writer);
-  }
-
-  @Override
-  void writeAsMessageSetTo(UnknownFieldSetLite fields, Writer writer) throws IOException {
-    fields.writeAsMessageSetTo(writer);
-  }
-
-  @Override
-  UnknownFieldSetLite merge(UnknownFieldSetLite message, UnknownFieldSetLite other) {
-    return other.equals(UnknownFieldSetLite.getDefaultInstance())
-        ? message
-        : UnknownFieldSetLite.mutableCopyOf(message, other);
-  }
-
-  @Override
-  int getSerializedSize(UnknownFieldSetLite unknowns) {
-    return unknowns.getSerializedSize();
-  }
-
-  @Override
-  int getSerializedSizeAsMessageSet(UnknownFieldSetLite unknowns) {
-    return unknowns.getSerializedSizeAsMessageSet();
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UnmodifiableCollections.kt b/java/kotlin-lite/target/generated-sources/com/google/protobuf/UnmodifiableCollections.kt
deleted file mode 100644
index 6af93e1..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UnmodifiableCollections.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.google.protobuf.kotlin
-
-/** Wraps an [Iterator] and makes it unmodifiable even from Java. */
-internal class UnmodifiableIterator<E>(delegate: Iterator<E>) : Iterator<E> by delegate
-
-/** Wraps a [ListIterator] and makes it unmodifiable even from Java. */
-internal class UnmodifiableListIterator<E>(
-  delegate: ListIterator<E>
-) : ListIterator<E> by delegate
-
-/** Wraps a [Collection] and makes it unmodifiable even from Java. */
-internal open class UnmodifiableCollection<E>(
-  private val delegate: Collection<E>
-) : Collection<E> by delegate {
-  override fun iterator(): Iterator<E> = UnmodifiableIterator(delegate.iterator())
-}
-
-/** Wraps a [Set] and makes it unmodifiable even from Java. */
-internal class UnmodifiableSet<E>(
-  delegate: Collection<E>
-) : UnmodifiableCollection<E>(delegate), Set<E>
-
-/** Wraps a [Map.Entry] and makes it unmodifiable even from Java. */
-internal class UnmodifiableMapEntry<K, V>(delegate: Map.Entry<K, V>) : Map.Entry<K, V> by delegate
-
-/** Wraps a [Set] of map entries and makes it unmodifiable even from Java. */
-internal class UnmodifiableMapEntries<K, V>(
-  private val delegate: Set<Map.Entry<K, V>>
-) : UnmodifiableCollection<Map.Entry<K, V>>(delegate), Set<Map.Entry<K, V>> {
-
-  // Is this overkill? Probably.
-
-  override fun iterator(): Iterator<Map.Entry<K, V>> {
-    val itr = delegate.iterator()
-    return object : Iterator<Map.Entry<K, V>> by itr {
-      override fun next(): Map.Entry<K, V> = UnmodifiableMapEntry(itr.next())
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UnmodifiableLazyStringList.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/UnmodifiableLazyStringList.java
deleted file mode 100644
index 415b2cd..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UnmodifiableLazyStringList.java
+++ /dev/null
@@ -1,210 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.util.AbstractList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.RandomAccess;
-
-/**
- * An implementation of {@link LazyStringList} that wraps another {@link LazyStringList} such that
- * it cannot be modified via the wrapper.
- *
- * @author jonp@google.com (Jon Perlow)
- */
-public class UnmodifiableLazyStringList extends AbstractList<String>
-    implements LazyStringList, RandomAccess {
-
-  private final LazyStringList list;
-
-  public UnmodifiableLazyStringList(LazyStringList list) {
-    this.list = list;
-  }
-
-  @Override
-  public String get(int index) {
-    return list.get(index);
-  }
-
-  @Override
-  public Object getRaw(int index) {
-    return list.getRaw(index);
-  }
-
-  @Override
-  public int size() {
-    return list.size();
-  }
-
-  @Override
-  public ByteString getByteString(int index) {
-    return list.getByteString(index);
-  }
-
-  @Override
-  public void add(ByteString element) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void set(int index, ByteString element) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public boolean addAllByteString(Collection<? extends ByteString> element) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public byte[] getByteArray(int index) {
-    return list.getByteArray(index);
-  }
-
-  @Override
-  public void add(byte[] element) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void set(int index, byte[] element) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public boolean addAllByteArray(Collection<byte[]> element) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public ListIterator<String> listIterator(final int index) {
-    return new ListIterator<String>() {
-      ListIterator<String> iter = list.listIterator(index);
-
-      @Override
-      public boolean hasNext() {
-        return iter.hasNext();
-      }
-
-      @Override
-      public String next() {
-        return iter.next();
-      }
-
-      @Override
-      public boolean hasPrevious() {
-        return iter.hasPrevious();
-      }
-
-      @Override
-      public String previous() {
-        return iter.previous();
-      }
-
-      @Override
-      public int nextIndex() {
-        return iter.nextIndex();
-      }
-
-      @Override
-      public int previousIndex() {
-        return iter.previousIndex();
-      }
-
-      @Override
-      public void remove() {
-        throw new UnsupportedOperationException();
-      }
-
-      @Override
-      public void set(String o) {
-        throw new UnsupportedOperationException();
-      }
-
-      @Override
-      public void add(String o) {
-        throw new UnsupportedOperationException();
-      }
-    };
-  }
-
-  @Override
-  public Iterator<String> iterator() {
-    return new Iterator<String>() {
-      Iterator<String> iter = list.iterator();
-
-      @Override
-      public boolean hasNext() {
-        return iter.hasNext();
-      }
-
-      @Override
-      public String next() {
-        return iter.next();
-      }
-
-      @Override
-      public void remove() {
-        throw new UnsupportedOperationException();
-      }
-    };
-  }
-
-  @Override
-  public List<?> getUnderlyingElements() {
-    // The returned value is already unmodifiable.
-    return list.getUnderlyingElements();
-  }
-
-  @Override
-  public void mergeFrom(LazyStringList other) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public List<byte[]> asByteArrayList() {
-    return Collections.unmodifiableList(list.asByteArrayList());
-  }
-
-  @Override
-  public List<ByteString> asByteStringList() {
-    return Collections.unmodifiableList(list.asByteStringList());
-  }
-
-  @Override
-  public LazyStringList getUnmodifiableView() {
-    return this;
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UnsafeUtil.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/UnsafeUtil.java
deleted file mode 100644
index dd459f0..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/UnsafeUtil.java
+++ /dev/null
@@ -1,1036 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.lang.reflect.Field;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.security.AccessController;
-import java.security.PrivilegedExceptionAction;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/** Utility class for working with unsafe operations. */
-final class UnsafeUtil {
-  private static final sun.misc.Unsafe UNSAFE = getUnsafe();
-  private static final Class<?> MEMORY_CLASS = Android.getMemoryClass();
-  private static final boolean IS_ANDROID_64 = determineAndroidSupportByAddressSize(long.class);
-  private static final boolean IS_ANDROID_32 = determineAndroidSupportByAddressSize(int.class);
-  private static final MemoryAccessor MEMORY_ACCESSOR = getMemoryAccessor();
-  private static final boolean HAS_UNSAFE_BYTEBUFFER_OPERATIONS =
-      supportsUnsafeByteBufferOperations();
-  private static final boolean HAS_UNSAFE_ARRAY_OPERATIONS = supportsUnsafeArrayOperations();
-
-  static final long BYTE_ARRAY_BASE_OFFSET = arrayBaseOffset(byte[].class);
-  // Micro-optimization: we can assume a scale of 1 and skip the multiply
-  // private static final long BYTE_ARRAY_INDEX_SCALE = 1;
-
-  private static final long BOOLEAN_ARRAY_BASE_OFFSET = arrayBaseOffset(boolean[].class);
-  private static final long BOOLEAN_ARRAY_INDEX_SCALE = arrayIndexScale(boolean[].class);
-
-  private static final long INT_ARRAY_BASE_OFFSET = arrayBaseOffset(int[].class);
-  private static final long INT_ARRAY_INDEX_SCALE = arrayIndexScale(int[].class);
-
-  private static final long LONG_ARRAY_BASE_OFFSET = arrayBaseOffset(long[].class);
-  private static final long LONG_ARRAY_INDEX_SCALE = arrayIndexScale(long[].class);
-
-  private static final long FLOAT_ARRAY_BASE_OFFSET = arrayBaseOffset(float[].class);
-  private static final long FLOAT_ARRAY_INDEX_SCALE = arrayIndexScale(float[].class);
-
-  private static final long DOUBLE_ARRAY_BASE_OFFSET = arrayBaseOffset(double[].class);
-  private static final long DOUBLE_ARRAY_INDEX_SCALE = arrayIndexScale(double[].class);
-
-  private static final long OBJECT_ARRAY_BASE_OFFSET = arrayBaseOffset(Object[].class);
-  private static final long OBJECT_ARRAY_INDEX_SCALE = arrayIndexScale(Object[].class);
-
-  private static final long BUFFER_ADDRESS_OFFSET = fieldOffset(bufferAddressField());
-
-  private static final int STRIDE = 8;
-  private static final int STRIDE_ALIGNMENT_MASK = STRIDE - 1;
-  private static final int BYTE_ARRAY_ALIGNMENT =
-      (int) (BYTE_ARRAY_BASE_OFFSET & STRIDE_ALIGNMENT_MASK);
-
-  static final boolean IS_BIG_ENDIAN = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
-
-  private UnsafeUtil() {}
-
-  static boolean hasUnsafeArrayOperations() {
-    return HAS_UNSAFE_ARRAY_OPERATIONS;
-  }
-
-  static boolean hasUnsafeByteBufferOperations() {
-    return HAS_UNSAFE_BYTEBUFFER_OPERATIONS;
-  }
-
-  static boolean isAndroid64() {
-    return IS_ANDROID_64;
-  }
-
-  @SuppressWarnings("unchecked") // safe by method contract
-  static <T> T allocateInstance(Class<T> clazz) {
-    try {
-      return (T) UNSAFE.allocateInstance(clazz);
-    } catch (InstantiationException e) {
-      throw new IllegalStateException(e);
-    }
-  }
-
-  static long objectFieldOffset(Field field) {
-    return MEMORY_ACCESSOR.objectFieldOffset(field);
-  }
-
-  private static int arrayBaseOffset(Class<?> clazz) {
-    return HAS_UNSAFE_ARRAY_OPERATIONS ? MEMORY_ACCESSOR.arrayBaseOffset(clazz) : -1;
-  }
-
-  private static int arrayIndexScale(Class<?> clazz) {
-    return HAS_UNSAFE_ARRAY_OPERATIONS ? MEMORY_ACCESSOR.arrayIndexScale(clazz) : -1;
-  }
-
-  static byte getByte(Object target, long offset) {
-    return MEMORY_ACCESSOR.getByte(target, offset);
-  }
-
-  static void putByte(Object target, long offset, byte value) {
-    MEMORY_ACCESSOR.putByte(target, offset, value);
-  }
-
-  static int getInt(Object target, long offset) {
-    return MEMORY_ACCESSOR.getInt(target, offset);
-  }
-
-  static void putInt(Object target, long offset, int value) {
-    MEMORY_ACCESSOR.putInt(target, offset, value);
-  }
-
-  static long getLong(Object target, long offset) {
-    return MEMORY_ACCESSOR.getLong(target, offset);
-  }
-
-  static void putLong(Object target, long offset, long value) {
-    MEMORY_ACCESSOR.putLong(target, offset, value);
-  }
-
-  static boolean getBoolean(Object target, long offset) {
-    return MEMORY_ACCESSOR.getBoolean(target, offset);
-  }
-
-  static void putBoolean(Object target, long offset, boolean value) {
-    MEMORY_ACCESSOR.putBoolean(target, offset, value);
-  }
-
-  static float getFloat(Object target, long offset) {
-    return MEMORY_ACCESSOR.getFloat(target, offset);
-  }
-
-  static void putFloat(Object target, long offset, float value) {
-    MEMORY_ACCESSOR.putFloat(target, offset, value);
-  }
-
-  static double getDouble(Object target, long offset) {
-    return MEMORY_ACCESSOR.getDouble(target, offset);
-  }
-
-  static void putDouble(Object target, long offset, double value) {
-    MEMORY_ACCESSOR.putDouble(target, offset, value);
-  }
-
-  static Object getObject(Object target, long offset) {
-    return MEMORY_ACCESSOR.getObject(target, offset);
-  }
-
-  static void putObject(Object target, long offset, Object value) {
-    MEMORY_ACCESSOR.putObject(target, offset, value);
-  }
-
-  static byte getByte(byte[] target, long index) {
-    return MEMORY_ACCESSOR.getByte(target, BYTE_ARRAY_BASE_OFFSET + index);
-  }
-
-  static void putByte(byte[] target, long index, byte value) {
-    MEMORY_ACCESSOR.putByte(target, BYTE_ARRAY_BASE_OFFSET + index, value);
-  }
-
-  static int getInt(int[] target, long index) {
-    return MEMORY_ACCESSOR.getInt(target, INT_ARRAY_BASE_OFFSET + (index * INT_ARRAY_INDEX_SCALE));
-  }
-
-  static void putInt(int[] target, long index, int value) {
-    MEMORY_ACCESSOR.putInt(target, INT_ARRAY_BASE_OFFSET + (index * INT_ARRAY_INDEX_SCALE), value);
-  }
-
-  static long getLong(long[] target, long index) {
-    return MEMORY_ACCESSOR.getLong(
-        target, LONG_ARRAY_BASE_OFFSET + (index * LONG_ARRAY_INDEX_SCALE));
-  }
-
-  static void putLong(long[] target, long index, long value) {
-    MEMORY_ACCESSOR.putLong(
-        target, LONG_ARRAY_BASE_OFFSET + (index * LONG_ARRAY_INDEX_SCALE), value);
-  }
-
-  static boolean getBoolean(boolean[] target, long index) {
-    return MEMORY_ACCESSOR.getBoolean(
-        target, BOOLEAN_ARRAY_BASE_OFFSET + (index * BOOLEAN_ARRAY_INDEX_SCALE));
-  }
-
-  static void putBoolean(boolean[] target, long index, boolean value) {
-    MEMORY_ACCESSOR.putBoolean(
-        target, BOOLEAN_ARRAY_BASE_OFFSET + (index * BOOLEAN_ARRAY_INDEX_SCALE), value);
-  }
-
-  static float getFloat(float[] target, long index) {
-    return MEMORY_ACCESSOR.getFloat(
-        target, FLOAT_ARRAY_BASE_OFFSET + (index * FLOAT_ARRAY_INDEX_SCALE));
-  }
-
-  static void putFloat(float[] target, long index, float value) {
-    MEMORY_ACCESSOR.putFloat(
-        target, FLOAT_ARRAY_BASE_OFFSET + (index * FLOAT_ARRAY_INDEX_SCALE), value);
-  }
-
-  static double getDouble(double[] target, long index) {
-    return MEMORY_ACCESSOR.getDouble(
-        target, DOUBLE_ARRAY_BASE_OFFSET + (index * DOUBLE_ARRAY_INDEX_SCALE));
-  }
-
-  static void putDouble(double[] target, long index, double value) {
-    MEMORY_ACCESSOR.putDouble(
-        target, DOUBLE_ARRAY_BASE_OFFSET + (index * DOUBLE_ARRAY_INDEX_SCALE), value);
-  }
-
-  static Object getObject(Object[] target, long index) {
-    return MEMORY_ACCESSOR.getObject(
-        target, OBJECT_ARRAY_BASE_OFFSET + (index * OBJECT_ARRAY_INDEX_SCALE));
-  }
-
-  static void putObject(Object[] target, long index, Object value) {
-    MEMORY_ACCESSOR.putObject(
-        target, OBJECT_ARRAY_BASE_OFFSET + (index * OBJECT_ARRAY_INDEX_SCALE), value);
-  }
-
-  static void copyMemory(byte[] src, long srcIndex, long targetOffset, long length) {
-    MEMORY_ACCESSOR.copyMemory(src, srcIndex, targetOffset, length);
-  }
-
-  static void copyMemory(long srcOffset, byte[] target, long targetIndex, long length) {
-    MEMORY_ACCESSOR.copyMemory(srcOffset, target, targetIndex, length);
-  }
-
-  static void copyMemory(byte[] src, long srcIndex, byte[] target, long targetIndex, long length) {
-    System.arraycopy(src, (int) srcIndex, target, (int) targetIndex, (int) length);
-  }
-
-  static byte getByte(long address) {
-    return MEMORY_ACCESSOR.getByte(address);
-  }
-
-  static void putByte(long address, byte value) {
-    MEMORY_ACCESSOR.putByte(address, value);
-  }
-
-  static int getInt(long address) {
-    return MEMORY_ACCESSOR.getInt(address);
-  }
-
-  static void putInt(long address, int value) {
-    MEMORY_ACCESSOR.putInt(address, value);
-  }
-
-  static long getLong(long address) {
-    return MEMORY_ACCESSOR.getLong(address);
-  }
-
-  static void putLong(long address, long value) {
-    MEMORY_ACCESSOR.putLong(address, value);
-  }
-
-  /** Gets the offset of the {@code address} field of the given direct {@link ByteBuffer}. */
-  static long addressOffset(ByteBuffer buffer) {
-    return MEMORY_ACCESSOR.getLong(buffer, BUFFER_ADDRESS_OFFSET);
-  }
-
-  static Object getStaticObject(Field field) {
-    return MEMORY_ACCESSOR.getStaticObject(field);
-  }
-
-  /**
-   * Gets the {@code sun.misc.Unsafe} instance, or {@code null} if not available on this platform.
-   */
-  static sun.misc.Unsafe getUnsafe() {
-    sun.misc.Unsafe unsafe = null;
-    try {
-      unsafe =
-          AccessController.doPrivileged(
-              new PrivilegedExceptionAction<sun.misc.Unsafe>() {
-                @Override
-                public sun.misc.Unsafe run() throws Exception {
-                  Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
-
-                  for (Field f : k.getDeclaredFields()) {
-                    f.setAccessible(true);
-                    Object x = f.get(null);
-                    if (k.isInstance(x)) {
-                      return k.cast(x);
-                    }
-                  }
-                  // The sun.misc.Unsafe field does not exist.
-                  return null;
-                }
-              });
-    } catch (Throwable e) {
-      // Catching Throwable here due to the fact that Google AppEngine raises NoClassDefFoundError
-      // for Unsafe.
-    }
-    return unsafe;
-  }
-
-  /** Get a {@link MemoryAccessor} appropriate for the platform, or null if not supported. */
-  private static MemoryAccessor getMemoryAccessor() {
-    if (UNSAFE == null) {
-      return null;
-    }
-    if (Android.isOnAndroidDevice()) {
-      if (IS_ANDROID_64) {
-        return new Android64MemoryAccessor(UNSAFE);
-      } else if (IS_ANDROID_32) {
-        return new Android32MemoryAccessor(UNSAFE);
-      } else {
-        return null;
-      }
-    }
-
-    return new JvmMemoryAccessor(UNSAFE);
-  }
-
-  private static boolean supportsUnsafeArrayOperations() {
-    if (MEMORY_ACCESSOR == null) {
-      return false;
-    }
-    return MEMORY_ACCESSOR.supportsUnsafeArrayOperations();
-  }
-
-  private static boolean supportsUnsafeByteBufferOperations() {
-    if (MEMORY_ACCESSOR == null) {
-      return false;
-    }
-    return MEMORY_ACCESSOR.supportsUnsafeByteBufferOperations();
-  }
-
-  static boolean determineAndroidSupportByAddressSize(Class<?> addressClass) {
-    if (!Android.isOnAndroidDevice()) {
-      return false;
-    }
-    try {
-      Class<?> clazz = MEMORY_CLASS;
-      clazz.getMethod("peekLong", addressClass, boolean.class);
-      clazz.getMethod("pokeLong", addressClass, long.class, boolean.class);
-      clazz.getMethod("pokeInt", addressClass, int.class, boolean.class);
-      clazz.getMethod("peekInt", addressClass, boolean.class);
-      clazz.getMethod("pokeByte", addressClass, byte.class);
-      clazz.getMethod("peekByte", addressClass);
-      clazz.getMethod("pokeByteArray", addressClass, byte[].class, int.class, int.class);
-      clazz.getMethod("peekByteArray", addressClass, byte[].class, int.class, int.class);
-      return true;
-    } catch (Throwable t) {
-      return false;
-    }
-  }
-
-  /** Finds the address field within a direct {@link Buffer}. */
-  private static Field bufferAddressField() {
-    if (Android.isOnAndroidDevice()) {
-      // Old versions of Android had renamed the address field to 'effectiveDirectAddress', but
-      // recent versions of Android (>M?) use the OpenJDK implementation. Fall through in that case.
-      Field field = field(Buffer.class, "effectiveDirectAddress");
-      if (field != null) {
-        return field;
-      }
-    }
-    Field field = field(Buffer.class, "address");
-    return field != null && field.getType() == long.class ? field : null;
-  }
-
-  /**
-   * Returns the index of the first byte where left and right differ, in the range [0, 8]. If {@code
-   * left == right}, the result will be 8, otherwise less than 8.
-   *
-   * <p>This counts from the *first* byte, which may be the most or least significant byte depending
-   * on the system endianness.
-   */
-  private static int firstDifferingByteIndexNativeEndian(long left, long right) {
-    int n =
-        IS_BIG_ENDIAN
-            ? Long.numberOfLeadingZeros(left ^ right)
-            : Long.numberOfTrailingZeros(left ^ right);
-    return n >> 3;
-  }
-
-  /**
-   * Returns the lowest {@code index} such that {@code 0 <= index < length} and {@code left[leftOff
-   * + index] != right[rightOff + index]}. If no such value exists -- if {@code left} and {@code
-   * right} match up to {@code length} bytes from their respective offsets -- returns -1.
-   *
-   * <p>{@code leftOff + length} must be less than or equal to {@code left.length}, and the same for
-   * {@code right}.
-   */
-  static int mismatch(byte[] left, int leftOff, byte[] right, int rightOff, int length) {
-    if (leftOff < 0
-        || rightOff < 0
-        || length < 0
-        || leftOff + length > left.length
-        || rightOff + length > right.length) {
-      throw new IndexOutOfBoundsException();
-    }
-
-    int index = 0;
-    if (HAS_UNSAFE_ARRAY_OPERATIONS) {
-      int leftAlignment = (BYTE_ARRAY_ALIGNMENT + leftOff) & STRIDE_ALIGNMENT_MASK;
-
-      // Most CPUs handle getting chunks of bytes better on addresses that are a multiple of 4
-      // or 8.
-      // We walk one byte at a time until the left address, at least, is a multiple of 8.
-      // If the right address is, too, so much the better.
-      for (;
-          index < length && (leftAlignment & STRIDE_ALIGNMENT_MASK) != 0;
-          index++, leftAlignment++) {
-        if (left[leftOff + index] != right[rightOff + index]) {
-          return index;
-        }
-      }
-
-      // Stride!  Grab eight bytes at a time from left and right and check them for equality.
-
-      int strideLength = ((length - index) & ~STRIDE_ALIGNMENT_MASK) + index;
-      // strideLength is the point where we want to stop striding: it differs from index by
-      // a multiple of STRIDE, and it's the largest such number <= length.
-
-      for (; index < strideLength; index += STRIDE) {
-        long leftLongWord = getLong(left, BYTE_ARRAY_BASE_OFFSET + leftOff + index);
-        long rightLongWord = getLong(right, BYTE_ARRAY_BASE_OFFSET + rightOff + index);
-        if (leftLongWord != rightLongWord) {
-          // one of these eight bytes differ!  use a helper to find out which one
-          return index + firstDifferingByteIndexNativeEndian(leftLongWord, rightLongWord);
-        }
-      }
-    }
-
-    // If we were able to stride, there are at most STRIDE - 1 bytes left to compare.
-    // If we weren't, then this loop covers the whole thing.
-    for (; index < length; index++) {
-      if (left[leftOff + index] != right[rightOff + index]) {
-        return index;
-      }
-    }
-    return -1;
-  }
-
-  /**
-   * Returns the offset of the provided field, or {@code -1} if {@code sun.misc.Unsafe} is not
-   * available.
-   */
-  private static long fieldOffset(Field field) {
-    return field == null || MEMORY_ACCESSOR == null ? -1 : MEMORY_ACCESSOR.objectFieldOffset(field);
-  }
-
-  /**
-   * Gets the field with the given name within the class, or {@code null} if not found.
-   */
-  private static Field field(Class<?> clazz, String fieldName) {
-    Field field;
-    try {
-      field = clazz.getDeclaredField(fieldName);
-    } catch (Throwable t) {
-      // Failed to access the fields.
-      field = null;
-    }
-    return field;
-  }
-
-  private abstract static class MemoryAccessor {
-
-    sun.misc.Unsafe unsafe;
-
-    MemoryAccessor(sun.misc.Unsafe unsafe) {
-      this.unsafe = unsafe;
-    }
-
-    public final long objectFieldOffset(Field field) {
-      return unsafe.objectFieldOffset(field);
-    }
-
-    public final int arrayBaseOffset(Class<?> clazz) {
-      return unsafe.arrayBaseOffset(clazz);
-    }
-
-    public final int arrayIndexScale(Class<?> clazz) {
-      return unsafe.arrayIndexScale(clazz);
-    }
-
-    public abstract Object getStaticObject(Field field);
-
-    // Relative Address Operations ---------------------------------------------
-
-    // Indicates whether the following relative address operations are supported
-    // by this memory accessor.
-    public boolean supportsUnsafeArrayOperations() {
-      if (unsafe == null) {
-        return false;
-      }
-      try {
-        Class<?> clazz = unsafe.getClass();
-        clazz.getMethod("objectFieldOffset", Field.class);
-        clazz.getMethod("arrayBaseOffset", Class.class);
-        clazz.getMethod("arrayIndexScale", Class.class);
-        clazz.getMethod("getInt", Object.class, long.class);
-        clazz.getMethod("putInt", Object.class, long.class, int.class);
-        clazz.getMethod("getLong", Object.class, long.class);
-        clazz.getMethod("putLong", Object.class, long.class, long.class);
-        clazz.getMethod("getObject", Object.class, long.class);
-        clazz.getMethod("putObject", Object.class, long.class, Object.class);
-
-        return true;
-      } catch (Throwable e) {
-        logMissingMethod(e);
-      }
-      return false;
-    }
-
-    public abstract byte getByte(Object target, long offset);
-
-    public abstract void putByte(Object target, long offset, byte value);
-
-    public final int getInt(Object target, long offset) {
-      return unsafe.getInt(target, offset);
-    }
-
-    public final void putInt(Object target, long offset, int value) {
-      unsafe.putInt(target, offset, value);
-    }
-
-    public final long getLong(Object target, long offset) {
-      return unsafe.getLong(target, offset);
-    }
-
-    public final void putLong(Object target, long offset, long value) {
-      unsafe.putLong(target, offset, value);
-    }
-
-    public abstract boolean getBoolean(Object target, long offset);
-
-    public abstract void putBoolean(Object target, long offset, boolean value);
-
-    public abstract float getFloat(Object target, long offset);
-
-    public abstract void putFloat(Object target, long offset, float value);
-
-    public abstract double getDouble(Object target, long offset);
-
-    public abstract void putDouble(Object target, long offset, double value);
-
-    public final Object getObject(Object target, long offset) {
-      return unsafe.getObject(target, offset);
-    }
-
-    public final void putObject(Object target, long offset, Object value) {
-      unsafe.putObject(target, offset, value);
-    }
-
-    // Absolute Address Operations --------------------------------------------
-
-    // Indicates whether the following absolute address operations are
-    // supported by this memory accessor.
-    public boolean supportsUnsafeByteBufferOperations() {
-      if (unsafe == null) {
-        return false;
-      }
-      try {
-        Class<?> clazz = unsafe.getClass();
-        // Methods for getting direct buffer address.
-        clazz.getMethod("objectFieldOffset", Field.class);
-        clazz.getMethod("getLong", Object.class, long.class);
-
-        if (bufferAddressField() == null) {
-          return false;
-        }
-
-        return true;
-      } catch (Throwable e) {
-        logMissingMethod(e);
-      }
-      return false;
-    }
-
-    public abstract byte getByte(long address);
-
-    public abstract void putByte(long address, byte value);
-
-    public abstract int getInt(long address);
-
-    public abstract void putInt(long address, int value);
-
-    public abstract long getLong(long address);
-
-    public abstract void putLong(long address, long value);
-
-    public abstract void copyMemory(long srcOffset, byte[] target, long targetIndex, long length);
-
-    public abstract void copyMemory(byte[] src, long srcIndex, long targetOffset, long length);
-  }
-
-  private static final class JvmMemoryAccessor extends MemoryAccessor {
-
-    JvmMemoryAccessor(sun.misc.Unsafe unsafe) {
-      super(unsafe);
-    }
-
-    @Override
-    public Object getStaticObject(Field field) {
-      return getObject(unsafe.staticFieldBase(field), unsafe.staticFieldOffset(field));
-    }
-
-    @Override
-    public boolean supportsUnsafeArrayOperations() {
-      if (!super.supportsUnsafeArrayOperations()) {
-        return false;
-      }
-
-      try {
-        Class<?> clazz = unsafe.getClass();
-        clazz.getMethod("getByte", Object.class, long.class);
-        clazz.getMethod("putByte", Object.class, long.class, byte.class);
-        clazz.getMethod("getBoolean", Object.class, long.class);
-        clazz.getMethod("putBoolean", Object.class, long.class, boolean.class);
-        clazz.getMethod("getFloat", Object.class, long.class);
-        clazz.getMethod("putFloat", Object.class, long.class, float.class);
-        clazz.getMethod("getDouble", Object.class, long.class);
-        clazz.getMethod("putDouble", Object.class, long.class, double.class);
-
-        return true;
-      } catch (Throwable e) {
-        logMissingMethod(e);
-      }
-      return false;
-    }
-
-    @Override
-    public byte getByte(Object target, long offset) {
-      return unsafe.getByte(target, offset);
-    }
-
-    @Override
-    public void putByte(Object target, long offset, byte value) {
-      unsafe.putByte(target, offset, value);
-    }
-
-    @Override
-    public boolean getBoolean(Object target, long offset) {
-      return unsafe.getBoolean(target, offset);
-    }
-
-    @Override
-    public void putBoolean(Object target, long offset, boolean value) {
-      unsafe.putBoolean(target, offset, value);
-    }
-
-    @Override
-    public float getFloat(Object target, long offset) {
-      return unsafe.getFloat(target, offset);
-    }
-
-    @Override
-    public void putFloat(Object target, long offset, float value) {
-      unsafe.putFloat(target, offset, value);
-    }
-
-    @Override
-    public double getDouble(Object target, long offset) {
-      return unsafe.getDouble(target, offset);
-    }
-
-    @Override
-    public void putDouble(Object target, long offset, double value) {
-      unsafe.putDouble(target, offset, value);
-    }
-
-    @Override
-    public boolean supportsUnsafeByteBufferOperations() {
-      if (!super.supportsUnsafeByteBufferOperations()) {
-        return false;
-      }
-
-      try {
-        Class<?> clazz = unsafe.getClass();
-        clazz.getMethod("getByte", long.class);
-        clazz.getMethod("putByte", long.class, byte.class);
-        clazz.getMethod("getInt", long.class);
-        clazz.getMethod("putInt", long.class, int.class);
-        clazz.getMethod("getLong", long.class);
-        clazz.getMethod("putLong", long.class, long.class);
-        clazz.getMethod("copyMemory", long.class, long.class, long.class);
-        clazz.getMethod(
-            "copyMemory", Object.class, long.class, Object.class, long.class, long.class);
-        return true;
-      } catch (Throwable e) {
-        logMissingMethod(e);
-      }
-      return false;
-    }
-
-    @Override
-    public byte getByte(long address) {
-      return unsafe.getByte(address);
-    }
-
-    @Override
-    public void putByte(long address, byte value) {
-      unsafe.putByte(address, value);
-    }
-
-    @Override
-    public int getInt(long address) {
-      return unsafe.getInt(address);
-    }
-
-    @Override
-    public void putInt(long address, int value) {
-      unsafe.putInt(address, value);
-    }
-
-    @Override
-    public long getLong(long address) {
-      return unsafe.getLong(address);
-    }
-
-    @Override
-    public void putLong(long address, long value) {
-      unsafe.putLong(address, value);
-    }
-
-    @Override
-    public void copyMemory(long srcOffset, byte[] target, long targetIndex, long length) {
-      unsafe.copyMemory(null, srcOffset, target, BYTE_ARRAY_BASE_OFFSET + targetIndex, length);
-    }
-
-    @Override
-    public void copyMemory(byte[] src, long srcIndex, long targetOffset, long length) {
-      unsafe.copyMemory(src, BYTE_ARRAY_BASE_OFFSET + srcIndex, null, targetOffset, length);
-    }
-  }
-
-  private static final class Android64MemoryAccessor extends MemoryAccessor {
-
-    Android64MemoryAccessor(sun.misc.Unsafe unsafe) {
-      super(unsafe);
-    }
-
-    @Override
-    public Object getStaticObject(Field field) {
-      try {
-        return field.get(null);
-      } catch (IllegalAccessException e) {
-        return null;
-      }
-    }
-
-    @Override
-    public byte getByte(Object target, long offset) {
-      if (IS_BIG_ENDIAN) {
-        return getByteBigEndian(target, offset);
-      } else {
-        return getByteLittleEndian(target, offset);
-      }
-    }
-
-    @Override
-    public void putByte(Object target, long offset, byte value) {
-      if (IS_BIG_ENDIAN) {
-        putByteBigEndian(target, offset, value);
-      } else {
-        putByteLittleEndian(target, offset, value);
-      }
-    }
-
-    @Override
-    public boolean getBoolean(Object target, long offset) {
-      if (IS_BIG_ENDIAN) {
-        return getBooleanBigEndian(target, offset);
-      } else {
-        return getBooleanLittleEndian(target, offset);
-      }
-    }
-
-    @Override
-    public void putBoolean(Object target, long offset, boolean value) {
-      if (IS_BIG_ENDIAN) {
-        putBooleanBigEndian(target, offset, value);
-      } else {
-        putBooleanLittleEndian(target, offset, value);
-      }
-    }
-
-    @Override
-    public float getFloat(Object target, long offset) {
-      return Float.intBitsToFloat(getInt(target, offset));
-    }
-
-    @Override
-    public void putFloat(Object target, long offset, float value) {
-      putInt(target, offset, Float.floatToIntBits(value));
-    }
-
-    @Override
-    public double getDouble(Object target, long offset) {
-      return Double.longBitsToDouble(getLong(target, offset));
-    }
-
-    @Override
-    public void putDouble(Object target, long offset, double value) {
-      putLong(target, offset, Double.doubleToLongBits(value));
-    }
-
-    @Override
-    public boolean supportsUnsafeByteBufferOperations() {
-      return false;
-    }
-
-    @Override
-    public byte getByte(long address) {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void putByte(long address, byte value) {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getInt(long address) {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void putInt(long address, int value) {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long getLong(long address) {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void putLong(long address, long value) {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void copyMemory(long srcOffset, byte[] target, long targetIndex, long length) {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void copyMemory(byte[] src, long srcIndex, long targetOffset, long length) {
-      throw new UnsupportedOperationException();
-    }
-  }
-
-  private static final class Android32MemoryAccessor extends MemoryAccessor {
-
-    /** Mask used to convert a 64 bit memory address to a 32 bit address. */
-    private static final long SMALL_ADDRESS_MASK = 0x00000000FFFFFFFF;
-
-    /** Truncate a {@code long} address into a short {@code int} address. */
-    private static int smallAddress(long address) {
-      return (int) (SMALL_ADDRESS_MASK & address);
-    }
-
-    Android32MemoryAccessor(sun.misc.Unsafe unsafe) {
-      super(unsafe);
-    }
-
-    @Override
-    public Object getStaticObject(Field field) {
-      try {
-        return field.get(null);
-      } catch (IllegalAccessException e) {
-        return null;
-      }
-    }
-
-    @Override
-    public byte getByte(Object target, long offset) {
-      if (IS_BIG_ENDIAN) {
-        return getByteBigEndian(target, offset);
-      } else {
-        return getByteLittleEndian(target, offset);
-      }
-    }
-
-    @Override
-    public void putByte(Object target, long offset, byte value) {
-      if (IS_BIG_ENDIAN) {
-        putByteBigEndian(target, offset, value);
-      } else {
-        putByteLittleEndian(target, offset, value);
-      }
-    }
-
-    @Override
-    public boolean getBoolean(Object target, long offset) {
-      if (IS_BIG_ENDIAN) {
-        return getBooleanBigEndian(target, offset);
-      } else {
-        return getBooleanLittleEndian(target, offset);
-      }
-    }
-
-    @Override
-    public void putBoolean(Object target, long offset, boolean value) {
-      if (IS_BIG_ENDIAN) {
-        putBooleanBigEndian(target, offset, value);
-      } else {
-        putBooleanLittleEndian(target, offset, value);
-      }
-    }
-
-    @Override
-    public float getFloat(Object target, long offset) {
-      return Float.intBitsToFloat(getInt(target, offset));
-    }
-
-    @Override
-    public void putFloat(Object target, long offset, float value) {
-      putInt(target, offset, Float.floatToIntBits(value));
-    }
-
-    @Override
-    public double getDouble(Object target, long offset) {
-      return Double.longBitsToDouble(getLong(target, offset));
-    }
-
-    @Override
-    public void putDouble(Object target, long offset, double value) {
-      putLong(target, offset, Double.doubleToLongBits(value));
-    }
-
-    @Override
-    public boolean supportsUnsafeByteBufferOperations() {
-      return false;
-    }
-
-    @Override
-    public byte getByte(long address) {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void putByte(long address, byte value) {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getInt(long address) {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void putInt(long address, int value) {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long getLong(long address) {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void putLong(long address, long value) {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void copyMemory(long srcOffset, byte[] target, long targetIndex, long length) {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void copyMemory(byte[] src, long srcIndex, long targetOffset, long length) {
-      throw new UnsupportedOperationException();
-    }
-  }
-
-  private static byte getByteBigEndian(Object target, long offset) {
-    return (byte) ((getInt(target, offset & ~3) >>> ((~offset & 3) << 3)) & 0xFF);
-  }
-
-  private static byte getByteLittleEndian(Object target, long offset) {
-    return (byte) ((getInt(target, offset & ~3) >>> ((offset & 3) << 3)) & 0xFF);
-  }
-
-  private static void putByteBigEndian(Object target, long offset, byte value) {
-    int intValue = getInt(target, offset & ~3);
-    int shift = ((~(int) offset) & 3) << 3;
-    int output = (intValue & ~(0xFF << shift)) | ((0xFF & value) << shift);
-    putInt(target, offset & ~3, output);
-  }
-
-  private static void putByteLittleEndian(Object target, long offset, byte value) {
-    int intValue = getInt(target, offset & ~3);
-    int shift = (((int) offset) & 3) << 3;
-    int output = (intValue & ~(0xFF << shift)) | ((0xFF & value) << shift);
-    putInt(target, offset & ~3, output);
-  }
-
-  private static boolean getBooleanBigEndian(Object target, long offset) {
-    return getByteBigEndian(target, offset) != 0;
-  }
-
-  private static boolean getBooleanLittleEndian(Object target, long offset) {
-    return getByteLittleEndian(target, offset) != 0;
-  }
-
-  private static void putBooleanBigEndian(Object target, long offset, boolean value) {
-    putByteBigEndian(target, offset, (byte) (value ? 1 : 0));
-  }
-
-  private static void putBooleanLittleEndian(Object target, long offset, boolean value) {
-    putByteLittleEndian(target, offset, (byte) (value ? 1 : 0));
-  }
-
-  private static void logMissingMethod(Throwable e) {
-    Logger.getLogger(UnsafeUtil.class.getName())
-        .log(
-            Level.WARNING,
-            "platform method missing - proto runtime falling back to safer methods: " + e);
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Utf8.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Utf8.java
deleted file mode 100644
index 104ab09..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Utf8.java
+++ /dev/null
@@ -1,1976 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.UnsafeUtil.addressOffset;
-import static com.google.protobuf.UnsafeUtil.hasUnsafeArrayOperations;
-import static com.google.protobuf.UnsafeUtil.hasUnsafeByteBufferOperations;
-import static java.lang.Character.MAX_SURROGATE;
-import static java.lang.Character.MIN_HIGH_SURROGATE;
-import static java.lang.Character.MIN_LOW_SURROGATE;
-import static java.lang.Character.MIN_SUPPLEMENTARY_CODE_POINT;
-import static java.lang.Character.MIN_SURROGATE;
-import static java.lang.Character.isSurrogatePair;
-import static java.lang.Character.toCodePoint;
-
-import java.nio.ByteBuffer;
-
-/**
- * A set of low-level, high-performance static utility methods related to the UTF-8 character
- * encoding. This class has no dependencies outside of the core JDK libraries.
- *
- * <p>There are several variants of UTF-8. The one implemented by this class is the restricted
- * definition of UTF-8 introduced in Unicode 3.1, which mandates the rejection of "overlong" byte
- * sequences as well as rejection of 3-byte surrogate codepoint byte sequences. Note that the UTF-8
- * decoder included in Oracle's JDK has been modified to also reject "overlong" byte sequences, but
- * (as of 2011) still accepts 3-byte surrogate codepoint byte sequences.
- *
- * <p>The byte sequences considered valid by this class are exactly those that can be roundtrip
- * converted to Strings and back to bytes using the UTF-8 charset, without loss:
- *
- * <pre>{@code
- * Arrays.equals(bytes, new String(bytes, Internal.UTF_8).getBytes(Internal.UTF_8))
- * }</pre>
- *
- * <p>See the Unicode Standard,</br> Table 3-6. <em>UTF-8 Bit Distribution</em>,</br> Table 3-7.
- * <em>Well Formed UTF-8 Byte Sequences</em>.
- *
- * <p>This class supports decoding of partial byte sequences, so that the bytes in a complete UTF-8
- * byte sequences can be stored in multiple segments. Methods typically return {@link #MALFORMED} if
- * the partial byte sequence is definitely not well-formed, {@link #COMPLETE} if it is well-formed
- * in the absence of additional input, or if the byte sequence apparently terminated in the middle
- * of a character, an opaque integer "state" value containing enough information to decode the
- * character when passed to a subsequent invocation of a partial decoding method.
- *
- * @author martinrb@google.com (Martin Buchholz)
- */
-// TODO(nathanmittler): Copy changes in this class back to Guava
-final class Utf8 {
-
-  /**
-   * UTF-8 is a runtime hot spot so we attempt to provide heavily optimized implementations
-   * depending on what is available on the platform. The processor is the platform-optimized
-   * delegate for which all methods are delegated directly to.
-   */
-  private static final Processor processor =
-      (UnsafeProcessor.isAvailable() && !Android.isOnAndroidDevice())
-          ? new UnsafeProcessor()
-          : new SafeProcessor();
-
-  /**
-   * A mask used when performing unsafe reads to determine if a long value contains any non-ASCII
-   * characters (i.e. any byte >= 0x80).
-   */
-  private static final long ASCII_MASK_LONG = 0x8080808080808080L;
-
-  /**
-   * Maximum number of bytes per Java UTF-16 char in UTF-8.
-   *
-   * @see java.nio.charset.CharsetEncoder#maxBytesPerChar()
-   */
-  static final int MAX_BYTES_PER_CHAR = 3;
-
-  /**
-   * State value indicating that the byte sequence is well-formed and complete (no further bytes are
-   * needed to complete a character).
-   */
-  public static final int COMPLETE = 0;
-
-  /** State value indicating that the byte sequence is definitely not well-formed. */
-  public static final int MALFORMED = -1;
-
-  /**
-   * Used by {@code Unsafe} UTF-8 string validation logic to determine the minimum string length
-   * above which to employ an optimized algorithm for counting ASCII characters. The reason for this
-   * threshold is that for small strings, the optimization may not be beneficial or may even
-   * negatively impact performance since it requires additional logic to avoid unaligned reads (when
-   * calling {@code Unsafe.getLong}). This threshold guarantees that even if the initial offset is
-   * unaligned, we're guaranteed to make at least one call to {@code Unsafe.getLong()} which
-   * provides a performance improvement that entirely subsumes the cost of the additional logic.
-   */
-  private static final int UNSAFE_COUNT_ASCII_THRESHOLD = 16;
-
-  // Other state values include the partial bytes of the incomplete
-  // character to be decoded in the simplest way: we pack the bytes
-  // into the state int in little-endian order.  For example:
-  //
-  // int state = byte1 ^ (byte2 << 8) ^ (byte3 << 16);
-  //
-  // Such a state is unpacked thus (note the ~ operation for byte2 to
-  // undo byte1's sign-extension bits):
-  //
-  // int byte1 = (byte) state;
-  // int byte2 = (byte) ~(state >> 8);
-  // int byte3 = (byte) (state >> 16);
-  //
-  // We cannot store a zero byte in the state because it would be
-  // indistinguishable from the absence of a byte.  But we don't need
-  // to, because partial bytes must always be negative.  When building
-  // a state, we ensure that byte1 is negative and subsequent bytes
-  // are valid trailing bytes.
-
-  /**
-   * Returns {@code true} if the given byte array is a well-formed UTF-8 byte sequence.
-   *
-   * <p>This is a convenience method, equivalent to a call to {@code isValidUtf8(bytes, 0,
-   * bytes.length)}.
-   */
-  public static boolean isValidUtf8(byte[] bytes) {
-    return processor.isValidUtf8(bytes, 0, bytes.length);
-  }
-
-  /**
-   * Returns {@code true} if the given byte array slice is a well-formed UTF-8 byte sequence. The
-   * range of bytes to be checked extends from index {@code index}, inclusive, to {@code limit},
-   * exclusive.
-   *
-   * <p>This is a convenience method, equivalent to {@code partialIsValidUtf8(bytes, index, limit)
-   * == Utf8.COMPLETE}.
-   */
-  public static boolean isValidUtf8(byte[] bytes, int index, int limit) {
-    return processor.isValidUtf8(bytes, index, limit);
-  }
-
-  /**
-   * Tells whether the given byte array slice is a well-formed, malformed, or incomplete UTF-8 byte
-   * sequence. The range of bytes to be checked extends from index {@code index}, inclusive, to
-   * {@code limit}, exclusive.
-   *
-   * @param state either {@link Utf8#COMPLETE} (if this is the initial decoding operation) or the
-   *     value returned from a call to a partial decoding method for the previous bytes
-   * @return {@link #MALFORMED} if the partial byte sequence is definitely not well-formed, {@link
-   *     #COMPLETE} if it is well-formed (no additional input needed), or if the byte sequence is
-   *     "incomplete", i.e. apparently terminated in the middle of a character, an opaque integer
-   *     "state" value containing enough information to decode the character when passed to a
-   *     subsequent invocation of a partial decoding method.
-   */
-  public static int partialIsValidUtf8(int state, byte[] bytes, int index, int limit) {
-    return processor.partialIsValidUtf8(state, bytes, index, limit);
-  }
-
-  private static int incompleteStateFor(int byte1) {
-    return (byte1 > (byte) 0xF4) ? MALFORMED : byte1;
-  }
-
-  private static int incompleteStateFor(int byte1, int byte2) {
-    return (byte1 > (byte) 0xF4 || byte2 > (byte) 0xBF) ? MALFORMED : byte1 ^ (byte2 << 8);
-  }
-
-  private static int incompleteStateFor(int byte1, int byte2, int byte3) {
-    return (byte1 > (byte) 0xF4 || byte2 > (byte) 0xBF || byte3 > (byte) 0xBF)
-        ? MALFORMED
-        : byte1 ^ (byte2 << 8) ^ (byte3 << 16);
-  }
-
-  private static int incompleteStateFor(byte[] bytes, int index, int limit) {
-    int byte1 = bytes[index - 1];
-    switch (limit - index) {
-      case 0:
-        return incompleteStateFor(byte1);
-      case 1:
-        return incompleteStateFor(byte1, bytes[index]);
-      case 2:
-        return incompleteStateFor(byte1, bytes[index], bytes[index + 1]);
-      default:
-        throw new AssertionError();
-    }
-  }
-
-  private static int incompleteStateFor(
-      final ByteBuffer buffer, final int byte1, final int index, final int remaining) {
-    switch (remaining) {
-      case 0:
-        return incompleteStateFor(byte1);
-      case 1:
-        return incompleteStateFor(byte1, buffer.get(index));
-      case 2:
-        return incompleteStateFor(byte1, buffer.get(index), buffer.get(index + 1));
-      default:
-        throw new AssertionError();
-    }
-  }
-
-  // These UTF-8 handling methods are copied from Guava's Utf8 class with a modification to throw
-  // a protocol buffer local exception. This exception is then caught in CodedOutputStream so it can
-  // fallback to more lenient behavior.
-
-  static class UnpairedSurrogateException extends IllegalArgumentException {
-    UnpairedSurrogateException(int index, int length) {
-      super("Unpaired surrogate at index " + index + " of " + length);
-    }
-  }
-
-  /**
-   * Returns the number of bytes in the UTF-8-encoded form of {@code sequence}. For a string, this
-   * method is equivalent to {@code string.getBytes(UTF_8).length}, but is more efficient in both
-   * time and space.
-   *
-   * @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired
-   *     surrogates)
-   */
-  static int encodedLength(CharSequence sequence) {
-    // Warning to maintainers: this implementation is highly optimized.
-    int utf16Length = sequence.length();
-    int utf8Length = utf16Length;
-    int i = 0;
-
-    // This loop optimizes for pure ASCII.
-    while (i < utf16Length && sequence.charAt(i) < 0x80) {
-      i++;
-    }
-
-    // This loop optimizes for chars less than 0x800.
-    for (; i < utf16Length; i++) {
-      char c = sequence.charAt(i);
-      if (c < 0x800) {
-        utf8Length += ((0x7f - c) >>> 31); // branch free!
-      } else {
-        utf8Length += encodedLengthGeneral(sequence, i);
-        break;
-      }
-    }
-
-    if (utf8Length < utf16Length) {
-      // Necessary and sufficient condition for overflow because of maximum 3x expansion
-      throw new IllegalArgumentException(
-          "UTF-8 length does not fit in int: " + (utf8Length + (1L << 32)));
-    }
-    return utf8Length;
-  }
-
-  private static int encodedLengthGeneral(CharSequence sequence, int start) {
-    int utf16Length = sequence.length();
-    int utf8Length = 0;
-    for (int i = start; i < utf16Length; i++) {
-      char c = sequence.charAt(i);
-      if (c < 0x800) {
-        utf8Length += (0x7f - c) >>> 31; // branch free!
-      } else {
-        utf8Length += 2;
-        // jdk7+: if (Character.isSurrogate(c)) {
-        if (Character.MIN_SURROGATE <= c && c <= Character.MAX_SURROGATE) {
-          // Check that we have a well-formed surrogate pair.
-          int cp = Character.codePointAt(sequence, i);
-          if (cp < MIN_SUPPLEMENTARY_CODE_POINT) {
-            throw new UnpairedSurrogateException(i, utf16Length);
-          }
-          i++;
-        }
-      }
-    }
-    return utf8Length;
-  }
-
-  static int encode(CharSequence in, byte[] out, int offset, int length) {
-    return processor.encodeUtf8(in, out, offset, length);
-  }
-  // End Guava UTF-8 methods.
-
-  /**
-   * Determines if the given {@link ByteBuffer} is a valid UTF-8 string.
-   *
-   * <p>Selects an optimal algorithm based on the type of {@link ByteBuffer} (i.e. heap or direct)
-   * and the capabilities of the platform.
-   *
-   * @param buffer the buffer to check.
-   * @see Utf8#isValidUtf8(byte[], int, int)
-   */
-  static boolean isValidUtf8(ByteBuffer buffer) {
-    return processor.isValidUtf8(buffer, buffer.position(), buffer.remaining());
-  }
-
-  /**
-   * Determines if the given {@link ByteBuffer} is a partially valid UTF-8 string.
-   *
-   * <p>Selects an optimal algorithm based on the type of {@link ByteBuffer} (i.e. heap or direct)
-   * and the capabilities of the platform.
-   *
-   * @param buffer the buffer to check.
-   * @see Utf8#partialIsValidUtf8(int, byte[], int, int)
-   */
-  static int partialIsValidUtf8(int state, ByteBuffer buffer, int index, int limit) {
-    return processor.partialIsValidUtf8(state, buffer, index, limit);
-  }
-
-  /**
-   * Decodes the given UTF-8 portion of the {@link ByteBuffer} into a {@link String}.
-   *
-   * @throws InvalidProtocolBufferException if the input is not valid UTF-8.
-   */
-  static String decodeUtf8(ByteBuffer buffer, int index, int size)
-      throws InvalidProtocolBufferException {
-    return processor.decodeUtf8(buffer, index, size);
-  }
-
-  /**
-   * Decodes the given UTF-8 encoded byte array slice into a {@link String}.
-   *
-   * @throws InvalidProtocolBufferException if the input is not valid UTF-8.
-   */
-  static String decodeUtf8(byte[] bytes, int index, int size)
-      throws InvalidProtocolBufferException {
-    return processor.decodeUtf8(bytes, index, size);
-  }
-
-  /**
-   * Encodes the given characters to the target {@link ByteBuffer} using UTF-8 encoding.
-   *
-   * <p>Selects an optimal algorithm based on the type of {@link ByteBuffer} (i.e. heap or direct)
-   * and the capabilities of the platform.
-   *
-   * @param in the source string to be encoded
-   * @param out the target buffer to receive the encoded string.
-   * @see Utf8#encode(CharSequence, byte[], int, int)
-   */
-  static void encodeUtf8(CharSequence in, ByteBuffer out) {
-    processor.encodeUtf8(in, out);
-  }
-
-  /**
-   * Counts (approximately) the number of consecutive ASCII characters in the given buffer. The byte
-   * order of the {@link ByteBuffer} does not matter, so performance can be improved if native byte
-   * order is used (i.e. no byte-swapping in {@link ByteBuffer#getLong(int)}).
-   *
-   * @param buffer the buffer to be scanned for ASCII chars
-   * @param index the starting index of the scan
-   * @param limit the limit within buffer for the scan
-   * @return the number of ASCII characters found. The stopping position will be at or before the
-   *     first non-ASCII byte.
-   */
-  private static int estimateConsecutiveAscii(ByteBuffer buffer, int index, int limit) {
-    int i = index;
-    final int lim = limit - 7;
-    // This simple loop stops when we encounter a byte >= 0x80 (i.e. non-ASCII).
-    // To speed things up further, we're reading longs instead of bytes so we use a mask to
-    // determine if any byte in the current long is non-ASCII.
-    for (; i < lim && (buffer.getLong(i) & ASCII_MASK_LONG) == 0; i += 8) {}
-    return i - index;
-  }
-
-  /** A processor of UTF-8 strings, providing methods for checking validity and encoding. */
-  // TODO(nathanmittler): Add support for Memory/MemoryBlock on Android.
-  abstract static class Processor {
-    /**
-     * Returns {@code true} if the given byte array slice is a well-formed UTF-8 byte sequence. The
-     * range of bytes to be checked extends from index {@code index}, inclusive, to {@code limit},
-     * exclusive.
-     *
-     * <p>This is a convenience method, equivalent to {@code partialIsValidUtf8(bytes, index, limit)
-     * == Utf8.COMPLETE}.
-     */
-    final boolean isValidUtf8(byte[] bytes, int index, int limit) {
-      return partialIsValidUtf8(COMPLETE, bytes, index, limit) == COMPLETE;
-    }
-
-    /**
-     * Tells whether the given byte array slice is a well-formed, malformed, or incomplete UTF-8
-     * byte sequence. The range of bytes to be checked extends from index {@code index}, inclusive,
-     * to {@code limit}, exclusive.
-     *
-     * @param state either {@link Utf8#COMPLETE} (if this is the initial decoding operation) or the
-     *     value returned from a call to a partial decoding method for the previous bytes
-     * @return {@link #MALFORMED} if the partial byte sequence is definitely not well-formed, {@link
-     *     #COMPLETE} if it is well-formed (no additional input needed), or if the byte sequence is
-     *     "incomplete", i.e. apparently terminated in the middle of a character, an opaque integer
-     *     "state" value containing enough information to decode the character when passed to a
-     *     subsequent invocation of a partial decoding method.
-     */
-    abstract int partialIsValidUtf8(int state, byte[] bytes, int index, int limit);
-
-    /**
-     * Returns {@code true} if the given portion of the {@link ByteBuffer} is a well-formed UTF-8
-     * byte sequence. The range of bytes to be checked extends from index {@code index}, inclusive,
-     * to {@code limit}, exclusive.
-     *
-     * <p>This is a convenience method, equivalent to {@code partialIsValidUtf8(bytes, index, limit)
-     * == Utf8.COMPLETE}.
-     */
-    final boolean isValidUtf8(ByteBuffer buffer, int index, int limit) {
-      return partialIsValidUtf8(COMPLETE, buffer, index, limit) == COMPLETE;
-    }
-
-    /**
-     * Indicates whether or not the given buffer contains a valid UTF-8 string.
-     *
-     * @param buffer the buffer to check.
-     * @return {@code true} if the given buffer contains a valid UTF-8 string.
-     */
-    final int partialIsValidUtf8(
-        final int state, final ByteBuffer buffer, int index, final int limit) {
-      if (buffer.hasArray()) {
-        final int offset = buffer.arrayOffset();
-        return partialIsValidUtf8(state, buffer.array(), offset + index, offset + limit);
-      } else if (buffer.isDirect()) {
-        return partialIsValidUtf8Direct(state, buffer, index, limit);
-      }
-      return partialIsValidUtf8Default(state, buffer, index, limit);
-    }
-
-    /** Performs validation for direct {@link ByteBuffer} instances. */
-    abstract int partialIsValidUtf8Direct(
-        final int state, final ByteBuffer buffer, int index, final int limit);
-
-    /**
-     * Performs validation for {@link ByteBuffer} instances using the {@link ByteBuffer} API rather
-     * than potentially faster approaches. This first completes validation for the current character
-     * (provided by {@code state}) and then finishes validation for the sequence.
-     */
-    final int partialIsValidUtf8Default(
-        final int state, final ByteBuffer buffer, int index, final int limit) {
-      if (state != COMPLETE) {
-        // The previous decoding operation was incomplete (or malformed).
-        // We look for a well-formed sequence consisting of bytes from
-        // the previous decoding operation (stored in state) together
-        // with bytes from the array slice.
-        //
-        // We expect such "straddler characters" to be rare.
-
-        if (index >= limit) { // No bytes? No progress.
-          return state;
-        }
-
-        byte byte1 = (byte) state;
-        // byte1 is never ASCII.
-        if (byte1 < (byte) 0xE0) {
-          // two-byte form
-
-          // Simultaneously checks for illegal trailing-byte in
-          // leading position and overlong 2-byte form.
-          if (byte1 < (byte) 0xC2
-              // byte2 trailing-byte test
-              || buffer.get(index++) > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        } else if (byte1 < (byte) 0xF0) {
-          // three-byte form
-
-          // Get byte2 from saved state or array
-          byte byte2 = (byte) ~(state >> 8);
-          if (byte2 == 0) {
-            byte2 = buffer.get(index++);
-            if (index >= limit) {
-              return incompleteStateFor(byte1, byte2);
-            }
-          }
-          if (byte2 > (byte) 0xBF
-              // overlong? 5 most significant bits must not all be zero
-              || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0)
-              // illegal surrogate codepoint?
-              || (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0)
-              // byte3 trailing-byte test
-              || buffer.get(index++) > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        } else {
-          // four-byte form
-
-          // Get byte2 and byte3 from saved state or array
-          byte byte2 = (byte) ~(state >> 8);
-          byte byte3 = 0;
-          if (byte2 == 0) {
-            byte2 = buffer.get(index++);
-            if (index >= limit) {
-              return incompleteStateFor(byte1, byte2);
-            }
-          } else {
-            byte3 = (byte) (state >> 16);
-          }
-          if (byte3 == 0) {
-            byte3 = buffer.get(index++);
-            if (index >= limit) {
-              return incompleteStateFor(byte1, byte2, byte3);
-            }
-          }
-
-          // If we were called with state == MALFORMED, then byte1 is 0xFF,
-          // which never occurs in well-formed UTF-8, and so we will return
-          // MALFORMED again below.
-
-          if (byte2 > (byte) 0xBF
-              // Check that 1 <= plane <= 16.  Tricky optimized form of:
-              // if (byte1 > (byte) 0xF4 ||
-              //     byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
-              //     byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
-              || (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0
-              // byte3 trailing-byte test
-              || byte3 > (byte) 0xBF
-              // byte4 trailing-byte test
-              || buffer.get(index++) > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        }
-      }
-
-      // Finish validation for the sequence.
-      return partialIsValidUtf8(buffer, index, limit);
-    }
-
-    /**
-     * Performs validation for {@link ByteBuffer} instances using the {@link ByteBuffer} API rather
-     * than potentially faster approaches.
-     */
-    private static int partialIsValidUtf8(final ByteBuffer buffer, int index, final int limit) {
-      index += estimateConsecutiveAscii(buffer, index, limit);
-
-      for (; ; ) {
-        // Optimize for interior runs of ASCII bytes.
-        // TODO(nathanmittler): Consider checking 8 bytes at a time after some threshold?
-        // Maybe after seeing a few in a row that are ASCII, go back to fast mode?
-        int byte1;
-        do {
-          if (index >= limit) {
-            return COMPLETE;
-          }
-        } while ((byte1 = buffer.get(index++)) >= 0);
-
-        // If we're here byte1 is not ASCII. Only need to handle 2-4 byte forms.
-        if (byte1 < (byte) 0xE0) {
-          // Two-byte form (110xxxxx 10xxxxxx)
-          if (index >= limit) {
-            // Incomplete sequence
-            return byte1;
-          }
-
-          // Simultaneously checks for illegal trailing-byte in
-          // leading position and overlong 2-byte form.
-          if (byte1 < (byte) 0xC2 || buffer.get(index) > (byte) 0xBF) {
-            return MALFORMED;
-          }
-          index++;
-        } else if (byte1 < (byte) 0xF0) {
-          // Three-byte form (1110xxxx 10xxxxxx 10xxxxxx)
-          if (index >= limit - 1) {
-            // Incomplete sequence
-            return incompleteStateFor(buffer, byte1, index, limit - index);
-          }
-
-          final byte byte2 = buffer.get(index++);
-          if (byte2 > (byte) 0xBF
-              // overlong? 5 most significant bits must not all be zero
-              || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0)
-              // check for illegal surrogate codepoints
-              || (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0)
-              // byte3 trailing-byte test
-              || buffer.get(index) > (byte) 0xBF) {
-            return MALFORMED;
-          }
-          index++;
-        } else {
-          // Four-byte form (1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx)
-          if (index >= limit - 2) {
-            // Incomplete sequence
-            return incompleteStateFor(buffer, byte1, index, limit - index);
-          }
-
-          // TODO(nathanmittler): Consider using getInt() to improve performance.
-          final int byte2 = buffer.get(index++);
-          if (byte2 > (byte) 0xBF
-              // Check that 1 <= plane <= 16.  Tricky optimized form of:
-              // if (byte1 > (byte) 0xF4 ||
-              //     byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
-              //     byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
-              || (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0
-              // byte3 trailing-byte test
-              || buffer.get(index++) > (byte) 0xBF
-              // byte4 trailing-byte test
-              || buffer.get(index++) > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        }
-      }
-    }
-
-    /**
-     * Decodes the given byte array slice into a {@link String}.
-     *
-     * @throws InvalidProtocolBufferException if the byte array slice is not valid UTF-8.
-     */
-    abstract String decodeUtf8(byte[] bytes, int index, int size)
-        throws InvalidProtocolBufferException;
-
-    /**
-     * Decodes the given portion of the {@link ByteBuffer} into a {@link String}.
-     *
-     * @throws InvalidProtocolBufferException if the portion of the buffer is not valid UTF-8.
-     */
-    final String decodeUtf8(ByteBuffer buffer, int index, int size)
-        throws InvalidProtocolBufferException {
-      if (buffer.hasArray()) {
-        final int offset = buffer.arrayOffset();
-        return decodeUtf8(buffer.array(), offset + index, size);
-      } else if (buffer.isDirect()) {
-        return decodeUtf8Direct(buffer, index, size);
-      }
-      return decodeUtf8Default(buffer, index, size);
-    }
-
-    /** Decodes direct {@link ByteBuffer} instances into {@link String}. */
-    abstract String decodeUtf8Direct(ByteBuffer buffer, int index, int size)
-        throws InvalidProtocolBufferException;
-
-    /**
-     * Decodes {@link ByteBuffer} instances using the {@link ByteBuffer} API rather than potentially
-     * faster approaches.
-     */
-    final String decodeUtf8Default(ByteBuffer buffer, int index, int size)
-        throws InvalidProtocolBufferException {
-      // Bitwise OR combines the sign bits so any negative value fails the check.
-      if ((index | size | buffer.limit() - index - size) < 0) {
-        throw new ArrayIndexOutOfBoundsException(
-            String.format("buffer limit=%d, index=%d, limit=%d", buffer.limit(), index, size));
-      }
-
-      int offset = index;
-      final int limit = offset + size;
-
-      // The longest possible resulting String is the same as the number of input bytes, when it is
-      // all ASCII. For other cases, this over-allocates and we will truncate in the end.
-      char[] resultArr = new char[size];
-      int resultPos = 0;
-
-      // Optimize for 100% ASCII (Hotspot loves small simple top-level loops like this).
-      // This simple loop stops when we encounter a byte >= 0x80 (i.e. non-ASCII).
-      while (offset < limit) {
-        byte b = buffer.get(offset);
-        if (!DecodeUtil.isOneByte(b)) {
-          break;
-        }
-        offset++;
-        DecodeUtil.handleOneByte(b, resultArr, resultPos++);
-      }
-
-      while (offset < limit) {
-        byte byte1 = buffer.get(offset++);
-        if (DecodeUtil.isOneByte(byte1)) {
-          DecodeUtil.handleOneByte(byte1, resultArr, resultPos++);
-          // It's common for there to be multiple ASCII characters in a run mixed in, so add an
-          // extra optimized loop to take care of these runs.
-          while (offset < limit) {
-            byte b = buffer.get(offset);
-            if (!DecodeUtil.isOneByte(b)) {
-              break;
-            }
-            offset++;
-            DecodeUtil.handleOneByte(b, resultArr, resultPos++);
-          }
-        } else if (DecodeUtil.isTwoBytes(byte1)) {
-          if (offset >= limit) {
-            throw InvalidProtocolBufferException.invalidUtf8();
-          }
-          DecodeUtil.handleTwoBytes(
-              byte1, /* byte2 */ buffer.get(offset++), resultArr, resultPos++);
-        } else if (DecodeUtil.isThreeBytes(byte1)) {
-          if (offset >= limit - 1) {
-            throw InvalidProtocolBufferException.invalidUtf8();
-          }
-          DecodeUtil.handleThreeBytes(
-              byte1,
-              /* byte2 */ buffer.get(offset++),
-              /* byte3 */ buffer.get(offset++),
-              resultArr,
-              resultPos++);
-        } else {
-          if (offset >= limit - 2) {
-            throw InvalidProtocolBufferException.invalidUtf8();
-          }
-          DecodeUtil.handleFourBytes(
-              byte1,
-              /* byte2 */ buffer.get(offset++),
-              /* byte3 */ buffer.get(offset++),
-              /* byte4 */ buffer.get(offset++),
-              resultArr,
-              resultPos++);
-          // 4-byte case requires two chars.
-          resultPos++;
-        }
-      }
-
-      return new String(resultArr, 0, resultPos);
-    }
-
-    /**
-     * Encodes an input character sequence ({@code in}) to UTF-8 in the target array ({@code out}).
-     * For a string, this method is similar to
-     *
-     * <pre>{@code
-     * byte[] a = string.getBytes(UTF_8);
-     * System.arraycopy(a, 0, bytes, offset, a.length);
-     * return offset + a.length;
-     * }</pre>
-     *
-     * but is more efficient in both time and space. One key difference is that this method requires
-     * paired surrogates, and therefore does not support chunking. While {@code
-     * String.getBytes(UTF_8)} replaces unpaired surrogates with the default replacement character,
-     * this method throws {@link UnpairedSurrogateException}.
-     *
-     * <p>To ensure sufficient space in the output buffer, either call {@link #encodedLength} to
-     * compute the exact amount needed, or leave room for {@code Utf8.MAX_BYTES_PER_CHAR *
-     * sequence.length()}, which is the largest possible number of bytes that any input can be
-     * encoded to.
-     *
-     * @param in the input character sequence to be encoded
-     * @param out the target array
-     * @param offset the starting offset in {@code bytes} to start writing at
-     * @param length the length of the {@code bytes}, starting from {@code offset}
-     * @throws UnpairedSurrogateException if {@code sequence} contains ill-formed UTF-16 (unpaired
-     *     surrogates)
-     * @throws ArrayIndexOutOfBoundsException if {@code sequence} encoded in UTF-8 is longer than
-     *     {@code bytes.length - offset}
-     * @return the new offset, equivalent to {@code offset + Utf8.encodedLength(sequence)}
-     */
-    abstract int encodeUtf8(CharSequence in, byte[] out, int offset, int length);
-
-    /**
-     * Encodes an input character sequence ({@code in}) to UTF-8 in the target buffer ({@code out}).
-     * Upon returning from this method, the {@code out} position will point to the position after
-     * the last encoded byte. This method requires paired surrogates, and therefore does not support
-     * chunking.
-     *
-     * <p>To ensure sufficient space in the output buffer, either call {@link #encodedLength} to
-     * compute the exact amount needed, or leave room for {@code Utf8.MAX_BYTES_PER_CHAR *
-     * in.length()}, which is the largest possible number of bytes that any input can be encoded to.
-     *
-     * @param in the source character sequence to be encoded
-     * @param out the target buffer
-     * @throws UnpairedSurrogateException if {@code in} contains ill-formed UTF-16 (unpaired
-     *     surrogates)
-     * @throws ArrayIndexOutOfBoundsException if {@code in} encoded in UTF-8 is longer than {@code
-     *     out.remaining()}
-     */
-    final void encodeUtf8(CharSequence in, ByteBuffer out) {
-      if (out.hasArray()) {
-        final int offset = out.arrayOffset();
-        int endIndex = Utf8.encode(in, out.array(), offset + out.position(), out.remaining());
-        out.position(endIndex - offset);
-      } else if (out.isDirect()) {
-        encodeUtf8Direct(in, out);
-      } else {
-        encodeUtf8Default(in, out);
-      }
-    }
-
-    /** Encodes the input character sequence to a direct {@link ByteBuffer} instance. */
-    abstract void encodeUtf8Direct(CharSequence in, ByteBuffer out);
-
-    /**
-     * Encodes the input character sequence to a {@link ByteBuffer} instance using the {@link
-     * ByteBuffer} API, rather than potentially faster approaches.
-     */
-    final void encodeUtf8Default(CharSequence in, ByteBuffer out) {
-      final int inLength = in.length();
-      int outIx = out.position();
-      int inIx = 0;
-
-      // Since ByteBuffer.putXXX() already checks boundaries for us, no need to explicitly check
-      // access. Assume the buffer is big enough and let it handle the out of bounds exception
-      // if it occurs.
-      try {
-        // Designed to take advantage of
-        // https://wiki.openjdk.java.net/display/HotSpotInternals/RangeCheckElimination
-        for (char c; inIx < inLength && (c = in.charAt(inIx)) < 0x80; ++inIx) {
-          out.put(outIx + inIx, (byte) c);
-        }
-        if (inIx == inLength) {
-          // Successfully encoded the entire string.
-          out.position(outIx + inIx);
-          return;
-        }
-
-        outIx += inIx;
-        for (char c; inIx < inLength; ++inIx, ++outIx) {
-          c = in.charAt(inIx);
-          if (c < 0x80) {
-            // One byte (0xxx xxxx)
-            out.put(outIx, (byte) c);
-          } else if (c < 0x800) {
-            // Two bytes (110x xxxx 10xx xxxx)
-
-            // Benchmarks show put performs better than putShort here (for HotSpot).
-            out.put(outIx++, (byte) (0xC0 | (c >>> 6)));
-            out.put(outIx, (byte) (0x80 | (0x3F & c)));
-          } else if (c < MIN_SURROGATE || MAX_SURROGATE < c) {
-            // Three bytes (1110 xxxx 10xx xxxx 10xx xxxx)
-            // Maximum single-char code point is 0xFFFF, 16 bits.
-
-            // Benchmarks show put performs better than putShort here (for HotSpot).
-            out.put(outIx++, (byte) (0xE0 | (c >>> 12)));
-            out.put(outIx++, (byte) (0x80 | (0x3F & (c >>> 6))));
-            out.put(outIx, (byte) (0x80 | (0x3F & c)));
-          } else {
-            // Four bytes (1111 xxxx 10xx xxxx 10xx xxxx 10xx xxxx)
-
-            // Minimum code point represented by a surrogate pair is 0x10000, 17 bits, four UTF-8
-            // bytes
-            final char low;
-            if (inIx + 1 == inLength || !isSurrogatePair(c, (low = in.charAt(++inIx)))) {
-              throw new UnpairedSurrogateException(inIx, inLength);
-            }
-            // TODO(nathanmittler): Consider using putInt() to improve performance.
-            int codePoint = toCodePoint(c, low);
-            out.put(outIx++, (byte) ((0xF << 4) | (codePoint >>> 18)));
-            out.put(outIx++, (byte) (0x80 | (0x3F & (codePoint >>> 12))));
-            out.put(outIx++, (byte) (0x80 | (0x3F & (codePoint >>> 6))));
-            out.put(outIx, (byte) (0x80 | (0x3F & codePoint)));
-          }
-        }
-
-        // Successfully encoded the entire string.
-        out.position(outIx);
-      } catch (IndexOutOfBoundsException e) {
-        // TODO(nathanmittler): Consider making the API throw IndexOutOfBoundsException instead.
-
-        // If we failed in the outer ASCII loop, outIx will not have been updated. In this case,
-        // use inIx to determine the bad write index.
-        int badWriteIndex = out.position() + Math.max(inIx, outIx - out.position() + 1);
-        throw new ArrayIndexOutOfBoundsException(
-            "Failed writing " + in.charAt(inIx) + " at index " + badWriteIndex);
-      }
-    }
-  }
-
-  /** {@link Processor} implementation that does not use any {@code sun.misc.Unsafe} methods. */
-  static final class SafeProcessor extends Processor {
-    @Override
-    int partialIsValidUtf8(int state, byte[] bytes, int index, int limit) {
-      if (state != COMPLETE) {
-        // The previous decoding operation was incomplete (or malformed).
-        // We look for a well-formed sequence consisting of bytes from
-        // the previous decoding operation (stored in state) together
-        // with bytes from the array slice.
-        //
-        // We expect such "straddler characters" to be rare.
-
-        if (index >= limit) { // No bytes? No progress.
-          return state;
-        }
-        int byte1 = (byte) state;
-        // byte1 is never ASCII.
-        if (byte1 < (byte) 0xE0) {
-          // two-byte form
-
-          // Simultaneously checks for illegal trailing-byte in
-          // leading position and overlong 2-byte form.
-          if (byte1 < (byte) 0xC2
-              // byte2 trailing-byte test
-              || bytes[index++] > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        } else if (byte1 < (byte) 0xF0) {
-          // three-byte form
-
-          // Get byte2 from saved state or array
-          int byte2 = (byte) ~(state >> 8);
-          if (byte2 == 0) {
-            byte2 = bytes[index++];
-            if (index >= limit) {
-              return incompleteStateFor(byte1, byte2);
-            }
-          }
-          if (byte2 > (byte) 0xBF
-              // overlong? 5 most significant bits must not all be zero
-              || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0)
-              // illegal surrogate codepoint?
-              || (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0)
-              // byte3 trailing-byte test
-              || bytes[index++] > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        } else {
-          // four-byte form
-
-          // Get byte2 and byte3 from saved state or array
-          int byte2 = (byte) ~(state >> 8);
-          int byte3 = 0;
-          if (byte2 == 0) {
-            byte2 = bytes[index++];
-            if (index >= limit) {
-              return incompleteStateFor(byte1, byte2);
-            }
-          } else {
-            byte3 = (byte) (state >> 16);
-          }
-          if (byte3 == 0) {
-            byte3 = bytes[index++];
-            if (index >= limit) {
-              return incompleteStateFor(byte1, byte2, byte3);
-            }
-          }
-
-          // If we were called with state == MALFORMED, then byte1 is 0xFF,
-          // which never occurs in well-formed UTF-8, and so we will return
-          // MALFORMED again below.
-
-          if (byte2 > (byte) 0xBF
-              // Check that 1 <= plane <= 16.  Tricky optimized form of:
-              // if (byte1 > (byte) 0xF4 ||
-              //     byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
-              //     byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
-              || (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0
-              // byte3 trailing-byte test
-              || byte3 > (byte) 0xBF
-              // byte4 trailing-byte test
-              || bytes[index++] > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        }
-      }
-
-      return partialIsValidUtf8(bytes, index, limit);
-    }
-
-    @Override
-    int partialIsValidUtf8Direct(int state, ByteBuffer buffer, int index, int limit) {
-      // For safe processing, we have to use the ByteBuffer API.
-      return partialIsValidUtf8Default(state, buffer, index, limit);
-    }
-
-    @Override
-    String decodeUtf8(byte[] bytes, int index, int size) throws InvalidProtocolBufferException {
-      // Bitwise OR combines the sign bits so any negative value fails the check.
-      if ((index | size | bytes.length - index - size) < 0) {
-        throw new ArrayIndexOutOfBoundsException(
-            String.format("buffer length=%d, index=%d, size=%d", bytes.length, index, size));
-      }
-
-      int offset = index;
-      final int limit = offset + size;
-
-      // The longest possible resulting String is the same as the number of input bytes, when it is
-      // all ASCII. For other cases, this over-allocates and we will truncate in the end.
-      char[] resultArr = new char[size];
-      int resultPos = 0;
-
-      // Optimize for 100% ASCII (Hotspot loves small simple top-level loops like this).
-      // This simple loop stops when we encounter a byte >= 0x80 (i.e. non-ASCII).
-      while (offset < limit) {
-        byte b = bytes[offset];
-        if (!DecodeUtil.isOneByte(b)) {
-          break;
-        }
-        offset++;
-        DecodeUtil.handleOneByte(b, resultArr, resultPos++);
-      }
-
-      while (offset < limit) {
-        byte byte1 = bytes[offset++];
-        if (DecodeUtil.isOneByte(byte1)) {
-          DecodeUtil.handleOneByte(byte1, resultArr, resultPos++);
-          // It's common for there to be multiple ASCII characters in a run mixed in, so add an
-          // extra optimized loop to take care of these runs.
-          while (offset < limit) {
-            byte b = bytes[offset];
-            if (!DecodeUtil.isOneByte(b)) {
-              break;
-            }
-            offset++;
-            DecodeUtil.handleOneByte(b, resultArr, resultPos++);
-          }
-        } else if (DecodeUtil.isTwoBytes(byte1)) {
-          if (offset >= limit) {
-            throw InvalidProtocolBufferException.invalidUtf8();
-          }
-          DecodeUtil.handleTwoBytes(byte1, /* byte2 */ bytes[offset++], resultArr, resultPos++);
-        } else if (DecodeUtil.isThreeBytes(byte1)) {
-          if (offset >= limit - 1) {
-            throw InvalidProtocolBufferException.invalidUtf8();
-          }
-          DecodeUtil.handleThreeBytes(
-              byte1,
-              /* byte2 */ bytes[offset++],
-              /* byte3 */ bytes[offset++],
-              resultArr,
-              resultPos++);
-        } else {
-          if (offset >= limit - 2) {
-            throw InvalidProtocolBufferException.invalidUtf8();
-          }
-          DecodeUtil.handleFourBytes(
-              byte1,
-              /* byte2 */ bytes[offset++],
-              /* byte3 */ bytes[offset++],
-              /* byte4 */ bytes[offset++],
-              resultArr,
-              resultPos++);
-          // 4-byte case requires two chars.
-          resultPos++;
-        }
-      }
-
-      return new String(resultArr, 0, resultPos);
-    }
-
-    @Override
-    String decodeUtf8Direct(ByteBuffer buffer, int index, int size)
-        throws InvalidProtocolBufferException {
-      // For safe processing, we have to use the ByteBufferAPI.
-      return decodeUtf8Default(buffer, index, size);
-    }
-
-    @Override
-    int encodeUtf8(CharSequence in, byte[] out, int offset, int length) {
-      int utf16Length = in.length();
-      int j = offset;
-      int i = 0;
-      int limit = offset + length;
-      // Designed to take advantage of
-      // https://wiki.openjdk.java.net/display/HotSpotInternals/RangeCheckElimination
-      for (char c; i < utf16Length && i + j < limit && (c = in.charAt(i)) < 0x80; i++) {
-        out[j + i] = (byte) c;
-      }
-      if (i == utf16Length) {
-        return j + utf16Length;
-      }
-      j += i;
-      for (char c; i < utf16Length; i++) {
-        c = in.charAt(i);
-        if (c < 0x80 && j < limit) {
-          out[j++] = (byte) c;
-        } else if (c < 0x800 && j <= limit - 2) { // 11 bits, two UTF-8 bytes
-          out[j++] = (byte) ((0xF << 6) | (c >>> 6));
-          out[j++] = (byte) (0x80 | (0x3F & c));
-        } else if ((c < Character.MIN_SURROGATE || Character.MAX_SURROGATE < c) && j <= limit - 3) {
-          // Maximum single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
-          out[j++] = (byte) ((0xF << 5) | (c >>> 12));
-          out[j++] = (byte) (0x80 | (0x3F & (c >>> 6)));
-          out[j++] = (byte) (0x80 | (0x3F & c));
-        } else if (j <= limit - 4) {
-          // Minimum code point represented by a surrogate pair is 0x10000, 17 bits,
-          // four UTF-8 bytes
-          final char low;
-          if (i + 1 == in.length() || !Character.isSurrogatePair(c, (low = in.charAt(++i)))) {
-            throw new UnpairedSurrogateException((i - 1), utf16Length);
-          }
-          int codePoint = Character.toCodePoint(c, low);
-          out[j++] = (byte) ((0xF << 4) | (codePoint >>> 18));
-          out[j++] = (byte) (0x80 | (0x3F & (codePoint >>> 12)));
-          out[j++] = (byte) (0x80 | (0x3F & (codePoint >>> 6)));
-          out[j++] = (byte) (0x80 | (0x3F & codePoint));
-        } else {
-          // If we are surrogates and we're not a surrogate pair, always throw an
-          // UnpairedSurrogateException instead of an ArrayOutOfBoundsException.
-          if ((Character.MIN_SURROGATE <= c && c <= Character.MAX_SURROGATE)
-              && (i + 1 == in.length() || !Character.isSurrogatePair(c, in.charAt(i + 1)))) {
-            throw new UnpairedSurrogateException(i, utf16Length);
-          }
-          throw new ArrayIndexOutOfBoundsException("Failed writing " + c + " at index " + j);
-        }
-      }
-      return j;
-    }
-
-    @Override
-    void encodeUtf8Direct(CharSequence in, ByteBuffer out) {
-      // For safe processing, we have to use the ByteBuffer API.
-      encodeUtf8Default(in, out);
-    }
-
-    private static int partialIsValidUtf8(byte[] bytes, int index, int limit) {
-      // Optimize for 100% ASCII (Hotspot loves small simple top-level loops like this).
-      // This simple loop stops when we encounter a byte >= 0x80 (i.e. non-ASCII).
-      while (index < limit && bytes[index] >= 0) {
-        index++;
-      }
-
-      return (index >= limit) ? COMPLETE : partialIsValidUtf8NonAscii(bytes, index, limit);
-    }
-
-    private static int partialIsValidUtf8NonAscii(byte[] bytes, int index, int limit) {
-      for (; ; ) {
-        int byte1;
-        int byte2;
-
-        // Optimize for interior runs of ASCII bytes.
-        do {
-          if (index >= limit) {
-            return COMPLETE;
-          }
-        } while ((byte1 = bytes[index++]) >= 0);
-
-        if (byte1 < (byte) 0xE0) {
-          // two-byte form
-
-          if (index >= limit) {
-            // Incomplete sequence
-            return byte1;
-          }
-
-          // Simultaneously checks for illegal trailing-byte in
-          // leading position and overlong 2-byte form.
-          if (byte1 < (byte) 0xC2 || bytes[index++] > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        } else if (byte1 < (byte) 0xF0) {
-          // three-byte form
-
-          if (index >= limit - 1) { // incomplete sequence
-            return incompleteStateFor(bytes, index, limit);
-          }
-          if ((byte2 = bytes[index++]) > (byte) 0xBF
-              // overlong? 5 most significant bits must not all be zero
-              || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0)
-              // check for illegal surrogate codepoints
-              || (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0)
-              // byte3 trailing-byte test
-              || bytes[index++] > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        } else {
-          // four-byte form
-
-          if (index >= limit - 2) { // incomplete sequence
-            return incompleteStateFor(bytes, index, limit);
-          }
-          if ((byte2 = bytes[index++]) > (byte) 0xBF
-              // Check that 1 <= plane <= 16.  Tricky optimized form of:
-              // if (byte1 > (byte) 0xF4 ||
-              //     byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
-              //     byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
-              || (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0
-              // byte3 trailing-byte test
-              || bytes[index++] > (byte) 0xBF
-              // byte4 trailing-byte test
-              || bytes[index++] > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        }
-      }
-    }
-  }
-
-  /** {@link Processor} that uses {@code sun.misc.Unsafe} where possible to improve performance. */
-  static final class UnsafeProcessor extends Processor {
-    /** Indicates whether or not all required unsafe operations are supported on this platform. */
-    static boolean isAvailable() {
-      return hasUnsafeArrayOperations() && hasUnsafeByteBufferOperations();
-    }
-
-    @Override
-    int partialIsValidUtf8(int state, byte[] bytes, final int index, final int limit) {
-      // Bitwise OR combines the sign bits so any negative value fails the check.
-      if ((index | limit | bytes.length - limit) < 0) {
-        throw new ArrayIndexOutOfBoundsException(
-            String.format("Array length=%d, index=%d, limit=%d", bytes.length, index, limit));
-      }
-      long offset = index;
-      final long offsetLimit = limit;
-      if (state != COMPLETE) {
-        // The previous decoding operation was incomplete (or malformed).
-        // We look for a well-formed sequence consisting of bytes from
-        // the previous decoding operation (stored in state) together
-        // with bytes from the array slice.
-        //
-        // We expect such "straddler characters" to be rare.
-
-        if (offset >= offsetLimit) { // No bytes? No progress.
-          return state;
-        }
-        int byte1 = (byte) state;
-        // byte1 is never ASCII.
-        if (byte1 < (byte) 0xE0) {
-          // two-byte form
-
-          // Simultaneously checks for illegal trailing-byte in
-          // leading position and overlong 2-byte form.
-          if (byte1 < (byte) 0xC2
-              // byte2 trailing-byte test
-              || UnsafeUtil.getByte(bytes, offset++) > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        } else if (byte1 < (byte) 0xF0) {
-          // three-byte form
-
-          // Get byte2 from saved state or array
-          int byte2 = (byte) ~(state >> 8);
-          if (byte2 == 0) {
-            byte2 = UnsafeUtil.getByte(bytes, offset++);
-            if (offset >= offsetLimit) {
-              return incompleteStateFor(byte1, byte2);
-            }
-          }
-          if (byte2 > (byte) 0xBF
-              // overlong? 5 most significant bits must not all be zero
-              || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0)
-              // illegal surrogate codepoint?
-              || (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0)
-              // byte3 trailing-byte test
-              || UnsafeUtil.getByte(bytes, offset++) > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        } else {
-          // four-byte form
-
-          // Get byte2 and byte3 from saved state or array
-          int byte2 = (byte) ~(state >> 8);
-          int byte3 = 0;
-          if (byte2 == 0) {
-            byte2 = UnsafeUtil.getByte(bytes, offset++);
-            if (offset >= offsetLimit) {
-              return incompleteStateFor(byte1, byte2);
-            }
-          } else {
-            byte3 = (byte) (state >> 16);
-          }
-          if (byte3 == 0) {
-            byte3 = UnsafeUtil.getByte(bytes, offset++);
-            if (offset >= offsetLimit) {
-              return incompleteStateFor(byte1, byte2, byte3);
-            }
-          }
-
-          // If we were called with state == MALFORMED, then byte1 is 0xFF,
-          // which never occurs in well-formed UTF-8, and so we will return
-          // MALFORMED again below.
-
-          if (byte2 > (byte) 0xBF
-              // Check that 1 <= plane <= 16.  Tricky optimized form of:
-              // if (byte1 > (byte) 0xF4 ||
-              //     byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
-              //     byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
-              || (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0
-              // byte3 trailing-byte test
-              || byte3 > (byte) 0xBF
-              // byte4 trailing-byte test
-              || UnsafeUtil.getByte(bytes, offset++) > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        }
-      }
-
-      return partialIsValidUtf8(bytes, offset, (int) (offsetLimit - offset));
-    }
-
-    @Override
-    int partialIsValidUtf8Direct(
-        final int state, ByteBuffer buffer, final int index, final int limit) {
-      // Bitwise OR combines the sign bits so any negative value fails the check.
-      if ((index | limit | buffer.limit() - limit) < 0) {
-        throw new ArrayIndexOutOfBoundsException(
-            String.format("buffer limit=%d, index=%d, limit=%d", buffer.limit(), index, limit));
-      }
-      long address = addressOffset(buffer) + index;
-      final long addressLimit = address + (limit - index);
-      if (state != COMPLETE) {
-        // The previous decoding operation was incomplete (or malformed).
-        // We look for a well-formed sequence consisting of bytes from
-        // the previous decoding operation (stored in state) together
-        // with bytes from the array slice.
-        //
-        // We expect such "straddler characters" to be rare.
-
-        if (address >= addressLimit) { // No bytes? No progress.
-          return state;
-        }
-
-        final int byte1 = (byte) state;
-        // byte1 is never ASCII.
-        if (byte1 < (byte) 0xE0) {
-          // two-byte form
-
-          // Simultaneously checks for illegal trailing-byte in
-          // leading position and overlong 2-byte form.
-          if (byte1 < (byte) 0xC2
-              // byte2 trailing-byte test
-              || UnsafeUtil.getByte(address++) > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        } else if (byte1 < (byte) 0xF0) {
-          // three-byte form
-
-          // Get byte2 from saved state or array
-          int byte2 = (byte) ~(state >> 8);
-          if (byte2 == 0) {
-            byte2 = UnsafeUtil.getByte(address++);
-            if (address >= addressLimit) {
-              return incompleteStateFor(byte1, byte2);
-            }
-          }
-          if (byte2 > (byte) 0xBF
-              // overlong? 5 most significant bits must not all be zero
-              || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0)
-              // illegal surrogate codepoint?
-              || (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0)
-              // byte3 trailing-byte test
-              || UnsafeUtil.getByte(address++) > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        } else {
-          // four-byte form
-
-          // Get byte2 and byte3 from saved state or array
-          int byte2 = (byte) ~(state >> 8);
-          int byte3 = 0;
-          if (byte2 == 0) {
-            byte2 = UnsafeUtil.getByte(address++);
-            if (address >= addressLimit) {
-              return incompleteStateFor(byte1, byte2);
-            }
-          } else {
-            byte3 = (byte) (state >> 16);
-          }
-          if (byte3 == 0) {
-            byte3 = UnsafeUtil.getByte(address++);
-            if (address >= addressLimit) {
-              return incompleteStateFor(byte1, byte2, byte3);
-            }
-          }
-
-          // If we were called with state == MALFORMED, then byte1 is 0xFF,
-          // which never occurs in well-formed UTF-8, and so we will return
-          // MALFORMED again below.
-
-          if (byte2 > (byte) 0xBF
-              // Check that 1 <= plane <= 16.  Tricky optimized form of:
-              // if (byte1 > (byte) 0xF4 ||
-              //     byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
-              //     byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
-              || (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0
-              // byte3 trailing-byte test
-              || byte3 > (byte) 0xBF
-              // byte4 trailing-byte test
-              || UnsafeUtil.getByte(address++) > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        }
-      }
-
-      return partialIsValidUtf8(address, (int) (addressLimit - address));
-    }
-
-    @Override
-    String decodeUtf8(byte[] bytes, int index, int size) throws InvalidProtocolBufferException {
-      if ((index | size | bytes.length - index - size) < 0) {
-        throw new ArrayIndexOutOfBoundsException(
-            String.format("buffer length=%d, index=%d, size=%d", bytes.length, index, size));
-      }
-
-      int offset = index;
-      final int limit = offset + size;
-
-      // The longest possible resulting String is the same as the number of input bytes, when it is
-      // all ASCII. For other cases, this over-allocates and we will truncate in the end.
-      char[] resultArr = new char[size];
-      int resultPos = 0;
-
-      // Optimize for 100% ASCII (Hotspot loves small simple top-level loops like this).
-      // This simple loop stops when we encounter a byte >= 0x80 (i.e. non-ASCII).
-      while (offset < limit) {
-        byte b = UnsafeUtil.getByte(bytes, offset);
-        if (!DecodeUtil.isOneByte(b)) {
-          break;
-        }
-        offset++;
-        DecodeUtil.handleOneByte(b, resultArr, resultPos++);
-      }
-
-      while (offset < limit) {
-        byte byte1 = UnsafeUtil.getByte(bytes, offset++);
-        if (DecodeUtil.isOneByte(byte1)) {
-          DecodeUtil.handleOneByte(byte1, resultArr, resultPos++);
-          // It's common for there to be multiple ASCII characters in a run mixed in, so add an
-          // extra optimized loop to take care of these runs.
-          while (offset < limit) {
-            byte b = UnsafeUtil.getByte(bytes, offset);
-            if (!DecodeUtil.isOneByte(b)) {
-              break;
-            }
-            offset++;
-            DecodeUtil.handleOneByte(b, resultArr, resultPos++);
-          }
-        } else if (DecodeUtil.isTwoBytes(byte1)) {
-          if (offset >= limit) {
-            throw InvalidProtocolBufferException.invalidUtf8();
-          }
-          DecodeUtil.handleTwoBytes(
-              byte1, /* byte2 */ UnsafeUtil.getByte(bytes, offset++), resultArr, resultPos++);
-        } else if (DecodeUtil.isThreeBytes(byte1)) {
-          if (offset >= limit - 1) {
-            throw InvalidProtocolBufferException.invalidUtf8();
-          }
-          DecodeUtil.handleThreeBytes(
-              byte1,
-              /* byte2 */ UnsafeUtil.getByte(bytes, offset++),
-              /* byte3 */ UnsafeUtil.getByte(bytes, offset++),
-              resultArr,
-              resultPos++);
-        } else {
-          if (offset >= limit - 2) {
-            throw InvalidProtocolBufferException.invalidUtf8();
-          }
-          DecodeUtil.handleFourBytes(
-              byte1,
-              /* byte2 */ UnsafeUtil.getByte(bytes, offset++),
-              /* byte3 */ UnsafeUtil.getByte(bytes, offset++),
-              /* byte4 */ UnsafeUtil.getByte(bytes, offset++),
-              resultArr,
-              resultPos++);
-          // 4-byte case requires two chars.
-          resultPos++;
-        }
-      }
-
-      return new String(resultArr, 0, resultPos);
-    }
-
-    @Override
-    String decodeUtf8Direct(ByteBuffer buffer, int index, int size)
-        throws InvalidProtocolBufferException {
-      // Bitwise OR combines the sign bits so any negative value fails the check.
-      if ((index | size | buffer.limit() - index - size) < 0) {
-        throw new ArrayIndexOutOfBoundsException(
-            String.format("buffer limit=%d, index=%d, limit=%d", buffer.limit(), index, size));
-      }
-      long address = UnsafeUtil.addressOffset(buffer) + index;
-      final long addressLimit = address + size;
-
-      // The longest possible resulting String is the same as the number of input bytes, when it is
-      // all ASCII. For other cases, this over-allocates and we will truncate in the end.
-      char[] resultArr = new char[size];
-      int resultPos = 0;
-
-      // Optimize for 100% ASCII (Hotspot loves small simple top-level loops like this).
-      // This simple loop stops when we encounter a byte >= 0x80 (i.e. non-ASCII).
-      while (address < addressLimit) {
-        byte b = UnsafeUtil.getByte(address);
-        if (!DecodeUtil.isOneByte(b)) {
-          break;
-        }
-        address++;
-        DecodeUtil.handleOneByte(b, resultArr, resultPos++);
-      }
-
-      while (address < addressLimit) {
-        byte byte1 = UnsafeUtil.getByte(address++);
-        if (DecodeUtil.isOneByte(byte1)) {
-          DecodeUtil.handleOneByte(byte1, resultArr, resultPos++);
-          // It's common for there to be multiple ASCII characters in a run mixed in, so add an
-          // extra optimized loop to take care of these runs.
-          while (address < addressLimit) {
-            byte b = UnsafeUtil.getByte(address);
-            if (!DecodeUtil.isOneByte(b)) {
-              break;
-            }
-            address++;
-            DecodeUtil.handleOneByte(b, resultArr, resultPos++);
-          }
-        } else if (DecodeUtil.isTwoBytes(byte1)) {
-          if (address >= addressLimit) {
-            throw InvalidProtocolBufferException.invalidUtf8();
-          }
-          DecodeUtil.handleTwoBytes(
-              byte1, /* byte2 */ UnsafeUtil.getByte(address++), resultArr, resultPos++);
-        } else if (DecodeUtil.isThreeBytes(byte1)) {
-          if (address >= addressLimit - 1) {
-            throw InvalidProtocolBufferException.invalidUtf8();
-          }
-          DecodeUtil.handleThreeBytes(
-              byte1,
-              /* byte2 */ UnsafeUtil.getByte(address++),
-              /* byte3 */ UnsafeUtil.getByte(address++),
-              resultArr,
-              resultPos++);
-        } else {
-          if (address >= addressLimit - 2) {
-            throw InvalidProtocolBufferException.invalidUtf8();
-          }
-          DecodeUtil.handleFourBytes(
-              byte1,
-              /* byte2 */ UnsafeUtil.getByte(address++),
-              /* byte3 */ UnsafeUtil.getByte(address++),
-              /* byte4 */ UnsafeUtil.getByte(address++),
-              resultArr,
-              resultPos++);
-          // 4-byte case requires two chars.
-          resultPos++;
-        }
-      }
-
-      return new String(resultArr, 0, resultPos);
-    }
-
-    @Override
-    int encodeUtf8(final CharSequence in, final byte[] out, final int offset, final int length) {
-      long outIx = offset;
-      final long outLimit = outIx + length;
-      final int inLimit = in.length();
-      if (inLimit > length || out.length - length < offset) {
-        // Not even enough room for an ASCII-encoded string.
-        throw new ArrayIndexOutOfBoundsException(
-            "Failed writing " + in.charAt(inLimit - 1) + " at index " + (offset + length));
-      }
-
-      // Designed to take advantage of
-      // https://wiki.openjdk.java.net/display/HotSpotInternals/RangeCheckElimination
-      int inIx = 0;
-      for (char c; inIx < inLimit && (c = in.charAt(inIx)) < 0x80; ++inIx) {
-        UnsafeUtil.putByte(out, outIx++, (byte) c);
-      }
-      if (inIx == inLimit) {
-        // We're done, it was ASCII encoded.
-        return (int) outIx;
-      }
-
-      for (char c; inIx < inLimit; ++inIx) {
-        c = in.charAt(inIx);
-        if (c < 0x80 && outIx < outLimit) {
-          UnsafeUtil.putByte(out, outIx++, (byte) c);
-        } else if (c < 0x800 && outIx <= outLimit - 2L) { // 11 bits, two UTF-8 bytes
-          UnsafeUtil.putByte(out, outIx++, (byte) ((0xF << 6) | (c >>> 6)));
-          UnsafeUtil.putByte(out, outIx++, (byte) (0x80 | (0x3F & c)));
-        } else if ((c < MIN_SURROGATE || MAX_SURROGATE < c) && outIx <= outLimit - 3L) {
-          // Maximum single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
-          UnsafeUtil.putByte(out, outIx++, (byte) ((0xF << 5) | (c >>> 12)));
-          UnsafeUtil.putByte(out, outIx++, (byte) (0x80 | (0x3F & (c >>> 6))));
-          UnsafeUtil.putByte(out, outIx++, (byte) (0x80 | (0x3F & c)));
-        } else if (outIx <= outLimit - 4L) {
-          // Minimum code point represented by a surrogate pair is 0x10000, 17 bits, four UTF-8
-          // bytes
-          final char low;
-          if (inIx + 1 == inLimit || !isSurrogatePair(c, (low = in.charAt(++inIx)))) {
-            throw new UnpairedSurrogateException((inIx - 1), inLimit);
-          }
-          int codePoint = toCodePoint(c, low);
-          UnsafeUtil.putByte(out, outIx++, (byte) ((0xF << 4) | (codePoint >>> 18)));
-          UnsafeUtil.putByte(out, outIx++, (byte) (0x80 | (0x3F & (codePoint >>> 12))));
-          UnsafeUtil.putByte(out, outIx++, (byte) (0x80 | (0x3F & (codePoint >>> 6))));
-          UnsafeUtil.putByte(out, outIx++, (byte) (0x80 | (0x3F & codePoint)));
-        } else {
-          if ((MIN_SURROGATE <= c && c <= MAX_SURROGATE)
-              && (inIx + 1 == inLimit || !isSurrogatePair(c, in.charAt(inIx + 1)))) {
-            // We are surrogates and we're not a surrogate pair.
-            throw new UnpairedSurrogateException(inIx, inLimit);
-          }
-          // Not enough space in the output buffer.
-          throw new ArrayIndexOutOfBoundsException("Failed writing " + c + " at index " + outIx);
-        }
-      }
-
-      // All bytes have been encoded.
-      return (int) outIx;
-    }
-
-    @Override
-    void encodeUtf8Direct(CharSequence in, ByteBuffer out) {
-      final long address = addressOffset(out);
-      long outIx = address + out.position();
-      final long outLimit = address + out.limit();
-      final int inLimit = in.length();
-      if (inLimit > outLimit - outIx) {
-        // Not even enough room for an ASCII-encoded string.
-        throw new ArrayIndexOutOfBoundsException(
-            "Failed writing " + in.charAt(inLimit - 1) + " at index " + out.limit());
-      }
-
-      // Designed to take advantage of
-      // https://wiki.openjdk.java.net/display/HotSpotInternals/RangeCheckElimination
-      int inIx = 0;
-      for (char c; inIx < inLimit && (c = in.charAt(inIx)) < 0x80; ++inIx) {
-        UnsafeUtil.putByte(outIx++, (byte) c);
-      }
-      if (inIx == inLimit) {
-        // We're done, it was ASCII encoded.
-        out.position((int) (outIx - address));
-        return;
-      }
-
-      for (char c; inIx < inLimit; ++inIx) {
-        c = in.charAt(inIx);
-        if (c < 0x80 && outIx < outLimit) {
-          UnsafeUtil.putByte(outIx++, (byte) c);
-        } else if (c < 0x800 && outIx <= outLimit - 2L) { // 11 bits, two UTF-8 bytes
-          UnsafeUtil.putByte(outIx++, (byte) ((0xF << 6) | (c >>> 6)));
-          UnsafeUtil.putByte(outIx++, (byte) (0x80 | (0x3F & c)));
-        } else if ((c < MIN_SURROGATE || MAX_SURROGATE < c) && outIx <= outLimit - 3L) {
-          // Maximum single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
-          UnsafeUtil.putByte(outIx++, (byte) ((0xF << 5) | (c >>> 12)));
-          UnsafeUtil.putByte(outIx++, (byte) (0x80 | (0x3F & (c >>> 6))));
-          UnsafeUtil.putByte(outIx++, (byte) (0x80 | (0x3F & c)));
-        } else if (outIx <= outLimit - 4L) {
-          // Minimum code point represented by a surrogate pair is 0x10000, 17 bits, four UTF-8
-          // bytes
-          final char low;
-          if (inIx + 1 == inLimit || !isSurrogatePair(c, (low = in.charAt(++inIx)))) {
-            throw new UnpairedSurrogateException((inIx - 1), inLimit);
-          }
-          int codePoint = toCodePoint(c, low);
-          UnsafeUtil.putByte(outIx++, (byte) ((0xF << 4) | (codePoint >>> 18)));
-          UnsafeUtil.putByte(outIx++, (byte) (0x80 | (0x3F & (codePoint >>> 12))));
-          UnsafeUtil.putByte(outIx++, (byte) (0x80 | (0x3F & (codePoint >>> 6))));
-          UnsafeUtil.putByte(outIx++, (byte) (0x80 | (0x3F & codePoint)));
-        } else {
-          if ((MIN_SURROGATE <= c && c <= MAX_SURROGATE)
-              && (inIx + 1 == inLimit || !isSurrogatePair(c, in.charAt(inIx + 1)))) {
-            // We are surrogates and we're not a surrogate pair.
-            throw new UnpairedSurrogateException(inIx, inLimit);
-          }
-          // Not enough space in the output buffer.
-          throw new ArrayIndexOutOfBoundsException("Failed writing " + c + " at index " + outIx);
-        }
-      }
-
-      // All bytes have been encoded.
-      out.position((int) (outIx - address));
-    }
-
-    /**
-     * Counts (approximately) the number of consecutive ASCII characters starting from the given
-     * position, using the most efficient method available to the platform.
-     *
-     * @param bytes the array containing the character sequence
-     * @param offset the offset position of the index (same as index + arrayBaseOffset)
-     * @param maxChars the maximum number of characters to count
-     * @return the number of ASCII characters found. The stopping position will be at or before the
-     *     first non-ASCII byte.
-     */
-    private static int unsafeEstimateConsecutiveAscii(
-        byte[] bytes, long offset, final int maxChars) {
-      if (maxChars < UNSAFE_COUNT_ASCII_THRESHOLD) {
-        // Don't bother with small strings.
-        return 0;
-      }
-
-      for (int i = 0; i < maxChars; i++) {
-        if (UnsafeUtil.getByte(bytes, offset++) < 0) {
-          return i;
-        }
-      }
-      return maxChars;
-    }
-
-    /**
-     * Same as {@link Utf8#estimateConsecutiveAscii(ByteBuffer, int, int)} except that it uses the
-     * most efficient method available to the platform.
-     */
-    private static int unsafeEstimateConsecutiveAscii(long address, final int maxChars) {
-      int remaining = maxChars;
-      if (remaining < UNSAFE_COUNT_ASCII_THRESHOLD) {
-        // Don't bother with small strings.
-        return 0;
-      }
-
-      // Read bytes until 8-byte aligned so that we can read longs in the loop below.
-      // We do this by ANDing the address with 7 to determine the number of bytes that need to
-      // be read before we're 8-byte aligned.
-      final int unaligned = 8 - ((int) address & 7);
-      for (int j = unaligned; j > 0; j--) {
-        if (UnsafeUtil.getByte(address++) < 0) {
-          return unaligned - j;
-        }
-      }
-
-      // This simple loop stops when we encounter a byte >= 0x80 (i.e. non-ASCII).
-      // To speed things up further, we're reading longs instead of bytes so we use a mask to
-      // determine if any byte in the current long is non-ASCII.
-      remaining -= unaligned;
-      for (;
-          remaining >= 8 && (UnsafeUtil.getLong(address) & ASCII_MASK_LONG) == 0;
-          address += 8, remaining -= 8) {}
-      return maxChars - remaining;
-    }
-
-    private static int partialIsValidUtf8(final byte[] bytes, long offset, int remaining) {
-      // Skip past ASCII characters as quickly as possible.
-      final int skipped = unsafeEstimateConsecutiveAscii(bytes, offset, remaining);
-      remaining -= skipped;
-      offset += skipped;
-
-      for (; ; ) {
-        // Optimize for interior runs of ASCII bytes.
-        // TODO(nathanmittler): Consider checking 8 bytes at a time after some threshold?
-        // Maybe after seeing a few in a row that are ASCII, go back to fast mode?
-        int byte1 = 0;
-        for (; remaining > 0 && (byte1 = UnsafeUtil.getByte(bytes, offset++)) >= 0; --remaining) {}
-        if (remaining == 0) {
-          return COMPLETE;
-        }
-        remaining--;
-
-        // If we're here byte1 is not ASCII. Only need to handle 2-4 byte forms.
-        if (byte1 < (byte) 0xE0) {
-          // Two-byte form (110xxxxx 10xxxxxx)
-          if (remaining == 0) {
-            // Incomplete sequence
-            return byte1;
-          }
-          remaining--;
-
-          // Simultaneously checks for illegal trailing-byte in
-          // leading position and overlong 2-byte form.
-          if (byte1 < (byte) 0xC2 || UnsafeUtil.getByte(bytes, offset++) > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        } else if (byte1 < (byte) 0xF0) {
-          // Three-byte form (1110xxxx 10xxxxxx 10xxxxxx)
-          if (remaining < 2) {
-            // Incomplete sequence
-            return unsafeIncompleteStateFor(bytes, byte1, offset, remaining);
-          }
-          remaining -= 2;
-
-          final int byte2;
-          if ((byte2 = UnsafeUtil.getByte(bytes, offset++)) > (byte) 0xBF
-              // overlong? 5 most significant bits must not all be zero
-              || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0)
-              // check for illegal surrogate codepoints
-              || (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0)
-              // byte3 trailing-byte test
-              || UnsafeUtil.getByte(bytes, offset++) > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        } else {
-          // Four-byte form (1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx)
-          if (remaining < 3) {
-            // Incomplete sequence
-            return unsafeIncompleteStateFor(bytes, byte1, offset, remaining);
-          }
-          remaining -= 3;
-
-          final int byte2;
-          if ((byte2 = UnsafeUtil.getByte(bytes, offset++)) > (byte) 0xBF
-              // Check that 1 <= plane <= 16.  Tricky optimized form of:
-              // if (byte1 > (byte) 0xF4 ||
-              //     byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
-              //     byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
-              || (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0
-              // byte3 trailing-byte test
-              || UnsafeUtil.getByte(bytes, offset++) > (byte) 0xBF
-              // byte4 trailing-byte test
-              || UnsafeUtil.getByte(bytes, offset++) > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        }
-      }
-    }
-
-    private static int partialIsValidUtf8(long address, int remaining) {
-      // Skip past ASCII characters as quickly as possible.
-      final int skipped = unsafeEstimateConsecutiveAscii(address, remaining);
-      address += skipped;
-      remaining -= skipped;
-
-      for (; ; ) {
-        // Optimize for interior runs of ASCII bytes.
-        // TODO(nathanmittler): Consider checking 8 bytes at a time after some threshold?
-        // Maybe after seeing a few in a row that are ASCII, go back to fast mode?
-        int byte1 = 0;
-        for (; remaining > 0 && (byte1 = UnsafeUtil.getByte(address++)) >= 0; --remaining) {}
-        if (remaining == 0) {
-          return COMPLETE;
-        }
-        remaining--;
-
-        if (byte1 < (byte) 0xE0) {
-          // Two-byte form
-
-          if (remaining == 0) {
-            // Incomplete sequence
-            return byte1;
-          }
-          remaining--;
-
-          // Simultaneously checks for illegal trailing-byte in
-          // leading position and overlong 2-byte form.
-          if (byte1 < (byte) 0xC2 || UnsafeUtil.getByte(address++) > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        } else if (byte1 < (byte) 0xF0) {
-          // Three-byte form
-
-          if (remaining < 2) {
-            // Incomplete sequence
-            return unsafeIncompleteStateFor(address, byte1, remaining);
-          }
-          remaining -= 2;
-
-          final byte byte2 = UnsafeUtil.getByte(address++);
-          if (byte2 > (byte) 0xBF
-              // overlong? 5 most significant bits must not all be zero
-              || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0)
-              // check for illegal surrogate codepoints
-              || (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0)
-              // byte3 trailing-byte test
-              || UnsafeUtil.getByte(address++) > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        } else {
-          // Four-byte form
-
-          if (remaining < 3) {
-            // Incomplete sequence
-            return unsafeIncompleteStateFor(address, byte1, remaining);
-          }
-          remaining -= 3;
-
-          final byte byte2 = UnsafeUtil.getByte(address++);
-          if (byte2 > (byte) 0xBF
-              // Check that 1 <= plane <= 16.  Tricky optimized form of:
-              // if (byte1 > (byte) 0xF4 ||
-              //     byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
-              //     byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
-              || (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0
-              // byte3 trailing-byte test
-              || UnsafeUtil.getByte(address++) > (byte) 0xBF
-              // byte4 trailing-byte test
-              || UnsafeUtil.getByte(address++) > (byte) 0xBF) {
-            return MALFORMED;
-          }
-        }
-      }
-    }
-
-    private static int unsafeIncompleteStateFor(
-        byte[] bytes, int byte1, long offset, int remaining) {
-      switch (remaining) {
-        case 0:
-          return incompleteStateFor(byte1);
-        case 1:
-          return incompleteStateFor(byte1, UnsafeUtil.getByte(bytes, offset));
-        case 2:
-          return incompleteStateFor(
-              byte1, UnsafeUtil.getByte(bytes, offset), UnsafeUtil.getByte(bytes, offset + 1));
-        default:
-          throw new AssertionError();
-      }
-    }
-
-    private static int unsafeIncompleteStateFor(long address, final int byte1, int remaining) {
-      switch (remaining) {
-        case 0:
-          return incompleteStateFor(byte1);
-        case 1:
-          return incompleteStateFor(byte1, UnsafeUtil.getByte(address));
-        case 2:
-          return incompleteStateFor(
-              byte1, UnsafeUtil.getByte(address), UnsafeUtil.getByte(address + 1));
-        default:
-          throw new AssertionError();
-      }
-    }
-  }
-
-  /**
-   * Utility methods for decoding bytes into {@link String}. Callers are responsible for extracting
-   * bytes (possibly using Unsafe methods), and checking remaining bytes. All other UTF-8 validity
-   * checks and codepoint conversion happen in this class.
-   */
-  private static class DecodeUtil {
-
-    /** Returns whether this is a single-byte codepoint (i.e., ASCII) with the form '0XXXXXXX'. */
-    private static boolean isOneByte(byte b) {
-      return b >= 0;
-    }
-
-    /** Returns whether this is a two-byte codepoint with the form '10XXXXXX'. */
-    private static boolean isTwoBytes(byte b) {
-      return b < (byte) 0xE0;
-    }
-
-    /** Returns whether this is a three-byte codepoint with the form '110XXXXX'. */
-    private static boolean isThreeBytes(byte b) {
-      return b < (byte) 0xF0;
-    }
-
-    private static void handleOneByte(byte byte1, char[] resultArr, int resultPos) {
-      resultArr[resultPos] = (char) byte1;
-    }
-
-    private static void handleTwoBytes(byte byte1, byte byte2, char[] resultArr, int resultPos)
-        throws InvalidProtocolBufferException {
-      // Simultaneously checks for illegal trailing-byte in leading position (<= '11000000') and
-      // overlong 2-byte, '11000001'.
-      if (byte1 < (byte) 0xC2 || isNotTrailingByte(byte2)) {
-        throw InvalidProtocolBufferException.invalidUtf8();
-      }
-      resultArr[resultPos] = (char) (((byte1 & 0x1F) << 6) | trailingByteValue(byte2));
-    }
-
-    private static void handleThreeBytes(
-        byte byte1, byte byte2, byte byte3, char[] resultArr, int resultPos)
-        throws InvalidProtocolBufferException {
-      if (isNotTrailingByte(byte2)
-          // overlong? 5 most significant bits must not all be zero
-          || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0)
-          // check for illegal surrogate codepoints
-          || (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0)
-          || isNotTrailingByte(byte3)) {
-        throw InvalidProtocolBufferException.invalidUtf8();
-      }
-      resultArr[resultPos] =
-          (char)
-              (((byte1 & 0x0F) << 12) | (trailingByteValue(byte2) << 6) | trailingByteValue(byte3));
-    }
-
-    private static void handleFourBytes(
-        byte byte1, byte byte2, byte byte3, byte byte4, char[] resultArr, int resultPos)
-        throws InvalidProtocolBufferException {
-      if (isNotTrailingByte(byte2)
-          // Check that 1 <= plane <= 16.  Tricky optimized form of:
-          //   valid 4-byte leading byte?
-          // if (byte1 > (byte) 0xF4 ||
-          //   overlong? 4 most significant bits must not all be zero
-          //     byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
-          //   codepoint larger than the highest code point (U+10FFFF)?
-          //     byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
-          || (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0
-          || isNotTrailingByte(byte3)
-          || isNotTrailingByte(byte4)) {
-        throw InvalidProtocolBufferException.invalidUtf8();
-      }
-      int codepoint =
-          ((byte1 & 0x07) << 18)
-              | (trailingByteValue(byte2) << 12)
-              | (trailingByteValue(byte3) << 6)
-              | trailingByteValue(byte4);
-      resultArr[resultPos] = DecodeUtil.highSurrogate(codepoint);
-      resultArr[resultPos + 1] = DecodeUtil.lowSurrogate(codepoint);
-    }
-
-    /** Returns whether the byte is not a valid continuation of the form '10XXXXXX'. */
-    private static boolean isNotTrailingByte(byte b) {
-      return b > (byte) 0xBF;
-    }
-
-    /** Returns the actual value of the trailing byte (removes the prefix '10') for composition. */
-    private static int trailingByteValue(byte b) {
-      return b & 0x3F;
-    }
-
-    private static char highSurrogate(int codePoint) {
-      return (char)
-          ((MIN_HIGH_SURROGATE - (MIN_SUPPLEMENTARY_CODE_POINT >>> 10)) + (codePoint >>> 10));
-    }
-
-    private static char lowSurrogate(int codePoint) {
-      return (char) (MIN_LOW_SURROGATE + (codePoint & 0x3ff));
-    }
-  }
-
-  private Utf8() {}
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Value.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Value.java
deleted file mode 100644
index d1cbc40..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Value.java
+++ /dev/null
@@ -1,1092 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/struct.proto
-
-package com.google.protobuf;
-
-/**
- * <pre>
- * `Value` represents a dynamically typed value which can be either
- * null, a number, a string, a boolean, a recursive struct value, or a
- * list of values. A producer of value is expected to set one of that
- * variants, absence of any variant indicates an error.
- * The JSON representation for `Value` is JSON value.
- * </pre>
- *
- * Protobuf type {@code google.protobuf.Value}
- */
-public  final class Value extends
-    com.google.protobuf.GeneratedMessageLite<
-        Value, Value.Builder> implements
-    // @@protoc_insertion_point(message_implements:google.protobuf.Value)
-    ValueOrBuilder {
-  private Value() {
-  }
-  private int kindCase_ = 0;
-  private java.lang.Object kind_;
-  public enum KindCase {
-    NULL_VALUE(1),
-    NUMBER_VALUE(2),
-    STRING_VALUE(3),
-    BOOL_VALUE(4),
-    STRUCT_VALUE(5),
-    LIST_VALUE(6),
-    KIND_NOT_SET(0);
-    private final int value;
-    private KindCase(int value) {
-      this.value = value;
-    }
-    /**
-     * @deprecated Use {@link #forNumber(int)} instead.
-     */
-    @java.lang.Deprecated
-    public static KindCase valueOf(int value) {
-      return forNumber(value);
-    }
-
-    public static KindCase forNumber(int value) {
-      switch (value) {
-        case 1: return NULL_VALUE;
-        case 2: return NUMBER_VALUE;
-        case 3: return STRING_VALUE;
-        case 4: return BOOL_VALUE;
-        case 5: return STRUCT_VALUE;
-        case 6: return LIST_VALUE;
-        case 0: return KIND_NOT_SET;
-        default: return null;
-      }
-    }
-    public int getNumber() {
-      return this.value;
-    }
-  };
-
-  @java.lang.Override
-  public KindCase
-  getKindCase() {
-    return KindCase.forNumber(
-        kindCase_);
-  }
-
-  private void clearKind() {
-    kindCase_ = 0;
-    kind_ = null;
-  }
-
-  public static final int NULL_VALUE_FIELD_NUMBER = 1;
-  /**
-   * <pre>
-   * Represents a null value.
-   * </pre>
-   *
-   * <code>.google.protobuf.NullValue null_value = 1;</code>
-   * @return Whether the nullValue field is set.
-   */
-  @java.lang.Override
-  public boolean hasNullValue() {
-    return kindCase_ == 1;
-  }
-  /**
-   * <pre>
-   * Represents a null value.
-   * </pre>
-   *
-   * <code>.google.protobuf.NullValue null_value = 1;</code>
-   * @return The enum numeric value on the wire for nullValue.
-   */
-  @java.lang.Override
-  public int getNullValueValue() {
-    if (kindCase_ == 1) {
-      return (java.lang.Integer) kind_;
-    }
-    return 0;
-  }
-  /**
-   * <pre>
-   * Represents a null value.
-   * </pre>
-   *
-   * <code>.google.protobuf.NullValue null_value = 1;</code>
-   * @return The nullValue.
-   */
-  @java.lang.Override
-  public com.google.protobuf.NullValue getNullValue() {
-    if (kindCase_ == 1) {
-      com.google.protobuf.NullValue result = com.google.protobuf.NullValue.forNumber((java.lang.Integer) kind_);
-      return result == null ? com.google.protobuf.NullValue.UNRECOGNIZED : result;
-    }
-    return com.google.protobuf.NullValue.NULL_VALUE;
-  }
-  /**
-   * <pre>
-   * Represents a null value.
-   * </pre>
-   *
-   * <code>.google.protobuf.NullValue null_value = 1;</code>
-   * @param value The enum numeric value on the wire for nullValue to set.
-   */
-  private void setNullValueValue(int value) {
-    kindCase_ = 1;
-    kind_ = value;
-  }
-  /**
-   * <pre>
-   * Represents a null value.
-   * </pre>
-   *
-   * <code>.google.protobuf.NullValue null_value = 1;</code>
-   * @param value The nullValue to set.
-   */
-  private void setNullValue(com.google.protobuf.NullValue value) {
-    kind_ = value.getNumber();
-    kindCase_ = 1;
-  }
-  /**
-   * <pre>
-   * Represents a null value.
-   * </pre>
-   *
-   * <code>.google.protobuf.NullValue null_value = 1;</code>
-   */
-  private void clearNullValue() {
-    if (kindCase_ == 1) {
-      kindCase_ = 0;
-      kind_ = null;
-    }
-  }
-
-  public static final int NUMBER_VALUE_FIELD_NUMBER = 2;
-  /**
-   * <pre>
-   * Represents a double value.
-   * </pre>
-   *
-   * <code>double number_value = 2;</code>
-   * @return Whether the numberValue field is set.
-   */
-  @java.lang.Override
-  public boolean hasNumberValue() {
-    return kindCase_ == 2;
-  }
-  /**
-   * <pre>
-   * Represents a double value.
-   * </pre>
-   *
-   * <code>double number_value = 2;</code>
-   * @return The numberValue.
-   */
-  @java.lang.Override
-  public double getNumberValue() {
-    if (kindCase_ == 2) {
-      return (java.lang.Double) kind_;
-    }
-    return 0D;
-  }
-  /**
-   * <pre>
-   * Represents a double value.
-   * </pre>
-   *
-   * <code>double number_value = 2;</code>
-   * @param value The numberValue to set.
-   */
-  private void setNumberValue(double value) {
-    kindCase_ = 2;
-    kind_ = value;
-  }
-  /**
-   * <pre>
-   * Represents a double value.
-   * </pre>
-   *
-   * <code>double number_value = 2;</code>
-   */
-  private void clearNumberValue() {
-    if (kindCase_ == 2) {
-      kindCase_ = 0;
-      kind_ = null;
-    }
-  }
-
-  public static final int STRING_VALUE_FIELD_NUMBER = 3;
-  /**
-   * <pre>
-   * Represents a string value.
-   * </pre>
-   *
-   * <code>string string_value = 3;</code>
-   * @return Whether the stringValue field is set.
-   */
-  @java.lang.Override
-  public boolean hasStringValue() {
-    return kindCase_ == 3;
-  }
-  /**
-   * <pre>
-   * Represents a string value.
-   * </pre>
-   *
-   * <code>string string_value = 3;</code>
-   * @return The stringValue.
-   */
-  @java.lang.Override
-  public java.lang.String getStringValue() {
-    java.lang.String ref = "";
-    if (kindCase_ == 3) {
-      ref = (java.lang.String) kind_;
-    }
-    return ref;
-  }
-  /**
-   * <pre>
-   * Represents a string value.
-   * </pre>
-   *
-   * <code>string string_value = 3;</code>
-   * @return The bytes for stringValue.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getStringValueBytes() {
-    java.lang.String ref = "";
-    if (kindCase_ == 3) {
-      ref = (java.lang.String) kind_;
-    }
-    return com.google.protobuf.ByteString.copyFromUtf8(ref);
-  }
-  /**
-   * <pre>
-   * Represents a string value.
-   * </pre>
-   *
-   * <code>string string_value = 3;</code>
-   * @param value The stringValue to set.
-   */
-  private void setStringValue(
-      java.lang.String value) {
-    value.getClass();
-  kindCase_ = 3;
-    kind_ = value;
-  }
-  /**
-   * <pre>
-   * Represents a string value.
-   * </pre>
-   *
-   * <code>string string_value = 3;</code>
-   */
-  private void clearStringValue() {
-    if (kindCase_ == 3) {
-      kindCase_ = 0;
-      kind_ = null;
-    }
-  }
-  /**
-   * <pre>
-   * Represents a string value.
-   * </pre>
-   *
-   * <code>string string_value = 3;</code>
-   * @param value The bytes for stringValue to set.
-   */
-  private void setStringValueBytes(
-      com.google.protobuf.ByteString value) {
-    checkByteStringIsUtf8(value);
-    kind_ = value.toStringUtf8();
-    kindCase_ = 3;
-  }
-
-  public static final int BOOL_VALUE_FIELD_NUMBER = 4;
-  /**
-   * <pre>
-   * Represents a boolean value.
-   * </pre>
-   *
-   * <code>bool bool_value = 4;</code>
-   * @return Whether the boolValue field is set.
-   */
-  @java.lang.Override
-  public boolean hasBoolValue() {
-    return kindCase_ == 4;
-  }
-  /**
-   * <pre>
-   * Represents a boolean value.
-   * </pre>
-   *
-   * <code>bool bool_value = 4;</code>
-   * @return The boolValue.
-   */
-  @java.lang.Override
-  public boolean getBoolValue() {
-    if (kindCase_ == 4) {
-      return (java.lang.Boolean) kind_;
-    }
-    return false;
-  }
-  /**
-   * <pre>
-   * Represents a boolean value.
-   * </pre>
-   *
-   * <code>bool bool_value = 4;</code>
-   * @param value The boolValue to set.
-   */
-  private void setBoolValue(boolean value) {
-    kindCase_ = 4;
-    kind_ = value;
-  }
-  /**
-   * <pre>
-   * Represents a boolean value.
-   * </pre>
-   *
-   * <code>bool bool_value = 4;</code>
-   */
-  private void clearBoolValue() {
-    if (kindCase_ == 4) {
-      kindCase_ = 0;
-      kind_ = null;
-    }
-  }
-
-  public static final int STRUCT_VALUE_FIELD_NUMBER = 5;
-  /**
-   * <pre>
-   * Represents a structured value.
-   * </pre>
-   *
-   * <code>.google.protobuf.Struct struct_value = 5;</code>
-   */
-  @java.lang.Override
-  public boolean hasStructValue() {
-    return kindCase_ == 5;
-  }
-  /**
-   * <pre>
-   * Represents a structured value.
-   * </pre>
-   *
-   * <code>.google.protobuf.Struct struct_value = 5;</code>
-   */
-  @java.lang.Override
-  public com.google.protobuf.Struct getStructValue() {
-    if (kindCase_ == 5) {
-       return (com.google.protobuf.Struct) kind_;
-    }
-    return com.google.protobuf.Struct.getDefaultInstance();
-  }
-  /**
-   * <pre>
-   * Represents a structured value.
-   * </pre>
-   *
-   * <code>.google.protobuf.Struct struct_value = 5;</code>
-   */
-  private void setStructValue(com.google.protobuf.Struct value) {
-    value.getClass();
-  kind_ = value;
-    kindCase_ = 5;
-  }
-  /**
-   * <pre>
-   * Represents a structured value.
-   * </pre>
-   *
-   * <code>.google.protobuf.Struct struct_value = 5;</code>
-   */
-  private void mergeStructValue(com.google.protobuf.Struct value) {
-    value.getClass();
-  if (kindCase_ == 5 &&
-        kind_ != com.google.protobuf.Struct.getDefaultInstance()) {
-      kind_ = com.google.protobuf.Struct.newBuilder((com.google.protobuf.Struct) kind_)
-          .mergeFrom(value).buildPartial();
-    } else {
-      kind_ = value;
-    }
-    kindCase_ = 5;
-  }
-  /**
-   * <pre>
-   * Represents a structured value.
-   * </pre>
-   *
-   * <code>.google.protobuf.Struct struct_value = 5;</code>
-   */
-  private void clearStructValue() {
-    if (kindCase_ == 5) {
-      kindCase_ = 0;
-      kind_ = null;
-    }
-  }
-
-  public static final int LIST_VALUE_FIELD_NUMBER = 6;
-  /**
-   * <pre>
-   * Represents a repeated `Value`.
-   * </pre>
-   *
-   * <code>.google.protobuf.ListValue list_value = 6;</code>
-   */
-  @java.lang.Override
-  public boolean hasListValue() {
-    return kindCase_ == 6;
-  }
-  /**
-   * <pre>
-   * Represents a repeated `Value`.
-   * </pre>
-   *
-   * <code>.google.protobuf.ListValue list_value = 6;</code>
-   */
-  @java.lang.Override
-  public com.google.protobuf.ListValue getListValue() {
-    if (kindCase_ == 6) {
-       return (com.google.protobuf.ListValue) kind_;
-    }
-    return com.google.protobuf.ListValue.getDefaultInstance();
-  }
-  /**
-   * <pre>
-   * Represents a repeated `Value`.
-   * </pre>
-   *
-   * <code>.google.protobuf.ListValue list_value = 6;</code>
-   */
-  private void setListValue(com.google.protobuf.ListValue value) {
-    value.getClass();
-  kind_ = value;
-    kindCase_ = 6;
-  }
-  /**
-   * <pre>
-   * Represents a repeated `Value`.
-   * </pre>
-   *
-   * <code>.google.protobuf.ListValue list_value = 6;</code>
-   */
-  private void mergeListValue(com.google.protobuf.ListValue value) {
-    value.getClass();
-  if (kindCase_ == 6 &&
-        kind_ != com.google.protobuf.ListValue.getDefaultInstance()) {
-      kind_ = com.google.protobuf.ListValue.newBuilder((com.google.protobuf.ListValue) kind_)
-          .mergeFrom(value).buildPartial();
-    } else {
-      kind_ = value;
-    }
-    kindCase_ = 6;
-  }
-  /**
-   * <pre>
-   * Represents a repeated `Value`.
-   * </pre>
-   *
-   * <code>.google.protobuf.ListValue list_value = 6;</code>
-   */
-  private void clearListValue() {
-    if (kindCase_ == 6) {
-      kindCase_ = 0;
-      kind_ = null;
-    }
-  }
-
-  public static com.google.protobuf.Value parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Value parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Value parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Value parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Value parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static com.google.protobuf.Value parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static com.google.protobuf.Value parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Value parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Value parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Value parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static com.google.protobuf.Value parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static com.google.protobuf.Value parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(com.google.protobuf.Value prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * <pre>
-   * `Value` represents a dynamically typed value which can be either
-   * null, a number, a string, a boolean, a recursive struct value, or a
-   * list of values. A producer of value is expected to set one of that
-   * variants, absence of any variant indicates an error.
-   * The JSON representation for `Value` is JSON value.
-   * </pre>
-   *
-   * Protobuf type {@code google.protobuf.Value}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        com.google.protobuf.Value, Builder> implements
-      // @@protoc_insertion_point(builder_implements:google.protobuf.Value)
-      com.google.protobuf.ValueOrBuilder {
-    // Construct using com.google.protobuf.Value.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-    @java.lang.Override
-    public KindCase
-        getKindCase() {
-      return instance.getKindCase();
-    }
-
-    public Builder clearKind() {
-      copyOnWrite();
-      instance.clearKind();
-      return this;
-    }
-
-
-    /**
-     * <pre>
-     * Represents a null value.
-     * </pre>
-     *
-     * <code>.google.protobuf.NullValue null_value = 1;</code>
-     * @return Whether the nullValue field is set.
-     */
-    @java.lang.Override
-    public boolean hasNullValue() {
-      return instance.hasNullValue();
-    }
-    /**
-     * <pre>
-     * Represents a null value.
-     * </pre>
-     *
-     * <code>.google.protobuf.NullValue null_value = 1;</code>
-     * @return The enum numeric value on the wire for nullValue.
-     */
-    @java.lang.Override
-    public int getNullValueValue() {
-      return instance.getNullValueValue();
-    }
-    /**
-     * <pre>
-     * Represents a null value.
-     * </pre>
-     *
-     * <code>.google.protobuf.NullValue null_value = 1;</code>
-     * @param value The enum numeric value on the wire for nullValue to set.
-     * @return This builder for chaining.
-     */
-    public Builder setNullValueValue(int value) {
-      copyOnWrite();
-      instance.setNullValueValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Represents a null value.
-     * </pre>
-     *
-     * <code>.google.protobuf.NullValue null_value = 1;</code>
-     * @return The nullValue.
-     */
-    @java.lang.Override
-    public com.google.protobuf.NullValue getNullValue() {
-      return instance.getNullValue();
-    }
-    /**
-     * <pre>
-     * Represents a null value.
-     * </pre>
-     *
-     * <code>.google.protobuf.NullValue null_value = 1;</code>
-     * @param value The nullValue to set.
-     * @return This builder for chaining.
-     */
-    public Builder setNullValue(com.google.protobuf.NullValue value) {
-      copyOnWrite();
-      instance.setNullValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Represents a null value.
-     * </pre>
-     *
-     * <code>.google.protobuf.NullValue null_value = 1;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearNullValue() {
-      copyOnWrite();
-      instance.clearNullValue();
-      return this;
-    }
-
-    /**
-     * <pre>
-     * Represents a double value.
-     * </pre>
-     *
-     * <code>double number_value = 2;</code>
-     * @return Whether the numberValue field is set.
-     */
-    @java.lang.Override
-    public boolean hasNumberValue() {
-      return instance.hasNumberValue();
-    }
-    /**
-     * <pre>
-     * Represents a double value.
-     * </pre>
-     *
-     * <code>double number_value = 2;</code>
-     * @return The numberValue.
-     */
-    @java.lang.Override
-    public double getNumberValue() {
-      return instance.getNumberValue();
-    }
-    /**
-     * <pre>
-     * Represents a double value.
-     * </pre>
-     *
-     * <code>double number_value = 2;</code>
-     * @param value The numberValue to set.
-     * @return This builder for chaining.
-     */
-    public Builder setNumberValue(double value) {
-      copyOnWrite();
-      instance.setNumberValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Represents a double value.
-     * </pre>
-     *
-     * <code>double number_value = 2;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearNumberValue() {
-      copyOnWrite();
-      instance.clearNumberValue();
-      return this;
-    }
-
-    /**
-     * <pre>
-     * Represents a string value.
-     * </pre>
-     *
-     * <code>string string_value = 3;</code>
-     * @return Whether the stringValue field is set.
-     */
-    @java.lang.Override
-    public boolean hasStringValue() {
-      return instance.hasStringValue();
-    }
-    /**
-     * <pre>
-     * Represents a string value.
-     * </pre>
-     *
-     * <code>string string_value = 3;</code>
-     * @return The stringValue.
-     */
-    @java.lang.Override
-    public java.lang.String getStringValue() {
-      return instance.getStringValue();
-    }
-    /**
-     * <pre>
-     * Represents a string value.
-     * </pre>
-     *
-     * <code>string string_value = 3;</code>
-     * @return The bytes for stringValue.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getStringValueBytes() {
-      return instance.getStringValueBytes();
-    }
-    /**
-     * <pre>
-     * Represents a string value.
-     * </pre>
-     *
-     * <code>string string_value = 3;</code>
-     * @param value The stringValue to set.
-     * @return This builder for chaining.
-     */
-    public Builder setStringValue(
-        java.lang.String value) {
-      copyOnWrite();
-      instance.setStringValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Represents a string value.
-     * </pre>
-     *
-     * <code>string string_value = 3;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearStringValue() {
-      copyOnWrite();
-      instance.clearStringValue();
-      return this;
-    }
-    /**
-     * <pre>
-     * Represents a string value.
-     * </pre>
-     *
-     * <code>string string_value = 3;</code>
-     * @param value The bytes for stringValue to set.
-     * @return This builder for chaining.
-     */
-    public Builder setStringValueBytes(
-        com.google.protobuf.ByteString value) {
-      copyOnWrite();
-      instance.setStringValueBytes(value);
-      return this;
-    }
-
-    /**
-     * <pre>
-     * Represents a boolean value.
-     * </pre>
-     *
-     * <code>bool bool_value = 4;</code>
-     * @return Whether the boolValue field is set.
-     */
-    @java.lang.Override
-    public boolean hasBoolValue() {
-      return instance.hasBoolValue();
-    }
-    /**
-     * <pre>
-     * Represents a boolean value.
-     * </pre>
-     *
-     * <code>bool bool_value = 4;</code>
-     * @return The boolValue.
-     */
-    @java.lang.Override
-    public boolean getBoolValue() {
-      return instance.getBoolValue();
-    }
-    /**
-     * <pre>
-     * Represents a boolean value.
-     * </pre>
-     *
-     * <code>bool bool_value = 4;</code>
-     * @param value The boolValue to set.
-     * @return This builder for chaining.
-     */
-    public Builder setBoolValue(boolean value) {
-      copyOnWrite();
-      instance.setBoolValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Represents a boolean value.
-     * </pre>
-     *
-     * <code>bool bool_value = 4;</code>
-     * @return This builder for chaining.
-     */
-    public Builder clearBoolValue() {
-      copyOnWrite();
-      instance.clearBoolValue();
-      return this;
-    }
-
-    /**
-     * <pre>
-     * Represents a structured value.
-     * </pre>
-     *
-     * <code>.google.protobuf.Struct struct_value = 5;</code>
-     */
-    @java.lang.Override
-    public boolean hasStructValue() {
-      return instance.hasStructValue();
-    }
-    /**
-     * <pre>
-     * Represents a structured value.
-     * </pre>
-     *
-     * <code>.google.protobuf.Struct struct_value = 5;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.Struct getStructValue() {
-      return instance.getStructValue();
-    }
-    /**
-     * <pre>
-     * Represents a structured value.
-     * </pre>
-     *
-     * <code>.google.protobuf.Struct struct_value = 5;</code>
-     */
-    public Builder setStructValue(com.google.protobuf.Struct value) {
-      copyOnWrite();
-      instance.setStructValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Represents a structured value.
-     * </pre>
-     *
-     * <code>.google.protobuf.Struct struct_value = 5;</code>
-     */
-    public Builder setStructValue(
-        com.google.protobuf.Struct.Builder builderForValue) {
-      copyOnWrite();
-      instance.setStructValue(builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Represents a structured value.
-     * </pre>
-     *
-     * <code>.google.protobuf.Struct struct_value = 5;</code>
-     */
-    public Builder mergeStructValue(com.google.protobuf.Struct value) {
-      copyOnWrite();
-      instance.mergeStructValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Represents a structured value.
-     * </pre>
-     *
-     * <code>.google.protobuf.Struct struct_value = 5;</code>
-     */
-    public Builder clearStructValue() {
-      copyOnWrite();
-      instance.clearStructValue();
-      return this;
-    }
-
-    /**
-     * <pre>
-     * Represents a repeated `Value`.
-     * </pre>
-     *
-     * <code>.google.protobuf.ListValue list_value = 6;</code>
-     */
-    @java.lang.Override
-    public boolean hasListValue() {
-      return instance.hasListValue();
-    }
-    /**
-     * <pre>
-     * Represents a repeated `Value`.
-     * </pre>
-     *
-     * <code>.google.protobuf.ListValue list_value = 6;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.ListValue getListValue() {
-      return instance.getListValue();
-    }
-    /**
-     * <pre>
-     * Represents a repeated `Value`.
-     * </pre>
-     *
-     * <code>.google.protobuf.ListValue list_value = 6;</code>
-     */
-    public Builder setListValue(com.google.protobuf.ListValue value) {
-      copyOnWrite();
-      instance.setListValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Represents a repeated `Value`.
-     * </pre>
-     *
-     * <code>.google.protobuf.ListValue list_value = 6;</code>
-     */
-    public Builder setListValue(
-        com.google.protobuf.ListValue.Builder builderForValue) {
-      copyOnWrite();
-      instance.setListValue(builderForValue.build());
-      return this;
-    }
-    /**
-     * <pre>
-     * Represents a repeated `Value`.
-     * </pre>
-     *
-     * <code>.google.protobuf.ListValue list_value = 6;</code>
-     */
-    public Builder mergeListValue(com.google.protobuf.ListValue value) {
-      copyOnWrite();
-      instance.mergeListValue(value);
-      return this;
-    }
-    /**
-     * <pre>
-     * Represents a repeated `Value`.
-     * </pre>
-     *
-     * <code>.google.protobuf.ListValue list_value = 6;</code>
-     */
-    public Builder clearListValue() {
-      copyOnWrite();
-      instance.clearListValue();
-      return this;
-    }
-
-    // @@protoc_insertion_point(builder_scope:google.protobuf.Value)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new com.google.protobuf.Value();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = new java.lang.Object[] {
-            "kind_",
-            "kindCase_",
-            com.google.protobuf.Struct.class,
-            com.google.protobuf.ListValue.class,
-          };
-          java.lang.String info =
-              "\u0000\u0006\u0001\u0000\u0001\u0006\u0006\u0000\u0000\u0000\u0001?\u0000\u00023" +
-              "\u0000\u0003\u023b\u0000\u0004:\u0000\u0005<\u0000\u0006<\u0000";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<com.google.protobuf.Value> parser = PARSER;
-        if (parser == null) {
-          synchronized (com.google.protobuf.Value.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<com.google.protobuf.Value>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:google.protobuf.Value)
-  private static final com.google.protobuf.Value DEFAULT_INSTANCE;
-  static {
-    Value defaultInstance = new Value();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      Value.class, defaultInstance);
-  }
-
-  public static com.google.protobuf.Value getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<Value> PARSER;
-
-  public static com.google.protobuf.Parser<Value> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ValueOrBuilder.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/ValueOrBuilder.java
deleted file mode 100644
index 5b1472a..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/ValueOrBuilder.java
+++ /dev/null
@@ -1,144 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/struct.proto
-
-package com.google.protobuf;
-
-public interface ValueOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:google.protobuf.Value)
-    com.google.protobuf.MessageLiteOrBuilder {
-
-  /**
-   * <pre>
-   * Represents a null value.
-   * </pre>
-   *
-   * <code>.google.protobuf.NullValue null_value = 1;</code>
-   * @return Whether the nullValue field is set.
-   */
-  boolean hasNullValue();
-  /**
-   * <pre>
-   * Represents a null value.
-   * </pre>
-   *
-   * <code>.google.protobuf.NullValue null_value = 1;</code>
-   * @return The enum numeric value on the wire for nullValue.
-   */
-  int getNullValueValue();
-  /**
-   * <pre>
-   * Represents a null value.
-   * </pre>
-   *
-   * <code>.google.protobuf.NullValue null_value = 1;</code>
-   * @return The nullValue.
-   */
-  com.google.protobuf.NullValue getNullValue();
-
-  /**
-   * <pre>
-   * Represents a double value.
-   * </pre>
-   *
-   * <code>double number_value = 2;</code>
-   * @return Whether the numberValue field is set.
-   */
-  boolean hasNumberValue();
-  /**
-   * <pre>
-   * Represents a double value.
-   * </pre>
-   *
-   * <code>double number_value = 2;</code>
-   * @return The numberValue.
-   */
-  double getNumberValue();
-
-  /**
-   * <pre>
-   * Represents a string value.
-   * </pre>
-   *
-   * <code>string string_value = 3;</code>
-   * @return Whether the stringValue field is set.
-   */
-  boolean hasStringValue();
-  /**
-   * <pre>
-   * Represents a string value.
-   * </pre>
-   *
-   * <code>string string_value = 3;</code>
-   * @return The stringValue.
-   */
-  java.lang.String getStringValue();
-  /**
-   * <pre>
-   * Represents a string value.
-   * </pre>
-   *
-   * <code>string string_value = 3;</code>
-   * @return The bytes for stringValue.
-   */
-  com.google.protobuf.ByteString
-      getStringValueBytes();
-
-  /**
-   * <pre>
-   * Represents a boolean value.
-   * </pre>
-   *
-   * <code>bool bool_value = 4;</code>
-   * @return Whether the boolValue field is set.
-   */
-  boolean hasBoolValue();
-  /**
-   * <pre>
-   * Represents a boolean value.
-   * </pre>
-   *
-   * <code>bool bool_value = 4;</code>
-   * @return The boolValue.
-   */
-  boolean getBoolValue();
-
-  /**
-   * <pre>
-   * Represents a structured value.
-   * </pre>
-   *
-   * <code>.google.protobuf.Struct struct_value = 5;</code>
-   * @return Whether the structValue field is set.
-   */
-  boolean hasStructValue();
-  /**
-   * <pre>
-   * Represents a structured value.
-   * </pre>
-   *
-   * <code>.google.protobuf.Struct struct_value = 5;</code>
-   * @return The structValue.
-   */
-  com.google.protobuf.Struct getStructValue();
-
-  /**
-   * <pre>
-   * Represents a repeated `Value`.
-   * </pre>
-   *
-   * <code>.google.protobuf.ListValue list_value = 6;</code>
-   * @return Whether the listValue field is set.
-   */
-  boolean hasListValue();
-  /**
-   * <pre>
-   * Represents a repeated `Value`.
-   * </pre>
-   *
-   * <code>.google.protobuf.ListValue list_value = 6;</code>
-   * @return The listValue.
-   */
-  com.google.protobuf.ListValue getListValue();
-
-  public com.google.protobuf.Value.KindCase getKindCase();
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/WireFormat.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/WireFormat.java
deleted file mode 100644
index 3c6e8dd..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/WireFormat.java
+++ /dev/null
@@ -1,271 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.io.IOException;
-
-/**
- * This class is used internally by the Protocol Buffer library and generated message
- * implementations. It is public only because those generated messages do not reside in the {@code
- * protobuf} package. Others should not use this class directly.
- *
- * <p>This class contains constants and helper functions useful for dealing with the Protocol Buffer
- * wire format.
- *
- * @author kenton@google.com Kenton Varda
- */
-public final class WireFormat {
-  // Do not allow instantiation.
-  private WireFormat() {}
-
-  static final int FIXED32_SIZE = 4;
-  static final int FIXED64_SIZE = 8;
-  static final int MAX_VARINT32_SIZE = 5;
-  static final int MAX_VARINT64_SIZE = 10;
-  static final int MAX_VARINT_SIZE = 10;
-
-  public static final int WIRETYPE_VARINT = 0;
-  public static final int WIRETYPE_FIXED64 = 1;
-  public static final int WIRETYPE_LENGTH_DELIMITED = 2;
-  public static final int WIRETYPE_START_GROUP = 3;
-  public static final int WIRETYPE_END_GROUP = 4;
-  public static final int WIRETYPE_FIXED32 = 5;
-
-  static final int TAG_TYPE_BITS = 3;
-  static final int TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1;
-
-  /** Given a tag value, determines the wire type (the lower 3 bits). */
-  public static int getTagWireType(final int tag) {
-    return tag & TAG_TYPE_MASK;
-  }
-
-  /** Given a tag value, determines the field number (the upper 29 bits). */
-  public static int getTagFieldNumber(final int tag) {
-    return tag >>> TAG_TYPE_BITS;
-  }
-
-  /** Makes a tag value given a field number and wire type. */
-  static int makeTag(final int fieldNumber, final int wireType) {
-    return (fieldNumber << TAG_TYPE_BITS) | wireType;
-  }
-
-  /**
-   * Lite equivalent to {@link Descriptors.FieldDescriptor.JavaType}. This is only here to support
-   * the lite runtime and should not be used by users.
-   */
-  public enum JavaType {
-    INT(0),
-    LONG(0L),
-    FLOAT(0F),
-    DOUBLE(0D),
-    BOOLEAN(false),
-    STRING(""),
-    BYTE_STRING(ByteString.EMPTY),
-    ENUM(null),
-    MESSAGE(null);
-
-    JavaType(final Object defaultDefault) {
-      this.defaultDefault = defaultDefault;
-    }
-
-    /** The default default value for fields of this type, if it's a primitive type. */
-    Object getDefaultDefault() {
-      return defaultDefault;
-    }
-
-    private final Object defaultDefault;
-  }
-
-  /**
-   * Lite equivalent to {@link Descriptors.FieldDescriptor.Type}. This is only here to support the
-   * lite runtime and should not be used by users.
-   */
-  public enum FieldType {
-    DOUBLE(JavaType.DOUBLE, WIRETYPE_FIXED64),
-    FLOAT(JavaType.FLOAT, WIRETYPE_FIXED32),
-    INT64(JavaType.LONG, WIRETYPE_VARINT),
-    UINT64(JavaType.LONG, WIRETYPE_VARINT),
-    INT32(JavaType.INT, WIRETYPE_VARINT),
-    FIXED64(JavaType.LONG, WIRETYPE_FIXED64),
-    FIXED32(JavaType.INT, WIRETYPE_FIXED32),
-    BOOL(JavaType.BOOLEAN, WIRETYPE_VARINT),
-    STRING(JavaType.STRING, WIRETYPE_LENGTH_DELIMITED) {
-      @Override
-      public boolean isPackable() {
-        return false;
-      }
-    },
-    GROUP(JavaType.MESSAGE, WIRETYPE_START_GROUP) {
-      @Override
-      public boolean isPackable() {
-        return false;
-      }
-    },
-    MESSAGE(JavaType.MESSAGE, WIRETYPE_LENGTH_DELIMITED) {
-      @Override
-      public boolean isPackable() {
-        return false;
-      }
-    },
-    BYTES(JavaType.BYTE_STRING, WIRETYPE_LENGTH_DELIMITED) {
-      @Override
-      public boolean isPackable() {
-        return false;
-      }
-    },
-    UINT32(JavaType.INT, WIRETYPE_VARINT),
-    ENUM(JavaType.ENUM, WIRETYPE_VARINT),
-    SFIXED32(JavaType.INT, WIRETYPE_FIXED32),
-    SFIXED64(JavaType.LONG, WIRETYPE_FIXED64),
-    SINT32(JavaType.INT, WIRETYPE_VARINT),
-    SINT64(JavaType.LONG, WIRETYPE_VARINT);
-
-    FieldType(final JavaType javaType, final int wireType) {
-      this.javaType = javaType;
-      this.wireType = wireType;
-    }
-
-    private final JavaType javaType;
-    private final int wireType;
-
-    public JavaType getJavaType() {
-      return javaType;
-    }
-
-    public int getWireType() {
-      return wireType;
-    }
-
-    public boolean isPackable() {
-      return true;
-    }
-  }
-
-  // Field numbers for fields in MessageSet wire format.
-  static final int MESSAGE_SET_ITEM = 1;
-  static final int MESSAGE_SET_TYPE_ID = 2;
-  static final int MESSAGE_SET_MESSAGE = 3;
-
-  // Tag numbers.
-  static final int MESSAGE_SET_ITEM_TAG = makeTag(MESSAGE_SET_ITEM, WIRETYPE_START_GROUP);
-  static final int MESSAGE_SET_ITEM_END_TAG = makeTag(MESSAGE_SET_ITEM, WIRETYPE_END_GROUP);
-  static final int MESSAGE_SET_TYPE_ID_TAG = makeTag(MESSAGE_SET_TYPE_ID, WIRETYPE_VARINT);
-  static final int MESSAGE_SET_MESSAGE_TAG =
-      makeTag(MESSAGE_SET_MESSAGE, WIRETYPE_LENGTH_DELIMITED);
-
-  /**
-   * Validation level for handling incoming string field data which potentially contain non-UTF8
-   * bytes.
-   */
-  enum Utf8Validation {
-    /** Eagerly parses to String; silently accepts invalid UTF8 bytes. */
-    LOOSE {
-      @Override
-      Object readString(CodedInputStream input) throws IOException {
-        return input.readString();
-      }
-    },
-    /** Eagerly parses to String; throws an IOException on invalid bytes. */
-    STRICT {
-      @Override
-      Object readString(CodedInputStream input) throws IOException {
-        return input.readStringRequireUtf8();
-      }
-    },
-    /** Keep data as ByteString; validation/conversion to String is lazy. */
-    LAZY {
-      @Override
-      Object readString(CodedInputStream input) throws IOException {
-        return input.readBytes();
-      }
-    };
-
-    /** Read a string field from the input with the proper UTF8 validation. */
-    abstract Object readString(CodedInputStream input) throws IOException;
-  }
-
-  /**
-   * Read a field of any primitive type for immutable messages from a CodedInputStream. Enums,
-   * groups, and embedded messages are not handled by this method.
-   *
-   * @param input The stream from which to read.
-   * @param type Declared type of the field.
-   * @param utf8Validation Different string UTF8 validation level for handling string fields.
-   * @return An object representing the field's value, of the exact type which would be returned by
-   *     {@link Message#getField(Descriptors.FieldDescriptor)} for this field.
-   */
-  static Object readPrimitiveField(
-      CodedInputStream input, FieldType type, Utf8Validation utf8Validation) throws IOException {
-    switch (type) {
-      case DOUBLE:
-        return input.readDouble();
-      case FLOAT:
-        return input.readFloat();
-      case INT64:
-        return input.readInt64();
-      case UINT64:
-        return input.readUInt64();
-      case INT32:
-        return input.readInt32();
-      case FIXED64:
-        return input.readFixed64();
-      case FIXED32:
-        return input.readFixed32();
-      case BOOL:
-        return input.readBool();
-      case BYTES:
-        return input.readBytes();
-      case UINT32:
-        return input.readUInt32();
-      case SFIXED32:
-        return input.readSFixed32();
-      case SFIXED64:
-        return input.readSFixed64();
-      case SINT32:
-        return input.readSInt32();
-      case SINT64:
-        return input.readSInt64();
-
-      case STRING:
-        return utf8Validation.readString(input);
-      case GROUP:
-        throw new IllegalArgumentException("readPrimitiveField() cannot handle nested groups.");
-      case MESSAGE:
-        throw new IllegalArgumentException("readPrimitiveField() cannot handle embedded messages.");
-      case ENUM:
-        // We don't handle enums because we don't know what to do if the
-        // value is not recognized.
-        throw new IllegalArgumentException("readPrimitiveField() cannot handle enums.");
-    }
-
-    throw new RuntimeException("There is no way to get here, but the compiler thinks otherwise.");
-  }
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/WrappersProto.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/WrappersProto.java
deleted file mode 100644
index c0109fe..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/WrappersProto.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/wrappers.proto
-
-package com.google.protobuf;
-
-public final class WrappersProto {
-  private WrappersProto() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Writer.java b/java/kotlin-lite/target/generated-sources/com/google/protobuf/Writer.java
deleted file mode 100644
index 3f95c32..0000000
--- a/java/kotlin-lite/target/generated-sources/com/google/protobuf/Writer.java
+++ /dev/null
@@ -1,219 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-
-/** A writer that performs serialization of protobuf message fields. */
-@ExperimentalApi
-interface Writer {
-
-  /** The order in which the fields are written by a {@link Writer}. */
-  enum FieldOrder {
-    /** Fields are written in ascending order by field number. */
-    ASCENDING,
-
-    /** Fields are written in descending order by field number. */
-    DESCENDING
-  }
-
-  /** Indicates the order in which the fields are written by this {@link Writer}. */
-  FieldOrder fieldOrder();
-
-  /** Writes a field of type {@link FieldType#SFIXED32}. */
-  void writeSFixed32(int fieldNumber, int value) throws IOException;
-
-  /** Writes a field of type {@link FieldType#INT64}. */
-  void writeInt64(int fieldNumber, long value) throws IOException;
-
-  /** Writes a field of type {@link FieldType#SFIXED64}. */
-  void writeSFixed64(int fieldNumber, long value) throws IOException;
-
-  /** Writes a field of type {@link FieldType#FLOAT}. */
-  void writeFloat(int fieldNumber, float value) throws IOException;
-
-  /** Writes a field of type {@link FieldType#DOUBLE}. */
-  void writeDouble(int fieldNumber, double value) throws IOException;
-
-  /** Writes a field of type {@link FieldType#ENUM}. */
-  void writeEnum(int fieldNumber, int value) throws IOException;
-
-  /** Writes a field of type {@link FieldType#UINT64}. */
-  void writeUInt64(int fieldNumber, long value) throws IOException;
-
-  /** Writes a field of type {@link FieldType#INT32}. */
-  void writeInt32(int fieldNumber, int value) throws IOException;
-
-  /** Writes a field of type {@link FieldType#FIXED64}. */
-  void writeFixed64(int fieldNumber, long value) throws IOException;
-
-  /** Writes a field of type {@link FieldType#FIXED32}. */
-  void writeFixed32(int fieldNumber, int value) throws IOException;
-
-  /** Writes a field of type {@link FieldType#BOOL}. */
-  void writeBool(int fieldNumber, boolean value) throws IOException;
-
-  /** Writes a field of type {@link FieldType#STRING}. */
-  void writeString(int fieldNumber, String value) throws IOException;
-
-  /** Writes a field of type {@link FieldType#BYTES}. */
-  void writeBytes(int fieldNumber, ByteString value) throws IOException;
-
-  /** Writes a field of type {@link FieldType#UINT32}. */
-  void writeUInt32(int fieldNumber, int value) throws IOException;
-
-  /** Writes a field of type {@link FieldType#SINT32}. */
-  void writeSInt32(int fieldNumber, int value) throws IOException;
-
-  /** Writes a field of type {@link FieldType#SINT64}. */
-  void writeSInt64(int fieldNumber, long value) throws IOException;
-
-  /** Writes a field of type {@link FieldType#MESSAGE}. */
-  void writeMessage(int fieldNumber, Object value) throws IOException;
-
-  /** Writes a field of type {@link FieldType#MESSAGE}. */
-  void writeMessage(int fieldNumber, Object value, Schema schema) throws IOException;
-
-  /**
-   * Writes a field of type {@link FieldType#GROUP}.
-   *
-   * @deprecated groups fields are deprecated.
-   */
-  @Deprecated
-  void writeGroup(int fieldNumber, Object value) throws IOException;
-
-  /**
-   * Writes a field of type {@link FieldType#GROUP}.
-   *
-   * @deprecated groups fields are deprecated.
-   */
-  @Deprecated
-  void writeGroup(int fieldNumber, Object value, Schema schema) throws IOException;
-
-  /**
-   * Writes a single start group tag.
-   *
-   * @deprecated groups fields are deprecated.
-   */
-  @Deprecated
-  void writeStartGroup(int fieldNumber) throws IOException;
-
-  /**
-   * Writes a single end group tag.
-   *
-   * @deprecated groups fields are deprecated.
-   */
-  @Deprecated
-  void writeEndGroup(int fieldNumber) throws IOException;
-
-  /** Writes a list field of type {@link FieldType#INT32}. */
-  void writeInt32List(int fieldNumber, List<Integer> value, boolean packed) throws IOException;
-
-  /** Writes a list field of type {@link FieldType#FIXED32}. */
-  void writeFixed32List(int fieldNumber, List<Integer> value, boolean packed) throws IOException;
-
-  /** Writes a list field of type {@link FieldType#INT64}. */
-  void writeInt64List(int fieldNumber, List<Long> value, boolean packed) throws IOException;
-
-  /** Writes a list field of type {@link FieldType#UINT64}. */
-  void writeUInt64List(int fieldNumber, List<Long> value, boolean packed) throws IOException;
-
-  /** Writes a list field of type {@link FieldType#FIXED64}. */
-  void writeFixed64List(int fieldNumber, List<Long> value, boolean packed) throws IOException;
-
-  /** Writes a list field of type {@link FieldType#FLOAT}. */
-  void writeFloatList(int fieldNumber, List<Float> value, boolean packed) throws IOException;
-
-  /** Writes a list field of type {@link FieldType#DOUBLE}. */
-  void writeDoubleList(int fieldNumber, List<Double> value, boolean packed) throws IOException;
-
-  /** Writes a list field of type {@link FieldType#ENUM}. */
-  void writeEnumList(int fieldNumber, List<Integer> value, boolean packed) throws IOException;
-
-  /** Writes a list field of type {@link FieldType#BOOL}. */
-  void writeBoolList(int fieldNumber, List<Boolean> value, boolean packed) throws IOException;
-
-  /** Writes a list field of type {@link FieldType#STRING}. */
-  void writeStringList(int fieldNumber, List<String> value) throws IOException;
-
-  /** Writes a list field of type {@link FieldType#BYTES}. */
-  void writeBytesList(int fieldNumber, List<ByteString> value) throws IOException;
-
-  /** Writes a list field of type {@link FieldType#UINT32}. */
-  void writeUInt32List(int fieldNumber, List<Integer> value, boolean packed) throws IOException;
-
-  /** Writes a list field of type {@link FieldType#SFIXED32}. */
-  void writeSFixed32List(int fieldNumber, List<Integer> value, boolean packed) throws IOException;
-
-  /** Writes a list field of type {@link FieldType#SFIXED64}. */
-  void writeSFixed64List(int fieldNumber, List<Long> value, boolean packed) throws IOException;
-
-  /** Writes a list field of type {@link FieldType#SINT32}. */
-  void writeSInt32List(int fieldNumber, List<Integer> value, boolean packed) throws IOException;
-
-  /** Writes a list field of type {@link FieldType#SINT64}. */
-  void writeSInt64List(int fieldNumber, List<Long> value, boolean packed) throws IOException;
-
-  /** Writes a list field of type {@link FieldType#MESSAGE}. */
-  void writeMessageList(int fieldNumber, List<?> value) throws IOException;
-
-  /** Writes a list field of type {@link FieldType#MESSAGE}. */
-  void writeMessageList(int fieldNumber, List<?> value, Schema schema) throws IOException;
-
-  /**
-   * Writes a list field of type {@link FieldType#GROUP}.
-   *
-   * @deprecated groups fields are deprecated.
-   */
-  @Deprecated
-  void writeGroupList(int fieldNumber, List<?> value) throws IOException;
-
-  /**
-   * Writes a list field of type {@link FieldType#GROUP}.
-   *
-   * @deprecated groups fields are deprecated.
-   */
-  @Deprecated
-  void writeGroupList(int fieldNumber, List<?> value, Schema schema) throws IOException;
-
-  /**
-   * Writes a message field in {@code MessageSet} wire-format.
-   *
-   * @param value A message instance or an opaque {@link ByteString} for an unknown field.
-   */
-  void writeMessageSetItem(int fieldNumber, Object value) throws IOException;
-
-  /** Writes a map field. */
-  <K, V> void writeMap(int fieldNumber, MapEntryLite.Metadata<K, V> metadata, Map<K, V> map)
-      throws IOException;
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/DslListTest.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/DslListTest.kt
deleted file mode 100644
index e5e6017..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/DslListTest.kt
+++ /dev/null
@@ -1,98 +0,0 @@
-package com.google.protobuf.kotlin
-
-import com.google.common.testing.EqualsTester
-import com.google.common.truth.Truth.assertThat
-import kotlin.test.assertFailsWith
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-/** Tests for [DslList]. */
-@RunWith(JUnit4::class)
-@OptIn(OnlyForUseByGeneratedProtoCode::class)
-class DslListTest {
-  class DummyProxy private constructor() : DslProxy()
-
-  @Test
-  fun matchesList() {
-    assertThat(DslList<Int, DummyProxy>(listOf(1, 2, 3))).containsExactly(1, 2, 3).inOrder()
-  }
-
-  @Test
-  fun reflectsChangesInList() {
-    val mutableList = mutableListOf(1, 2, 3)
-    val dslList = DslList<Int, DummyProxy>(mutableList)
-    mutableList.add(4)
-    assertThat(dslList).containsExactly(1, 2, 3, 4).inOrder()
-  }
-
-  @Test
-  fun dslListIsNotMutable() {
-    val dslList = DslList<Int, DummyProxy>(mutableListOf(1, 2, 3))
-    assertThat(dslList is MutableList<*>).isFalse()
-  }
-
-  @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
-  @Test
-  fun dslListIsNotEvenSecretlyMutable() {
-    val dslList = DslList<Int, DummyProxy>(mutableListOf(1, 2, 3))
-    val dslListAsJavaUtil = dslList as java.util.List<Int>
-    assertFailsWith<UnsupportedOperationException> {
-      dslListAsJavaUtil.add(4)
-    }
-  }
-
-  @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
-  @Test
-  fun dslList_IteratorIsNotEvenSecretlyMutable() {
-    val dslList = DslList<Int, DummyProxy>(mutableListOf(1, 2, 3))
-    val iterator = dslList.iterator() as java.util.Iterator<Int>
-    iterator.next()
-
-    assertFailsWith<UnsupportedOperationException> {
-      iterator.remove()
-    }
-  }
-
-  @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
-  @Test
-  fun dslList_ListIteratorIsNotEvenSecretlyMutable() {
-    val dslList = DslList<Int, DummyProxy>(mutableListOf(1, 2, 3))
-    val iterator = dslList.listIterator() as java.util.ListIterator<Int>
-    iterator.next()
-
-    assertFailsWith<UnsupportedOperationException> {
-      iterator.remove()
-    }
-  }
-
-  @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
-  @Test
-  fun dslList_ListIteratorIndexIsNotEvenSecretlyMutable() {
-    val dslList = DslList<Int, DummyProxy>(mutableListOf(1, 2, 3))
-    val iterator = dslList.listIterator(1) as java.util.ListIterator<Int>
-    iterator.next()
-
-    assertFailsWith<UnsupportedOperationException> {
-      iterator.remove()
-    }
-  }
-
-  @Test
-  fun expectedToString() {
-    assertThat(DslList<Int, DummyProxy>(listOf(1, 2)).toString()).isEqualTo("[1, 2]")
-  }
-
-  @Test
-  fun equality() {
-    EqualsTester()
-      .addEqualityGroup(DslList<Int, DummyProxy>(listOf(1, 2)), listOf(1, 2))
-      .addEqualityGroup(DslList<Int, DummyProxy>(listOf(2, 2)), listOf(2, 2))
-      .addEqualityGroup(
-        DslList<Int, DummyProxy>(emptyList()),
-        DslList<String, DummyProxy>(emptyList()),
-        emptyList<Int>()
-      )
-      .testEquals()
-  }
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/DslMapTest.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/DslMapTest.kt
deleted file mode 100644
index 470e42e..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/DslMapTest.kt
+++ /dev/null
@@ -1,164 +0,0 @@
-package com.google.protobuf.kotlin
-
-import com.google.common.testing.EqualsTester
-import com.google.common.truth.Truth.assertThat
-import kotlin.test.assertFailsWith
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@RunWith(JUnit4::class)
-@OptIn(OnlyForUseByGeneratedProtoCode::class)
-class DslMapTest {
-  class DummyProxy private constructor() : DslProxy()
-
-  @Test
-  fun matchesMap() {
-    assertThat(DslMap<Int, Int, DummyProxy>(mapOf(1 to -1, 2 to -2)))
-      .containsExactly(1, -1, 2, -2)
-  }
-
-  @Test
-  fun reflectsChangesInMap() {
-    val mutableMap = mutableMapOf(1 to -1, 2 to -2)
-    val dslMap = DslMap<Int, Int, DummyProxy>(mutableMap)
-    mutableMap[3] = -3
-    assertThat(dslMap).containsExactly(1, -1, 2, -2, 3, -3).inOrder()
-  }
-
-  @Test
-  fun dslMapIsNotMutable() {
-    val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1))
-    assertThat(dslMap is MutableMap<*, *>).isFalse()
-  }
-
-  @Test
-  fun dslMapKeysAreNotMutable() {
-    val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1))
-    assertThat(dslMap.keys is MutableSet<*>).isFalse()
-  }
-
-  @Test
-  fun dslMapValuesAreNotMutable() {
-    val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1))
-    assertThat(dslMap.values is MutableSet<*>).isFalse()
-  }
-
-  @Test
-  fun dslMapEntriesAreNotMutable() {
-    val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1))
-    assertThat(dslMap.entries is MutableSet<*>).isFalse()
-  }
-
-  @Test
-  fun dslMapEntryObjectsAreNotMutable() {
-    val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1))
-    assertThat(dslMap.entries.single() is MutableMap.MutableEntry<*, *>).isFalse()
-  }
-
-  @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
-  @Test
-  fun dslMapIsNotEvenSecretlyMutable() {
-    val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1))
-    val dslMapAsJavaUtilMap = dslMap as java.util.Map<Int, Int>
-    assertFailsWith<UnsupportedOperationException> {
-      dslMapAsJavaUtilMap.put(2, -2)
-    }
-  }
-
-  @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
-  @Test
-  fun dslMapKeysAreNotEvenSecretlyMutable() {
-    val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1))
-    val dslMapKeysAsJavaUtilSet = dslMap.keys as java.util.Set<Int>
-    assertFailsWith<UnsupportedOperationException> {
-      dslMapKeysAsJavaUtilSet.remove(1)
-    }
-  }
-
-  @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
-  @Test
-  fun dslMapKeysIteratorIsNotEvenSecretlyMutable() {
-    val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1))
-    val dslMapKeysAsJavaUtilSet = dslMap.keys as java.util.Set<Int>
-    val itr = dslMapKeysAsJavaUtilSet.iterator()
-    itr.next()
-    assertFailsWith<UnsupportedOperationException> {
-      itr.remove()
-    }
-  }
-
-  @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
-  @Test
-  fun dslMapValuesAreNotEvenSecretlyMutable() {
-    val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1))
-    val dslMapValuesAsJavaUtilCollection = dslMap.values as java.util.Collection<Int>
-    assertFailsWith<UnsupportedOperationException> {
-      dslMapValuesAsJavaUtilCollection.remove(1)
-    }
-  }
-
-  @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
-  @Test
-  fun dslMapValuesIteratorIsNotEvenSecretlyMutable() {
-    val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1))
-    val dslMapValuesAsJavaUtilCollection = dslMap.values as java.util.Collection<Int>
-    val itr = dslMapValuesAsJavaUtilCollection.iterator()
-    itr.next()
-    assertFailsWith<UnsupportedOperationException> {
-      itr.remove()
-    }
-  }
-
-  @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
-  @Test
-  fun dslMapEntriesAreNotEvenSecretlyMutable() {
-    val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1))
-    val dslMapEntriesAsJavaUtilSet = dslMap.entries as java.util.Set<Map.Entry<Int, Int>>
-    val entry = dslMap.entries.single()
-    assertFailsWith<UnsupportedOperationException> {
-      dslMapEntriesAsJavaUtilSet.remove(entry)
-    }
-  }
-
-  @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
-  @Test
-  fun dslMapEntriesIteratorIsNotEvenSecretlyMutable() {
-    val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1))
-    val dslMapEntriesAsJavaUtilSet = dslMap.entries as java.util.Set<Map.Entry<Int, Int>>
-    val itr = dslMapEntriesAsJavaUtilSet.iterator()
-    itr.next()
-    assertFailsWith<UnsupportedOperationException> {
-      itr.remove()
-    }
-  }
-
-  @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
-  @Test
-  fun dslMapEntryObjectsAreNotEvenSecretlyMutable() {
-    val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1))
-    val dslMapEntryAsJavaUtilMapEntry = dslMap.entries.single() as java.util.Map.Entry<Int, Int>
-    assertFailsWith<UnsupportedOperationException> {
-      dslMapEntryAsJavaUtilMapEntry.value = 2
-    }
-  }
-
-  @Test
-  fun expectedToString() {
-    assertThat(DslMap<Int, Int, DummyProxy>(mapOf(1 to 2, 2 to 3)).toString())
-      .isEqualTo("{1=2, 2=3}")
-  }
-
-  @Test
-  fun equality() {
-    EqualsTester()
-      .addEqualityGroup(DslMap<Int, Int, DummyProxy>(mapOf(1 to 2, 2 to 3)), mapOf(1 to 2, 2 to 3))
-      .addEqualityGroup(DslMap<Int, Int, DummyProxy>(mapOf(1 to 3, 2 to 3)), mapOf(1 to 3, 2 to 3))
-      .addEqualityGroup(
-        DslMap<Int, Int, DummyProxy>(emptyMap()),
-        DslMap<String, String, DummyProxy>(emptyMap()),
-        emptyMap<Int, Int>()
-      )
-      .testEquals()
-  }
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/DupEnumKt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/DupEnumKt.kt
deleted file mode 100644
index 5d8f85f..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/DupEnumKt.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun dupEnum(block: com.google.protobuf.DupEnumKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.DupEnum =
-  com.google.protobuf.DupEnumKt.Dsl._create(com.google.protobuf.UnittestLite.DupEnum.newBuilder()).apply { block() }._build()
-object DupEnumKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.DupEnum.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.DupEnum.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.DupEnum = _builder.build()
-  }
-}
-inline fun com.google.protobuf.UnittestLite.DupEnum.copy(block: com.google.protobuf.DupEnumKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.DupEnum =
-  com.google.protobuf.DupEnumKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/ExtensionListTest.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/ExtensionListTest.kt
deleted file mode 100644
index e805e1e..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/ExtensionListTest.kt
+++ /dev/null
@@ -1,125 +0,0 @@
-package com.google.protobuf.kotlin
-
-import com.google.common.testing.EqualsTester
-import com.google.common.truth.Truth.assertThat
-import example_extensible_message.ExampleExtensibleMessage
-import example_extensible_message.ExampleExtensibleMessageOuterClass as TestProto
-import kotlin.test.assertFailsWith
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-/** Tests for [DslList]. */
-@RunWith(JUnit4::class)
-@OptIn(OnlyForUseByGeneratedProtoCode::class)
-class ExtensionListTest {
-  class DummyProxy private constructor() : DslProxy()
-
-  @Test
-  fun matchesList() {
-    assertThat(
-      ExtensionList<Int, ExampleExtensibleMessage>(
-        TestProto.repeatedExtension, listOf(1, 2, 3)
-      )
-    ).containsExactly(1, 2, 3).inOrder()
-  }
-
-  @Test
-  fun reflectsChangesInList() {
-    val mutableList = mutableListOf(1, 2, 3)
-    val extensionList = ExtensionList<Int, ExampleExtensibleMessage>(
-      TestProto.repeatedExtension, mutableList
-    )
-    mutableList.add(4)
-    assertThat(extensionList).containsExactly(1, 2, 3, 4).inOrder()
-  }
-
-  @Test
-  fun extensionListIsNotMutable() {
-    val extensionList = ExtensionList<Int, ExampleExtensibleMessage>(
-      TestProto.repeatedExtension, mutableListOf(1, 2, 3)
-    )
-    assertThat(extensionList is MutableList<*>).isFalse()
-  }
-
-  @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
-  @Test
-  fun extensionListIsNotEvenSecretlyMutable() {
-    val extensionList = ExtensionList<Int, ExampleExtensibleMessage>(
-      TestProto.repeatedExtension, mutableListOf(1, 2, 3)
-    )
-    val extensionListAsJavaUtil = extensionList as java.util.List<Int>
-    assertFailsWith<UnsupportedOperationException> {
-      extensionListAsJavaUtil.add(4)
-    }
-  }
-
-  @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
-  @Test
-  fun extensionList_IteratorIsNotEvenSecretlyMutable() {
-    val extensionList = ExtensionList<Int, ExampleExtensibleMessage>(
-      TestProto.repeatedExtension, mutableListOf(1, 2, 3)
-    )
-    val iterator = extensionList.iterator() as java.util.Iterator<Int>
-    iterator.next()
-
-    assertFailsWith<UnsupportedOperationException> {
-      iterator.remove()
-    }
-  }
-
-  @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
-  @Test
-  fun extensionList_ListIteratorIsNotEvenSecretlyMutable() {
-    val extensionList = ExtensionList<Int, ExampleExtensibleMessage>(
-      TestProto.repeatedExtension, mutableListOf(1, 2, 3)
-    )
-    val iterator = extensionList.listIterator() as java.util.ListIterator<Int>
-    iterator.next()
-
-    assertFailsWith<UnsupportedOperationException> {
-      iterator.remove()
-    }
-  }
-
-  @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
-  @Test
-  fun extensionList_ListIteratorIndexIsNotEvenSecretlyMutable() {
-    val extensionList = ExtensionList<Int, ExampleExtensibleMessage>(
-      TestProto.repeatedExtension, mutableListOf(1, 2, 3)
-    )
-    val iterator = extensionList.listIterator(1) as java.util.ListIterator<Int>
-    iterator.next()
-
-    assertFailsWith<UnsupportedOperationException> {
-      iterator.remove()
-    }
-  }
-
-  @Test
-  fun expectedToString() {
-    assertThat(
-      ExtensionList<Int, ExampleExtensibleMessage>(TestProto.repeatedExtension, listOf(1, 2))
-        .toString()
-    ).isEqualTo("[1, 2]")
-  }
-
-  @Test
-  fun equality() {
-    EqualsTester()
-      .addEqualityGroup(
-        ExtensionList<Int, ExampleExtensibleMessage>(TestProto.repeatedExtension, listOf(1, 2)),
-        ExtensionList<Int, ExampleExtensibleMessage>(TestProto.differentExtension, listOf(1, 2)),
-        listOf(1, 2)
-      )
-      .addEqualityGroup(
-        ExtensionList<Int, ExampleExtensibleMessage>(TestProto.repeatedExtension, listOf(2, 2)),
-        listOf(2, 2)
-      )
-      .addEqualityGroup(
-        ExtensionList<Int, ExampleExtensibleMessage>(TestProto.repeatedExtension, emptyList()),
-        emptyList<Int>()
-      )
-      .testEquals()
-  }
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/ForeignMessageLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/ForeignMessageLiteKt.kt
deleted file mode 100644
index e264d1e..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/ForeignMessageLiteKt.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun foreignMessageLite(block: com.google.protobuf.ForeignMessageLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.ForeignMessageLite =
-  com.google.protobuf.ForeignMessageLiteKt.Dsl._create(com.google.protobuf.UnittestLite.ForeignMessageLite.newBuilder()).apply { block() }._build()
-object ForeignMessageLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.ForeignMessageLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.ForeignMessageLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.ForeignMessageLite = _builder.build()
-
-    /**
-     * <code>optional int32 c = 1;</code>
-     */
-    var c: kotlin.Int
-      @JvmName("getC")
-      get() = _builder.getC()
-      @JvmName("setC")
-      set(value) {
-        _builder.setC(value)
-      }
-    /**
-     * <code>optional int32 c = 1;</code>
-     */
-    fun clearC() {
-      _builder.clearC()
-    }
-    /**
-     * <code>optional int32 c = 1;</code>
-     * @return Whether the c field is set.
-     */
-    fun hasC(): kotlin.Boolean {
-      return _builder.hasC()
-    }
-  }
-}
-inline fun com.google.protobuf.UnittestLite.ForeignMessageLite.copy(block: com.google.protobuf.ForeignMessageLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.ForeignMessageLite =
-  com.google.protobuf.ForeignMessageLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/NonPackedFixed32Kt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/NonPackedFixed32Kt.kt
deleted file mode 100644
index 4aad2a1..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/NonPackedFixed32Kt.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun nonPackedFixed32(block: com.google.protobuf.NonPackedFixed32Kt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.NonPackedFixed32 =
-  com.google.protobuf.NonPackedFixed32Kt.Dsl._create(com.google.protobuf.UnittestLite.NonPackedFixed32.newBuilder()).apply { block() }._build()
-object NonPackedFixed32Kt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.NonPackedFixed32.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.NonPackedFixed32.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.NonPackedFixed32 = _builder.build()
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedFixed32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-     */
-     val repeatedFixed32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedFixed32List()
-      )
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-     * @param value The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedFixed32(value)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-     * @param value The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedFixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-     * @param values The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedFixed32(values)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-     * @param values The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedFixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedFixed32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedFixed32(index, value)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.clear() {
-      _builder.clearRepeatedFixed32()
-    }}
-}
-inline fun com.google.protobuf.UnittestLite.NonPackedFixed32.copy(block: com.google.protobuf.NonPackedFixed32Kt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.NonPackedFixed32 =
-  com.google.protobuf.NonPackedFixed32Kt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/NonPackedInt32Kt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/NonPackedInt32Kt.kt
deleted file mode 100644
index 49e44c5..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/NonPackedInt32Kt.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun nonPackedInt32(block: com.google.protobuf.NonPackedInt32Kt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.NonPackedInt32 =
-  com.google.protobuf.NonPackedInt32Kt.Dsl._create(com.google.protobuf.UnittestLite.NonPackedInt32.newBuilder()).apply { block() }._build()
-object NonPackedInt32Kt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.NonPackedInt32.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.NonPackedInt32.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.NonPackedInt32 = _builder.build()
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedInt32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated int32 repeated_int32 = 2048;</code>
-     */
-     val repeatedInt32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedInt32List()
-      )
-    /**
-     * <code>repeated int32 repeated_int32 = 2048;</code>
-     * @param value The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedInt32(value)
-    }/**
-     * <code>repeated int32 repeated_int32 = 2048;</code>
-     * @param value The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedInt32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated int32 repeated_int32 = 2048;</code>
-     * @param values The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedInt32(values)
-    }/**
-     * <code>repeated int32 repeated_int32 = 2048;</code>
-     * @param values The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedInt32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated int32 repeated_int32 = 2048;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedInt32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedInt32(index, value)
-    }/**
-     * <code>repeated int32 repeated_int32 = 2048;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.clear() {
-      _builder.clearRepeatedInt32()
-    }}
-}
-inline fun com.google.protobuf.UnittestLite.NonPackedInt32.copy(block: com.google.protobuf.NonPackedInt32Kt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.NonPackedInt32 =
-  com.google.protobuf.NonPackedInt32Kt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/OptionalGroup_extension_liteKt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/OptionalGroup_extension_liteKt.kt
deleted file mode 100644
index 009e4bb..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/OptionalGroup_extension_liteKt.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun optionalGroupExtensionLite(block: com.google.protobuf.OptionalGroup_extension_liteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.OptionalGroup_extension_lite =
-  com.google.protobuf.OptionalGroup_extension_liteKt.Dsl._create(com.google.protobuf.UnittestLite.OptionalGroup_extension_lite.newBuilder()).apply { block() }._build()
-object OptionalGroup_extension_liteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.OptionalGroup_extension_lite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.OptionalGroup_extension_lite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.OptionalGroup_extension_lite = _builder.build()
-
-    /**
-     * <code>optional int32 a = 17;</code>
-     */
-    var a: kotlin.Int
-      @JvmName("getA")
-      get() = _builder.getA()
-      @JvmName("setA")
-      set(value) {
-        _builder.setA(value)
-      }
-    /**
-     * <code>optional int32 a = 17;</code>
-     */
-    fun clearA() {
-      _builder.clearA()
-    }
-    /**
-     * <code>optional int32 a = 17;</code>
-     * @return Whether the a field is set.
-     */
-    fun hasA(): kotlin.Boolean {
-      return _builder.hasA()
-    }
-  }
-}
-inline fun com.google.protobuf.UnittestLite.OptionalGroup_extension_lite.copy(block: com.google.protobuf.OptionalGroup_extension_liteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.OptionalGroup_extension_lite =
-  com.google.protobuf.OptionalGroup_extension_liteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/PackedFixed32Kt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/PackedFixed32Kt.kt
deleted file mode 100644
index 6e96e2f..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/PackedFixed32Kt.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun packedFixed32(block: com.google.protobuf.PackedFixed32Kt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.PackedFixed32 =
-  com.google.protobuf.PackedFixed32Kt.Dsl._create(com.google.protobuf.UnittestLite.PackedFixed32.newBuilder()).apply { block() }._build()
-object PackedFixed32Kt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.PackedFixed32.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.PackedFixed32.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.PackedFixed32 = _builder.build()
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedFixed32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-     */
-     val repeatedFixed32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedFixed32List()
-      )
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-     * @param value The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedFixed32(value)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-     * @param value The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedFixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-     * @param values The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedFixed32(values)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-     * @param values The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedFixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedFixed32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedFixed32(index, value)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.clear() {
-      _builder.clearRepeatedFixed32()
-    }}
-}
-inline fun com.google.protobuf.UnittestLite.PackedFixed32.copy(block: com.google.protobuf.PackedFixed32Kt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.PackedFixed32 =
-  com.google.protobuf.PackedFixed32Kt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/PackedInt32Kt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/PackedInt32Kt.kt
deleted file mode 100644
index 6d131ed..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/PackedInt32Kt.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun packedInt32(block: com.google.protobuf.PackedInt32Kt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.PackedInt32 =
-  com.google.protobuf.PackedInt32Kt.Dsl._create(com.google.protobuf.UnittestLite.PackedInt32.newBuilder()).apply { block() }._build()
-object PackedInt32Kt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.PackedInt32.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.PackedInt32.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.PackedInt32 = _builder.build()
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedInt32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-     */
-     val repeatedInt32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedInt32List()
-      )
-    /**
-     * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-     * @param value The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedInt32(value)
-    }/**
-     * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-     * @param value The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedInt32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-     * @param values The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedInt32(values)
-    }/**
-     * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-     * @param values The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedInt32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedInt32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedInt32(index, value)
-    }/**
-     * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.clear() {
-      _builder.clearRepeatedInt32()
-    }}
-}
-inline fun com.google.protobuf.UnittestLite.PackedInt32.copy(block: com.google.protobuf.PackedInt32Kt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.PackedInt32 =
-  com.google.protobuf.PackedInt32Kt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/Proto3Test.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/Proto3Test.kt
deleted file mode 100644
index b3fd336..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/Proto3Test.kt
+++ /dev/null
@@ -1,340 +0,0 @@
-package com.google.protobuf.kotlin
-
-import com.google.common.truth.Truth.assertThat
-import evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3
-import evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes
-import evil_names_proto3.EvilNamesProto3OuterClass.Class
-import evil_names_proto3.HardKeywordsAllTypesKt
-import evil_names_proto3.class_
-import evil_names_proto3.evilNamesProto3
-import evil_names_proto3.hardKeywordsAllTypes
-import multiple_files_proto3.MultipleFilesMessageA
-import multiple_files_proto3.MultipleFilesMessageB
-import multiple_files_proto3.multipleFilesMessageA
-import multiple_files_proto3.multipleFilesMessageB
-import proto3_unittest.UnittestProto3
-import proto3_unittest.TestAllTypesKt
-import proto3_unittest.TestAllTypesKt.nestedMessage
-import proto3_unittest.UnittestProto3.TestAllTypes
-import proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum
-import proto3_unittest.UnittestProto3.TestEmptyMessage
-import proto3_unittest.copy
-import proto3_unittest.testAllTypes
-import proto3_unittest.testEmptyMessage
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@RunWith(JUnit4::class)
-class Proto3Test {
-  @Test
-  fun testGettersAndSetters() {
-    testAllTypes {
-      optionalInt32 = 101
-      assertThat(optionalInt32).isEqualTo(101)
-      optionalString = "115"
-      assertThat(optionalString).isEqualTo("115")
-      optionalNestedMessage = TestAllTypesKt.nestedMessage { bb = 118 }
-      assertThat(optionalNestedMessage).isEqualTo(TestAllTypesKt.nestedMessage { bb = 118 })
-      optionalNestedEnum = NestedEnum.BAZ
-      assertThat(optionalNestedEnum).isEqualTo(NestedEnum.BAZ)
-      oneofUint32 = 601
-      assertThat(oneofUint32).isEqualTo(601)
-    }
-  }
-
-  @Test
-  fun testRepeatedGettersAndSetters() {
-    testAllTypes {
-      repeatedInt32.addAll(listOf(1, 2))
-      assertThat(repeatedInt32).isEqualTo(listOf(1, 2))
-      repeatedInt32 += listOf(3, 4)
-      assertThat(repeatedInt32).isEqualTo(listOf(1, 2, 3, 4))
-      repeatedInt32[0] = 5
-      assertThat(repeatedInt32).isEqualTo(listOf(5, 2, 3, 4))
-
-      repeatedString.addAll(listOf("1", "2"))
-      assertThat(repeatedString).isEqualTo(listOf("1", "2"))
-      repeatedString += listOf("3", "4")
-      assertThat(repeatedString).isEqualTo(listOf("1", "2", "3", "4"))
-      repeatedString[0] = "5"
-      assertThat(repeatedString).isEqualTo(listOf("5", "2", "3", "4"))
-
-      repeatedNestedMessage.addAll(listOf(nestedMessage { bb = 1 }, nestedMessage { bb = 2 }))
-      assertThat(repeatedNestedMessage).isEqualTo(
-        listOf(
-          nestedMessage { bb = 1 },
-          nestedMessage { bb = 2 }
-        )
-      )
-      repeatedNestedMessage += listOf(nestedMessage { bb = 3 }, nestedMessage { bb = 4 })
-      assertThat(repeatedNestedMessage).isEqualTo(
-        listOf(
-          nestedMessage { bb = 1 },
-          nestedMessage { bb = 2 },
-          nestedMessage { bb = 3 },
-          nestedMessage { bb = 4 }
-        )
-      )
-      repeatedNestedMessage[0] = nestedMessage { bb = 5 }
-      assertThat(repeatedNestedMessage).isEqualTo(
-        listOf(
-          nestedMessage { bb = 5 },
-          nestedMessage { bb = 2 },
-          nestedMessage { bb = 3 },
-          nestedMessage { bb = 4 }
-        )
-      )
-
-      repeatedNestedEnum.addAll(listOf(NestedEnum.FOO, NestedEnum.BAR))
-      assertThat(repeatedNestedEnum).isEqualTo(listOf(NestedEnum.FOO, NestedEnum.BAR))
-      repeatedNestedEnum += listOf(NestedEnum.BAZ, NestedEnum.FOO)
-      assertThat(repeatedNestedEnum).isEqualTo(
-        listOf(NestedEnum.FOO, NestedEnum.BAR, NestedEnum.BAZ, NestedEnum.FOO)
-      )
-      repeatedNestedEnum[0] = NestedEnum.BAR
-      assertThat(repeatedNestedEnum).isEqualTo(
-        listOf(NestedEnum.BAR, NestedEnum.BAR, NestedEnum.BAZ, NestedEnum.FOO)
-      )
-    }
-  }
-
-  @Test
-  fun testClears() {
-    assertThat(
-      testAllTypes {
-        optionalInt32 = 101
-        clearOptionalInt32()
-
-        optionalString = "115"
-        clearOptionalString()
-
-        optionalNestedMessage = TestAllTypesKt.nestedMessage { bb = 118 }
-        clearOptionalNestedMessage()
-
-        optionalNestedEnum = NestedEnum.BAZ
-        clearOptionalNestedEnum()
-
-        oneofUint32 = 601
-        clearOneofUint32()
-      }
-    ).isEqualTo(
-      TestAllTypes.newBuilder().build()
-    )
-  }
-
-  @Test
-  fun testCopy() {
-    val message = testAllTypes {
-      optionalInt32 = 101
-      optionalString = "115"
-    }
-    val modifiedMessage = message.copy {
-      optionalInt32 = 201
-    }
-
-    assertThat(message).isEqualTo(
-      TestAllTypes.newBuilder()
-        .setOptionalInt32(101)
-        .setOptionalString("115")
-        .build()
-    )
-    assertThat(modifiedMessage).isEqualTo(
-      TestAllTypes.newBuilder()
-        .setOptionalInt32(201)
-        .setOptionalString("115")
-        .build()
-    )
-  }
-
-  @Test
-  fun testOneof() {
-    val message = testAllTypes {
-      oneofString = "foo"
-      assertThat(oneofFieldCase)
-        .isEqualTo(TestAllTypes.OneofFieldCase.ONEOF_STRING)
-      assertThat(oneofString).isEqualTo("foo")
-      clearOneofField()
-      assertThat(oneofFieldCase)
-        .isEqualTo(TestAllTypes.OneofFieldCase.ONEOFFIELD_NOT_SET)
-      oneofUint32 = 5
-    }
-
-    assertThat(message.getOneofFieldCase())
-      .isEqualTo(TestAllTypes.OneofFieldCase.ONEOF_UINT32)
-    assertThat(message.getOneofUint32()).isEqualTo(5)
-  }
-
-  @Test
-  fun testEmptyMessages() {
-    assertThat(
-      testEmptyMessage {}
-    ).isEqualTo(
-      TestEmptyMessage.newBuilder().build()
-    )
-  }
-
-  @Test
-  fun testEvilNames() {
-    assertThat(
-      evilNamesProto3 {
-        initialized = true
-        hasFoo = true
-        bar = "foo"
-        isInitialized = true
-        fooBar = "foo"
-        aLLCAPS += "foo"
-        aLLCAPSMAP[1] = true
-        hasUnderbarPrecedingNumeric1Foo = true
-        hasUnderbarPrecedingNumeric42Bar = true
-        hasUnderbarPrecedingNumeric123Foo42BarBaz = true
-        extension += "foo"
-        class_ = "foo"
-        int = 1.0
-        long = true
-        boolean = 1L
-        sealed = "foo"
-        interface_ = 1F
-        in_ = 1
-        object_ = "foo"
-        cachedSize_ = "foo"
-        serializedSize_ = true
-        value = "foo"
-        index = 1L
-        values += "foo"
-        newValues += "foo"
-        builder = true
-        k[1] = 1
-        v["foo"] = "foo"
-        key["foo"] = 1
-        map[1] = "foo"
-        pairs["foo"] = 1
-        LeadingUnderscore = "foo"
-        option = 1
-      }
-    ).isEqualTo(
-      EvilNamesProto3.newBuilder()
-        .setInitialized(true)
-        .setHasFoo(true)
-        .setBar("foo")
-        .setIsInitialized(true)
-        .setFooBar("foo")
-        .addALLCAPS("foo")
-        .putALLCAPSMAP(1, true)
-        .setHasUnderbarPrecedingNumeric1Foo(true)
-        .setHasUnderbarPrecedingNumeric42Bar(true)
-        .setHasUnderbarPrecedingNumeric123Foo42BarBaz(true)
-        .addExtension("foo")
-        .setClass_("foo")
-        .setInt(1.0)
-        .setLong(true)
-        .setBoolean(1L)
-        .setSealed("foo")
-        .setInterface(1F)
-        .setIn(1)
-        .setObject("foo")
-        .setCachedSize_("foo")
-        .setSerializedSize_(true)
-        .setValue("foo")
-        .setIndex(1L)
-        .addValues("foo")
-        .addNewValues("foo")
-        .setBuilder(true)
-        .putK(1, 1)
-        .putV("foo", "foo")
-        .putKey("foo", 1)
-        .putMap(1, "foo")
-        .putPairs("foo", 1)
-        .setLeadingUnderscore("foo")
-        .setOption(1)
-        .build()
-    )
-
-    assertThat(class_ {}).isEqualTo(Class.newBuilder().build())
-  }
-
-  @Test
-  fun testHardKeywordGettersAndSetters() {
-    hardKeywordsAllTypes {
-      as_ = 1
-      assertThat(as_).isEqualTo(1)
-
-      in_ = "foo"
-      assertThat(in_).isEqualTo("foo")
-
-      break_ = HardKeywordsAllTypes.NestedEnum.FOO
-      assertThat(break_).isEqualTo(HardKeywordsAllTypes.NestedEnum.FOO)
-
-      do_ = HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }
-      assertThat(do_).isEqualTo(HardKeywordsAllTypesKt.nestedMessage { while_ = 1 })
-
-      continue_[1] = 1
-      assertThat(continue_[1]).isEqualTo(1)
-
-      else_ += 1
-      assertThat(else_).isEqualTo(listOf(1))
-
-      for_ += "foo"
-      assertThat(for_).isEqualTo(listOf("foo"))
-
-      fun_ += HardKeywordsAllTypes.NestedEnum.FOO
-      assertThat(fun_).isEqualTo(listOf(HardKeywordsAllTypes.NestedEnum.FOO))
-
-      if_ += HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }
-      assertThat(if_).isEqualTo(listOf(HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }))
-    }
-  }
-
-  @Test
-  fun testHardKeywordHazzers() {
-    hardKeywordsAllTypes {
-      as_ = 1
-      assertThat(hasAs_()).isTrue()
-
-      in_ = "foo"
-      assertThat(hasIn_()).isTrue()
-
-      break_ = HardKeywordsAllTypes.NestedEnum.FOO
-      assertThat(hasBreak_()).isTrue()
-
-      do_ = HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }
-      assertThat(hasDo_()).isTrue()
-    }
-  }
-
-  @Test
-  fun testHardKeywordClears() {
-    hardKeywordsAllTypes {
-      as_ = 1
-      clearAs_()
-      assertThat(hasAs_()).isFalse()
-
-      in_ = "foo"
-      clearIn_()
-      assertThat(hasIn_()).isFalse()
-
-      break_ = HardKeywordsAllTypes.NestedEnum.FOO
-      clearBreak_()
-      assertThat(hasBreak_()).isFalse()
-
-      do_ = HardKeywordsAllTypesKt.nestedMessage { while_ = 1 }
-      clearDo_()
-      assertThat(hasDo_()).isFalse()
-    }
-  }
-
-  @Test
-  fun testMultipleFiles() {
-    assertThat(
-      multipleFilesMessageA {}
-    ).isEqualTo(
-      MultipleFilesMessageA.newBuilder().build()
-    )
-
-    assertThat(
-      multipleFilesMessageB {}
-    ).isEqualTo(
-      MultipleFilesMessageB.newBuilder().build()
-    )
-  }
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/RecursiveMessageKt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/RecursiveMessageKt.kt
deleted file mode 100644
index 783e8e3..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/RecursiveMessageKt.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun recursiveMessage(block: com.google.protobuf.RecursiveMessageKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.RecursiveMessage =
-  com.google.protobuf.RecursiveMessageKt.Dsl._create(com.google.protobuf.UnittestLite.RecursiveMessage.newBuilder()).apply { block() }._build()
-object RecursiveMessageKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.RecursiveMessage.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.RecursiveMessage.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.RecursiveMessage = _builder.build()
-
-    /**
-     * <code>optional .protobuf_unittest.RecursiveMessage recurse = 1;</code>
-     */
-    var recurse: com.google.protobuf.UnittestLite.RecursiveMessage
-      @JvmName("getRecurse")
-      get() = _builder.getRecurse()
-      @JvmName("setRecurse")
-      set(value) {
-        _builder.setRecurse(value)
-      }
-    /**
-     * <code>optional .protobuf_unittest.RecursiveMessage recurse = 1;</code>
-     */
-    fun clearRecurse() {
-      _builder.clearRecurse()
-    }
-    /**
-     * <code>optional .protobuf_unittest.RecursiveMessage recurse = 1;</code>
-     * @return Whether the recurse field is set.
-     */
-    fun hasRecurse(): kotlin.Boolean {
-      return _builder.hasRecurse()
-    }
-
-    /**
-     * <code>optional bytes payload = 2;</code>
-     */
-    var payload: com.google.protobuf.ByteString
-      @JvmName("getPayload")
-      get() = _builder.getPayload()
-      @JvmName("setPayload")
-      set(value) {
-        _builder.setPayload(value)
-      }
-    /**
-     * <code>optional bytes payload = 2;</code>
-     */
-    fun clearPayload() {
-      _builder.clearPayload()
-    }
-    /**
-     * <code>optional bytes payload = 2;</code>
-     * @return Whether the payload field is set.
-     */
-    fun hasPayload(): kotlin.Boolean {
-      return _builder.hasPayload()
-    }
-  }
-}
-inline fun com.google.protobuf.UnittestLite.RecursiveMessage.copy(block: com.google.protobuf.RecursiveMessageKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.RecursiveMessage =
-  com.google.protobuf.RecursiveMessageKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/RepeatedGroup_extension_liteKt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/RepeatedGroup_extension_liteKt.kt
deleted file mode 100644
index 6fd86ab..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/RepeatedGroup_extension_liteKt.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun repeatedGroupExtensionLite(block: com.google.protobuf.RepeatedGroup_extension_liteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite =
-  com.google.protobuf.RepeatedGroup_extension_liteKt.Dsl._create(com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite.newBuilder()).apply { block() }._build()
-object RepeatedGroup_extension_liteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite = _builder.build()
-
-    /**
-     * <code>optional int32 a = 47;</code>
-     */
-    var a: kotlin.Int
-      @JvmName("getA")
-      get() = _builder.getA()
-      @JvmName("setA")
-      set(value) {
-        _builder.setA(value)
-      }
-    /**
-     * <code>optional int32 a = 47;</code>
-     */
-    fun clearA() {
-      _builder.clearA()
-    }
-    /**
-     * <code>optional int32 a = 47;</code>
-     * @return Whether the a field is set.
-     */
-    fun hasA(): kotlin.Boolean {
-      return _builder.hasA()
-    }
-  }
-}
-inline fun com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite.copy(block: com.google.protobuf.RepeatedGroup_extension_liteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite =
-  com.google.protobuf.RepeatedGroup_extension_liteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestAllExtensionsLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestAllExtensionsLiteKt.kt
deleted file mode 100644
index ed66d72..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestAllExtensionsLiteKt.kt
+++ /dev/null
@@ -1,118 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testAllExtensionsLite(block: com.google.protobuf.TestAllExtensionsLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestAllExtensionsLite =
-  com.google.protobuf.TestAllExtensionsLiteKt.Dsl._create(com.google.protobuf.UnittestLite.TestAllExtensionsLite.newBuilder()).apply { block() }._build()
-object TestAllExtensionsLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestAllExtensionsLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.TestAllExtensionsLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.TestAllExtensionsLite = _builder.build()
-    @Suppress("UNCHECKED_CAST")
-    @kotlin.jvm.JvmSynthetic
-    operator fun <T> get(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestAllExtensionsLite, T>): T {
-      return if (extension.isRepeated) {
-        get(extension as com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestAllExtensionsLite, List<*>>) as T
-      } else {
-        _builder.getExtension(extension)
-      }
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    @kotlin.jvm.JvmName("-getRepeatedExtension")
-    operator fun <E> get(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestAllExtensionsLite, List<E>>
-    ): com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestAllExtensionsLite> {
-      return com.google.protobuf.kotlin.ExtensionList(extension, _builder.getExtension(extension))
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    operator fun contains(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestAllExtensionsLite, *>): Boolean {
-      return _builder.hasExtension(extension)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun clear(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestAllExtensionsLite, *>) {
-      _builder.clearExtension(extension)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun <T> setExtension(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestAllExtensionsLite, T>, value: T) {
-      _builder.setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <T : Comparable<T>> set(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestAllExtensionsLite, T>,
-      value: T
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun set(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestAllExtensionsLite, com.google.protobuf.ByteString>,
-      value: com.google.protobuf.ByteString
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <T : com.google.protobuf.MessageLite> set(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestAllExtensionsLite, T>,
-      value: T
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestAllExtensionsLite>.add(value: E) {
-      _builder.addExtension(this.extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestAllExtensionsLite>.plusAssign(value: E) {
-      add(value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestAllExtensionsLite>.addAll(values: Iterable<E>) {
-      for (value in values) {
-        add(value)
-      }
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestAllExtensionsLite>.plusAssign(values: Iterable<E>) {
-      addAll(values)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestAllExtensionsLite>.set(index: Int, value: E) {
-      _builder.setExtension(this.extension, index, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline fun com.google.protobuf.kotlin.ExtensionList<*, com.google.protobuf.UnittestLite.TestAllExtensionsLite>.clear() {
-      clear(extension)
-    }
-
-  }
-}
-inline fun com.google.protobuf.UnittestLite.TestAllExtensionsLite.copy(block: com.google.protobuf.TestAllExtensionsLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestAllExtensionsLite =
-  com.google.protobuf.TestAllExtensionsLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestAllTypesLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestAllTypesLiteKt.kt
deleted file mode 100644
index 9e85ba8..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestAllTypesLiteKt.kt
+++ /dev/null
@@ -1,3180 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testAllTypesLite(block: com.google.protobuf.TestAllTypesLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestAllTypesLite =
-  com.google.protobuf.TestAllTypesLiteKt.Dsl._create(com.google.protobuf.UnittestLite.TestAllTypesLite.newBuilder()).apply { block() }._build()
-object TestAllTypesLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestAllTypesLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.TestAllTypesLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.TestAllTypesLite = _builder.build()
-
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>optional int32 optional_int32 = 1;</code>
-     */
-    var optionalInt32: kotlin.Int
-      @JvmName("getOptionalInt32")
-      get() = _builder.getOptionalInt32()
-      @JvmName("setOptionalInt32")
-      set(value) {
-        _builder.setOptionalInt32(value)
-      }
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>optional int32 optional_int32 = 1;</code>
-     */
-    fun clearOptionalInt32() {
-      _builder.clearOptionalInt32()
-    }
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>optional int32 optional_int32 = 1;</code>
-     * @return Whether the optionalInt32 field is set.
-     */
-    fun hasOptionalInt32(): kotlin.Boolean {
-      return _builder.hasOptionalInt32()
-    }
-
-    /**
-     * <code>optional int64 optional_int64 = 2;</code>
-     */
-    var optionalInt64: kotlin.Long
-      @JvmName("getOptionalInt64")
-      get() = _builder.getOptionalInt64()
-      @JvmName("setOptionalInt64")
-      set(value) {
-        _builder.setOptionalInt64(value)
-      }
-    /**
-     * <code>optional int64 optional_int64 = 2;</code>
-     */
-    fun clearOptionalInt64() {
-      _builder.clearOptionalInt64()
-    }
-    /**
-     * <code>optional int64 optional_int64 = 2;</code>
-     * @return Whether the optionalInt64 field is set.
-     */
-    fun hasOptionalInt64(): kotlin.Boolean {
-      return _builder.hasOptionalInt64()
-    }
-
-    /**
-     * <code>optional uint32 optional_uint32 = 3;</code>
-     */
-    var optionalUint32: kotlin.Int
-      @JvmName("getOptionalUint32")
-      get() = _builder.getOptionalUint32()
-      @JvmName("setOptionalUint32")
-      set(value) {
-        _builder.setOptionalUint32(value)
-      }
-    /**
-     * <code>optional uint32 optional_uint32 = 3;</code>
-     */
-    fun clearOptionalUint32() {
-      _builder.clearOptionalUint32()
-    }
-    /**
-     * <code>optional uint32 optional_uint32 = 3;</code>
-     * @return Whether the optionalUint32 field is set.
-     */
-    fun hasOptionalUint32(): kotlin.Boolean {
-      return _builder.hasOptionalUint32()
-    }
-
-    /**
-     * <code>optional uint64 optional_uint64 = 4;</code>
-     */
-    var optionalUint64: kotlin.Long
-      @JvmName("getOptionalUint64")
-      get() = _builder.getOptionalUint64()
-      @JvmName("setOptionalUint64")
-      set(value) {
-        _builder.setOptionalUint64(value)
-      }
-    /**
-     * <code>optional uint64 optional_uint64 = 4;</code>
-     */
-    fun clearOptionalUint64() {
-      _builder.clearOptionalUint64()
-    }
-    /**
-     * <code>optional uint64 optional_uint64 = 4;</code>
-     * @return Whether the optionalUint64 field is set.
-     */
-    fun hasOptionalUint64(): kotlin.Boolean {
-      return _builder.hasOptionalUint64()
-    }
-
-    /**
-     * <code>optional sint32 optional_sint32 = 5;</code>
-     */
-    var optionalSint32: kotlin.Int
-      @JvmName("getOptionalSint32")
-      get() = _builder.getOptionalSint32()
-      @JvmName("setOptionalSint32")
-      set(value) {
-        _builder.setOptionalSint32(value)
-      }
-    /**
-     * <code>optional sint32 optional_sint32 = 5;</code>
-     */
-    fun clearOptionalSint32() {
-      _builder.clearOptionalSint32()
-    }
-    /**
-     * <code>optional sint32 optional_sint32 = 5;</code>
-     * @return Whether the optionalSint32 field is set.
-     */
-    fun hasOptionalSint32(): kotlin.Boolean {
-      return _builder.hasOptionalSint32()
-    }
-
-    /**
-     * <code>optional sint64 optional_sint64 = 6;</code>
-     */
-    var optionalSint64: kotlin.Long
-      @JvmName("getOptionalSint64")
-      get() = _builder.getOptionalSint64()
-      @JvmName("setOptionalSint64")
-      set(value) {
-        _builder.setOptionalSint64(value)
-      }
-    /**
-     * <code>optional sint64 optional_sint64 = 6;</code>
-     */
-    fun clearOptionalSint64() {
-      _builder.clearOptionalSint64()
-    }
-    /**
-     * <code>optional sint64 optional_sint64 = 6;</code>
-     * @return Whether the optionalSint64 field is set.
-     */
-    fun hasOptionalSint64(): kotlin.Boolean {
-      return _builder.hasOptionalSint64()
-    }
-
-    /**
-     * <code>optional fixed32 optional_fixed32 = 7;</code>
-     */
-    var optionalFixed32: kotlin.Int
-      @JvmName("getOptionalFixed32")
-      get() = _builder.getOptionalFixed32()
-      @JvmName("setOptionalFixed32")
-      set(value) {
-        _builder.setOptionalFixed32(value)
-      }
-    /**
-     * <code>optional fixed32 optional_fixed32 = 7;</code>
-     */
-    fun clearOptionalFixed32() {
-      _builder.clearOptionalFixed32()
-    }
-    /**
-     * <code>optional fixed32 optional_fixed32 = 7;</code>
-     * @return Whether the optionalFixed32 field is set.
-     */
-    fun hasOptionalFixed32(): kotlin.Boolean {
-      return _builder.hasOptionalFixed32()
-    }
-
-    /**
-     * <code>optional fixed64 optional_fixed64 = 8;</code>
-     */
-    var optionalFixed64: kotlin.Long
-      @JvmName("getOptionalFixed64")
-      get() = _builder.getOptionalFixed64()
-      @JvmName("setOptionalFixed64")
-      set(value) {
-        _builder.setOptionalFixed64(value)
-      }
-    /**
-     * <code>optional fixed64 optional_fixed64 = 8;</code>
-     */
-    fun clearOptionalFixed64() {
-      _builder.clearOptionalFixed64()
-    }
-    /**
-     * <code>optional fixed64 optional_fixed64 = 8;</code>
-     * @return Whether the optionalFixed64 field is set.
-     */
-    fun hasOptionalFixed64(): kotlin.Boolean {
-      return _builder.hasOptionalFixed64()
-    }
-
-    /**
-     * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-     */
-    var optionalSfixed32: kotlin.Int
-      @JvmName("getOptionalSfixed32")
-      get() = _builder.getOptionalSfixed32()
-      @JvmName("setOptionalSfixed32")
-      set(value) {
-        _builder.setOptionalSfixed32(value)
-      }
-    /**
-     * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-     */
-    fun clearOptionalSfixed32() {
-      _builder.clearOptionalSfixed32()
-    }
-    /**
-     * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-     * @return Whether the optionalSfixed32 field is set.
-     */
-    fun hasOptionalSfixed32(): kotlin.Boolean {
-      return _builder.hasOptionalSfixed32()
-    }
-
-    /**
-     * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-     */
-    var optionalSfixed64: kotlin.Long
-      @JvmName("getOptionalSfixed64")
-      get() = _builder.getOptionalSfixed64()
-      @JvmName("setOptionalSfixed64")
-      set(value) {
-        _builder.setOptionalSfixed64(value)
-      }
-    /**
-     * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-     */
-    fun clearOptionalSfixed64() {
-      _builder.clearOptionalSfixed64()
-    }
-    /**
-     * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-     * @return Whether the optionalSfixed64 field is set.
-     */
-    fun hasOptionalSfixed64(): kotlin.Boolean {
-      return _builder.hasOptionalSfixed64()
-    }
-
-    /**
-     * <code>optional float optional_float = 11;</code>
-     */
-    var optionalFloat: kotlin.Float
-      @JvmName("getOptionalFloat")
-      get() = _builder.getOptionalFloat()
-      @JvmName("setOptionalFloat")
-      set(value) {
-        _builder.setOptionalFloat(value)
-      }
-    /**
-     * <code>optional float optional_float = 11;</code>
-     */
-    fun clearOptionalFloat() {
-      _builder.clearOptionalFloat()
-    }
-    /**
-     * <code>optional float optional_float = 11;</code>
-     * @return Whether the optionalFloat field is set.
-     */
-    fun hasOptionalFloat(): kotlin.Boolean {
-      return _builder.hasOptionalFloat()
-    }
-
-    /**
-     * <code>optional double optional_double = 12;</code>
-     */
-    var optionalDouble: kotlin.Double
-      @JvmName("getOptionalDouble")
-      get() = _builder.getOptionalDouble()
-      @JvmName("setOptionalDouble")
-      set(value) {
-        _builder.setOptionalDouble(value)
-      }
-    /**
-     * <code>optional double optional_double = 12;</code>
-     */
-    fun clearOptionalDouble() {
-      _builder.clearOptionalDouble()
-    }
-    /**
-     * <code>optional double optional_double = 12;</code>
-     * @return Whether the optionalDouble field is set.
-     */
-    fun hasOptionalDouble(): kotlin.Boolean {
-      return _builder.hasOptionalDouble()
-    }
-
-    /**
-     * <code>optional bool optional_bool = 13;</code>
-     */
-    var optionalBool: kotlin.Boolean
-      @JvmName("getOptionalBool")
-      get() = _builder.getOptionalBool()
-      @JvmName("setOptionalBool")
-      set(value) {
-        _builder.setOptionalBool(value)
-      }
-    /**
-     * <code>optional bool optional_bool = 13;</code>
-     */
-    fun clearOptionalBool() {
-      _builder.clearOptionalBool()
-    }
-    /**
-     * <code>optional bool optional_bool = 13;</code>
-     * @return Whether the optionalBool field is set.
-     */
-    fun hasOptionalBool(): kotlin.Boolean {
-      return _builder.hasOptionalBool()
-    }
-
-    /**
-     * <code>optional string optional_string = 14;</code>
-     */
-    var optionalString: kotlin.String
-      @JvmName("getOptionalString")
-      get() = _builder.getOptionalString()
-      @JvmName("setOptionalString")
-      set(value) {
-        _builder.setOptionalString(value)
-      }
-    /**
-     * <code>optional string optional_string = 14;</code>
-     */
-    fun clearOptionalString() {
-      _builder.clearOptionalString()
-    }
-    /**
-     * <code>optional string optional_string = 14;</code>
-     * @return Whether the optionalString field is set.
-     */
-    fun hasOptionalString(): kotlin.Boolean {
-      return _builder.hasOptionalString()
-    }
-
-    /**
-     * <code>optional bytes optional_bytes = 15;</code>
-     */
-    var optionalBytes: com.google.protobuf.ByteString
-      @JvmName("getOptionalBytes")
-      get() = _builder.getOptionalBytes()
-      @JvmName("setOptionalBytes")
-      set(value) {
-        _builder.setOptionalBytes(value)
-      }
-    /**
-     * <code>optional bytes optional_bytes = 15;</code>
-     */
-    fun clearOptionalBytes() {
-      _builder.clearOptionalBytes()
-    }
-    /**
-     * <code>optional bytes optional_bytes = 15;</code>
-     * @return Whether the optionalBytes field is set.
-     */
-    fun hasOptionalBytes(): kotlin.Boolean {
-      return _builder.hasOptionalBytes()
-    }
-
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     */
-    var optionalGroup: com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup
-      @JvmName("getOptionalGroup")
-      get() = _builder.getOptionalGroup()
-      @JvmName("setOptionalGroup")
-      set(value) {
-        _builder.setOptionalGroup(value)
-      }
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     */
-    fun clearOptionalGroup() {
-      _builder.clearOptionalGroup()
-    }
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     * @return Whether the optionalgroup field is set.
-     */
-    fun hasOptionalGroup(): kotlin.Boolean {
-      return _builder.hasOptionalGroup()
-    }
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_nested_message = 18;</code>
-     */
-    var optionalNestedMessage: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage
-      @JvmName("getOptionalNestedMessage")
-      get() = _builder.getOptionalNestedMessage()
-      @JvmName("setOptionalNestedMessage")
-      set(value) {
-        _builder.setOptionalNestedMessage(value)
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_nested_message = 18;</code>
-     */
-    fun clearOptionalNestedMessage() {
-      _builder.clearOptionalNestedMessage()
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_nested_message = 18;</code>
-     * @return Whether the optionalNestedMessage field is set.
-     */
-    fun hasOptionalNestedMessage(): kotlin.Boolean {
-      return _builder.hasOptionalNestedMessage()
-    }
-
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_foreign_message = 19;</code>
-     */
-    var optionalForeignMessage: com.google.protobuf.UnittestLite.ForeignMessageLite
-      @JvmName("getOptionalForeignMessage")
-      get() = _builder.getOptionalForeignMessage()
-      @JvmName("setOptionalForeignMessage")
-      set(value) {
-        _builder.setOptionalForeignMessage(value)
-      }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_foreign_message = 19;</code>
-     */
-    fun clearOptionalForeignMessage() {
-      _builder.clearOptionalForeignMessage()
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_foreign_message = 19;</code>
-     * @return Whether the optionalForeignMessage field is set.
-     */
-    fun hasOptionalForeignMessage(): kotlin.Boolean {
-      return _builder.hasOptionalForeignMessage()
-    }
-
-    /**
-     * <code>optional .protobuf_unittest_import.ImportMessageLite optional_import_message = 20;</code>
-     */
-    var optionalImportMessage: com.google.protobuf.UnittestImportLite.ImportMessageLite
-      @JvmName("getOptionalImportMessage")
-      get() = _builder.getOptionalImportMessage()
-      @JvmName("setOptionalImportMessage")
-      set(value) {
-        _builder.setOptionalImportMessage(value)
-      }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportMessageLite optional_import_message = 20;</code>
-     */
-    fun clearOptionalImportMessage() {
-      _builder.clearOptionalImportMessage()
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportMessageLite optional_import_message = 20;</code>
-     * @return Whether the optionalImportMessage field is set.
-     */
-    fun hasOptionalImportMessage(): kotlin.Boolean {
-      return _builder.hasOptionalImportMessage()
-    }
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum optional_nested_enum = 21;</code>
-     */
-    var optionalNestedEnum: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum
-      @JvmName("getOptionalNestedEnum")
-      get() = _builder.getOptionalNestedEnum()
-      @JvmName("setOptionalNestedEnum")
-      set(value) {
-        _builder.setOptionalNestedEnum(value)
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum optional_nested_enum = 21;</code>
-     */
-    fun clearOptionalNestedEnum() {
-      _builder.clearOptionalNestedEnum()
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum optional_nested_enum = 21;</code>
-     * @return Whether the optionalNestedEnum field is set.
-     */
-    fun hasOptionalNestedEnum(): kotlin.Boolean {
-      return _builder.hasOptionalNestedEnum()
-    }
-
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite optional_foreign_enum = 22;</code>
-     */
-    var optionalForeignEnum: com.google.protobuf.UnittestLite.ForeignEnumLite
-      @JvmName("getOptionalForeignEnum")
-      get() = _builder.getOptionalForeignEnum()
-      @JvmName("setOptionalForeignEnum")
-      set(value) {
-        _builder.setOptionalForeignEnum(value)
-      }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite optional_foreign_enum = 22;</code>
-     */
-    fun clearOptionalForeignEnum() {
-      _builder.clearOptionalForeignEnum()
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite optional_foreign_enum = 22;</code>
-     * @return Whether the optionalForeignEnum field is set.
-     */
-    fun hasOptionalForeignEnum(): kotlin.Boolean {
-      return _builder.hasOptionalForeignEnum()
-    }
-
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnumLite optional_import_enum = 23;</code>
-     */
-    var optionalImportEnum: com.google.protobuf.UnittestImportLite.ImportEnumLite
-      @JvmName("getOptionalImportEnum")
-      get() = _builder.getOptionalImportEnum()
-      @JvmName("setOptionalImportEnum")
-      set(value) {
-        _builder.setOptionalImportEnum(value)
-      }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnumLite optional_import_enum = 23;</code>
-     */
-    fun clearOptionalImportEnum() {
-      _builder.clearOptionalImportEnum()
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnumLite optional_import_enum = 23;</code>
-     * @return Whether the optionalImportEnum field is set.
-     */
-    fun hasOptionalImportEnum(): kotlin.Boolean {
-      return _builder.hasOptionalImportEnum()
-    }
-
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     */
-    var optionalStringPiece: kotlin.String
-      @JvmName("getOptionalStringPiece")
-      get() = _builder.getOptionalStringPiece()
-      @JvmName("setOptionalStringPiece")
-      set(value) {
-        _builder.setOptionalStringPiece(value)
-      }
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     */
-    fun clearOptionalStringPiece() {
-      _builder.clearOptionalStringPiece()
-    }
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @return Whether the optionalStringPiece field is set.
-     */
-    fun hasOptionalStringPiece(): kotlin.Boolean {
-      return _builder.hasOptionalStringPiece()
-    }
-
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     */
-    var optionalCord: kotlin.String
-      @JvmName("getOptionalCord")
-      get() = _builder.getOptionalCord()
-      @JvmName("setOptionalCord")
-      set(value) {
-        _builder.setOptionalCord(value)
-      }
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     */
-    fun clearOptionalCord() {
-      _builder.clearOptionalCord()
-    }
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     * @return Whether the optionalCord field is set.
-     */
-    fun hasOptionalCord(): kotlin.Boolean {
-      return _builder.hasOptionalCord()
-    }
-
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>optional .protobuf_unittest_import.PublicImportMessageLite optional_public_import_message = 26;</code>
-     */
-    var optionalPublicImportMessage: com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite
-      @JvmName("getOptionalPublicImportMessage")
-      get() = _builder.getOptionalPublicImportMessage()
-      @JvmName("setOptionalPublicImportMessage")
-      set(value) {
-        _builder.setOptionalPublicImportMessage(value)
-      }
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>optional .protobuf_unittest_import.PublicImportMessageLite optional_public_import_message = 26;</code>
-     */
-    fun clearOptionalPublicImportMessage() {
-      _builder.clearOptionalPublicImportMessage()
-    }
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>optional .protobuf_unittest_import.PublicImportMessageLite optional_public_import_message = 26;</code>
-     * @return Whether the optionalPublicImportMessage field is set.
-     */
-    fun hasOptionalPublicImportMessage(): kotlin.Boolean {
-      return _builder.hasOptionalPublicImportMessage()
-    }
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     */
-    var optionalLazyMessage: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage
-      @JvmName("getOptionalLazyMessage")
-      get() = _builder.getOptionalLazyMessage()
-      @JvmName("setOptionalLazyMessage")
-      set(value) {
-        _builder.setOptionalLazyMessage(value)
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     */
-    fun clearOptionalLazyMessage() {
-      _builder.clearOptionalLazyMessage()
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     * @return Whether the optionalLazyMessage field is set.
-     */
-    fun hasOptionalLazyMessage(): kotlin.Boolean {
-      return _builder.hasOptionalLazyMessage()
-    }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedInt32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     */
-     val repeatedInt32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedInt32List()
-      )
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param value The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedInt32(value)
-    }/**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param value The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedInt32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param values The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedInt32(values)
-    }/**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param values The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedInt32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedInt32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedInt32(index, value)
-    }/**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.clear() {
-      _builder.clearRepeatedInt32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedInt64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     */
-     val repeatedInt64: com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedInt64List()
-      )
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param value The repeatedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedInt64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>.add(value: kotlin.Long) {
-      _builder.addRepeatedInt64(value)
-    }/**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param value The repeatedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedInt64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param values The repeatedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedInt64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllRepeatedInt64(values)
-    }/**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param values The repeatedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedInt64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedInt64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setRepeatedInt64(index, value)
-    }/**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedInt64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>.clear() {
-      _builder.clearRepeatedInt64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedUint32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     */
-     val repeatedUint32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedUint32List()
-      )
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param value The repeatedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedUint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedUint32(value)
-    }/**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param value The repeatedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedUint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param values The repeatedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedUint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedUint32(values)
-    }/**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param values The repeatedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedUint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedUint32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedUint32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedUint32(index, value)
-    }/**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedUint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>.clear() {
-      _builder.clearRepeatedUint32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedUint64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     */
-     val repeatedUint64: com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedUint64List()
-      )
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param value The repeatedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedUint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>.add(value: kotlin.Long) {
-      _builder.addRepeatedUint64(value)
-    }/**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param value The repeatedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedUint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param values The repeatedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedUint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllRepeatedUint64(values)
-    }/**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param values The repeatedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedUint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedUint64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedUint64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setRepeatedUint64(index, value)
-    }/**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedUint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>.clear() {
-      _builder.clearRepeatedUint64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedSint32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     */
-     val repeatedSint32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedSint32List()
-      )
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param value The repeatedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedSint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedSint32(value)
-    }/**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param value The repeatedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedSint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param values The repeatedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedSint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedSint32(values)
-    }/**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param values The repeatedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedSint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSint32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedSint32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedSint32(index, value)
-    }/**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedSint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>.clear() {
-      _builder.clearRepeatedSint32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedSint64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     */
-     val repeatedSint64: com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedSint64List()
-      )
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param value The repeatedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedSint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>.add(value: kotlin.Long) {
-      _builder.addRepeatedSint64(value)
-    }/**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param value The repeatedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedSint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param values The repeatedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedSint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllRepeatedSint64(values)
-    }/**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param values The repeatedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedSint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSint64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedSint64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setRepeatedSint64(index, value)
-    }/**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedSint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>.clear() {
-      _builder.clearRepeatedSint64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedFixed32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     */
-     val repeatedFixed32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedFixed32List()
-      )
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param value The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedFixed32(value)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param value The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedFixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param values The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedFixed32(values)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param values The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedFixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedFixed32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedFixed32(index, value)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.clear() {
-      _builder.clearRepeatedFixed32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedFixed64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     */
-     val repeatedFixed64: com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedFixed64List()
-      )
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param value The repeatedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedFixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>.add(value: kotlin.Long) {
-      _builder.addRepeatedFixed64(value)
-    }/**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param value The repeatedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedFixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param values The repeatedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedFixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllRepeatedFixed64(values)
-    }/**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param values The repeatedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedFixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedFixed64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setRepeatedFixed64(index, value)
-    }/**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedFixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>.clear() {
-      _builder.clearRepeatedFixed64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedSfixed32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     */
-     val repeatedSfixed32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedSfixed32List()
-      )
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param value The repeatedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedSfixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedSfixed32(value)
-    }/**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param value The repeatedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedSfixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param values The repeatedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedSfixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedSfixed32(values)
-    }/**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param values The repeatedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedSfixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSfixed32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedSfixed32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedSfixed32(index, value)
-    }/**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedSfixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>.clear() {
-      _builder.clearRepeatedSfixed32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedSfixed64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     */
-     val repeatedSfixed64: com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedSfixed64List()
-      )
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param value The repeatedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedSfixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>.add(value: kotlin.Long) {
-      _builder.addRepeatedSfixed64(value)
-    }/**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param value The repeatedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedSfixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param values The repeatedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedSfixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllRepeatedSfixed64(values)
-    }/**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param values The repeatedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedSfixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSfixed64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedSfixed64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setRepeatedSfixed64(index, value)
-    }/**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedSfixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>.clear() {
-      _builder.clearRepeatedSfixed64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedFloatProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     */
-     val repeatedFloat: com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedFloatList()
-      )
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param value The repeatedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedFloat")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>.add(value: kotlin.Float) {
-      _builder.addRepeatedFloat(value)
-    }/**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param value The repeatedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedFloat")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>.plusAssign(value: kotlin.Float) {
-      add(value)
-    }/**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param values The repeatedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedFloat")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>.addAll(values: kotlin.collections.Iterable<kotlin.Float>) {
-      _builder.addAllRepeatedFloat(values)
-    }/**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param values The repeatedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedFloat")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Float>) {
-      addAll(values)
-    }/**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFloat to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedFloat")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>.set(index: kotlin.Int, value: kotlin.Float) {
-      _builder.setRepeatedFloat(index, value)
-    }/**
-     * <code>repeated float repeated_float = 41;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedFloat")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>.clear() {
-      _builder.clearRepeatedFloat()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedDoubleProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     */
-     val repeatedDouble: com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedDoubleList()
-      )
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param value The repeatedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedDouble")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>.add(value: kotlin.Double) {
-      _builder.addRepeatedDouble(value)
-    }/**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param value The repeatedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedDouble")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>.plusAssign(value: kotlin.Double) {
-      add(value)
-    }/**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param values The repeatedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedDouble")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>.addAll(values: kotlin.collections.Iterable<kotlin.Double>) {
-      _builder.addAllRepeatedDouble(values)
-    }/**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param values The repeatedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedDouble")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Double>) {
-      addAll(values)
-    }/**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedDouble to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedDouble")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>.set(index: kotlin.Int, value: kotlin.Double) {
-      _builder.setRepeatedDouble(index, value)
-    }/**
-     * <code>repeated double repeated_double = 42;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedDouble")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>.clear() {
-      _builder.clearRepeatedDouble()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedBoolProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     */
-     val repeatedBool: com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedBoolList()
-      )
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param value The repeatedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedBool")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>.add(value: kotlin.Boolean) {
-      _builder.addRepeatedBool(value)
-    }/**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param value The repeatedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedBool")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>.plusAssign(value: kotlin.Boolean) {
-      add(value)
-    }/**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param values The repeatedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedBool")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>.addAll(values: kotlin.collections.Iterable<kotlin.Boolean>) {
-      _builder.addAllRepeatedBool(values)
-    }/**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param values The repeatedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedBool")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Boolean>) {
-      addAll(values)
-    }/**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedBool to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedBool")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>.set(index: kotlin.Int, value: kotlin.Boolean) {
-      _builder.setRepeatedBool(index, value)
-    }/**
-     * <code>repeated bool repeated_bool = 43;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedBool")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>.clear() {
-      _builder.clearRepeatedBool()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedStringProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @return A list containing the repeatedString.
-     */
-    val repeatedString: com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringProxy>
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedStringList()
-      )
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param value The repeatedString to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedString")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringProxy>.add(value: kotlin.String) {
-      _builder.addRepeatedString(value)
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param value The repeatedString to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedString")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringProxy>.plusAssign(value: kotlin.String) {
-      add(value)
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param values The repeatedString to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedString")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringProxy>.addAll(values: kotlin.collections.Iterable<kotlin.String>) {
-      _builder.addAllRepeatedString(values)
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param values The repeatedString to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedString")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.String>) {
-      addAll(values)
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedString to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedString")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringProxy>.set(index: kotlin.Int, value: kotlin.String) {
-      _builder.setRepeatedString(index, value)
-    }/**
-     * <code>repeated string repeated_string = 44;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedString")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringProxy>.clear() {
-      _builder.clearRepeatedString()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedBytesProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     */
-     val repeatedBytes: com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, RepeatedBytesProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedBytesList()
-      )
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param value The repeatedBytes to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedBytes")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, RepeatedBytesProxy>.add(value: com.google.protobuf.ByteString) {
-      _builder.addRepeatedBytes(value)
-    }/**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param value The repeatedBytes to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedBytes")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, RepeatedBytesProxy>.plusAssign(value: com.google.protobuf.ByteString) {
-      add(value)
-    }/**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param values The repeatedBytes to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedBytes")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, RepeatedBytesProxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.ByteString>) {
-      _builder.addAllRepeatedBytes(values)
-    }/**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param values The repeatedBytes to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedBytes")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, RepeatedBytesProxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.ByteString>) {
-      addAll(values)
-    }/**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedBytes to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedBytes")
-    operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, RepeatedBytesProxy>.set(index: kotlin.Int, value: com.google.protobuf.ByteString) {
-      _builder.setRepeatedBytes(index, value)
-    }/**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedBytes")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, RepeatedBytesProxy>.clear() {
-      _builder.clearRepeatedBytes()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedGroupProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-     val repeatedGroup: com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup, RepeatedGroupProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedGroupList()
-      )
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     * @param value The repeatedgroup to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedGroup")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup, RepeatedGroupProxy>.add(value: com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup) {
-      _builder.addRepeatedGroup(value)
-    }/**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     * @param value The repeatedgroup to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedGroup")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup, RepeatedGroupProxy>.plusAssign(value: com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup) {
-      add(value)
-    }/**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     * @param values The repeatedgroup to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedGroup")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup, RepeatedGroupProxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup>) {
-      _builder.addAllRepeatedGroup(values)
-    }/**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     * @param values The repeatedgroup to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedGroup")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup, RepeatedGroupProxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup>) {
-      addAll(values)
-    }/**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedgroup to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedGroup")
-    operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup, RepeatedGroupProxy>.set(index: kotlin.Int, value: com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup) {
-      _builder.setRepeatedGroup(index, value)
-    }/**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedGroup")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup, RepeatedGroupProxy>.clear() {
-      _builder.clearRepeatedGroup()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedNestedMessageProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     */
-     val repeatedNestedMessage: com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage, RepeatedNestedMessageProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedNestedMessageList()
-      )
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     * @param value The repeatedNestedMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedNestedMessage")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage, RepeatedNestedMessageProxy>.add(value: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage) {
-      _builder.addRepeatedNestedMessage(value)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     * @param value The repeatedNestedMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedNestedMessage")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage, RepeatedNestedMessageProxy>.plusAssign(value: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage) {
-      add(value)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     * @param values The repeatedNestedMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedNestedMessage")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage, RepeatedNestedMessageProxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage>) {
-      _builder.addAllRepeatedNestedMessage(values)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     * @param values The repeatedNestedMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedNestedMessage")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage, RepeatedNestedMessageProxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage>) {
-      addAll(values)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedNestedMessage to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedNestedMessage")
-    operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage, RepeatedNestedMessageProxy>.set(index: kotlin.Int, value: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage) {
-      _builder.setRepeatedNestedMessage(index, value)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedNestedMessage")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage, RepeatedNestedMessageProxy>.clear() {
-      _builder.clearRepeatedNestedMessage()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedForeignMessageProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     */
-     val repeatedForeignMessage: com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignMessageLite, RepeatedForeignMessageProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedForeignMessageList()
-      )
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     * @param value The repeatedForeignMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedForeignMessage")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignMessageLite, RepeatedForeignMessageProxy>.add(value: com.google.protobuf.UnittestLite.ForeignMessageLite) {
-      _builder.addRepeatedForeignMessage(value)
-    }/**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     * @param value The repeatedForeignMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedForeignMessage")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignMessageLite, RepeatedForeignMessageProxy>.plusAssign(value: com.google.protobuf.UnittestLite.ForeignMessageLite) {
-      add(value)
-    }/**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     * @param values The repeatedForeignMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedForeignMessage")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignMessageLite, RepeatedForeignMessageProxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.ForeignMessageLite>) {
-      _builder.addAllRepeatedForeignMessage(values)
-    }/**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     * @param values The repeatedForeignMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedForeignMessage")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignMessageLite, RepeatedForeignMessageProxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.ForeignMessageLite>) {
-      addAll(values)
-    }/**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedForeignMessage to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedForeignMessage")
-    operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignMessageLite, RepeatedForeignMessageProxy>.set(index: kotlin.Int, value: com.google.protobuf.UnittestLite.ForeignMessageLite) {
-      _builder.setRepeatedForeignMessage(index, value)
-    }/**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedForeignMessage")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignMessageLite, RepeatedForeignMessageProxy>.clear() {
-      _builder.clearRepeatedForeignMessage()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedImportMessageProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     */
-     val repeatedImportMessage: com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestImportLite.ImportMessageLite, RepeatedImportMessageProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedImportMessageList()
-      )
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     * @param value The repeatedImportMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedImportMessage")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestImportLite.ImportMessageLite, RepeatedImportMessageProxy>.add(value: com.google.protobuf.UnittestImportLite.ImportMessageLite) {
-      _builder.addRepeatedImportMessage(value)
-    }/**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     * @param value The repeatedImportMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedImportMessage")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestImportLite.ImportMessageLite, RepeatedImportMessageProxy>.plusAssign(value: com.google.protobuf.UnittestImportLite.ImportMessageLite) {
-      add(value)
-    }/**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     * @param values The repeatedImportMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedImportMessage")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestImportLite.ImportMessageLite, RepeatedImportMessageProxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.UnittestImportLite.ImportMessageLite>) {
-      _builder.addAllRepeatedImportMessage(values)
-    }/**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     * @param values The repeatedImportMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedImportMessage")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestImportLite.ImportMessageLite, RepeatedImportMessageProxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.UnittestImportLite.ImportMessageLite>) {
-      addAll(values)
-    }/**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedImportMessage to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedImportMessage")
-    operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestImportLite.ImportMessageLite, RepeatedImportMessageProxy>.set(index: kotlin.Int, value: com.google.protobuf.UnittestImportLite.ImportMessageLite) {
-      _builder.setRepeatedImportMessage(index, value)
-    }/**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedImportMessage")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestImportLite.ImportMessageLite, RepeatedImportMessageProxy>.clear() {
-      _builder.clearRepeatedImportMessage()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedNestedEnumProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-     */
-     val repeatedNestedEnum: com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum, RepeatedNestedEnumProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedNestedEnumList()
-      )
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-     * @param value The repeatedNestedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedNestedEnum")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum, RepeatedNestedEnumProxy>.add(value: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum) {
-      _builder.addRepeatedNestedEnum(value)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-     * @param value The repeatedNestedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedNestedEnum")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum, RepeatedNestedEnumProxy>.plusAssign(value: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum) {
-      add(value)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-     * @param values The repeatedNestedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedNestedEnum")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum, RepeatedNestedEnumProxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum>) {
-      _builder.addAllRepeatedNestedEnum(values)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-     * @param values The repeatedNestedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedNestedEnum")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum, RepeatedNestedEnumProxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum>) {
-      addAll(values)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedNestedEnum to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedNestedEnum")
-    operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum, RepeatedNestedEnumProxy>.set(index: kotlin.Int, value: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum) {
-      _builder.setRepeatedNestedEnum(index, value)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedNestedEnum")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum, RepeatedNestedEnumProxy>.clear() {
-      _builder.clearRepeatedNestedEnum()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedForeignEnumProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-     */
-     val repeatedForeignEnum: com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignEnumLite, RepeatedForeignEnumProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedForeignEnumList()
-      )
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-     * @param value The repeatedForeignEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedForeignEnum")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignEnumLite, RepeatedForeignEnumProxy>.add(value: com.google.protobuf.UnittestLite.ForeignEnumLite) {
-      _builder.addRepeatedForeignEnum(value)
-    }/**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-     * @param value The repeatedForeignEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedForeignEnum")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignEnumLite, RepeatedForeignEnumProxy>.plusAssign(value: com.google.protobuf.UnittestLite.ForeignEnumLite) {
-      add(value)
-    }/**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-     * @param values The repeatedForeignEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedForeignEnum")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignEnumLite, RepeatedForeignEnumProxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.ForeignEnumLite>) {
-      _builder.addAllRepeatedForeignEnum(values)
-    }/**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-     * @param values The repeatedForeignEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedForeignEnum")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignEnumLite, RepeatedForeignEnumProxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.ForeignEnumLite>) {
-      addAll(values)
-    }/**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedForeignEnum to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedForeignEnum")
-    operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignEnumLite, RepeatedForeignEnumProxy>.set(index: kotlin.Int, value: com.google.protobuf.UnittestLite.ForeignEnumLite) {
-      _builder.setRepeatedForeignEnum(index, value)
-    }/**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedForeignEnum")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignEnumLite, RepeatedForeignEnumProxy>.clear() {
-      _builder.clearRepeatedForeignEnum()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedImportEnumProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-     */
-     val repeatedImportEnum: com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestImportLite.ImportEnumLite, RepeatedImportEnumProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedImportEnumList()
-      )
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-     * @param value The repeatedImportEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedImportEnum")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestImportLite.ImportEnumLite, RepeatedImportEnumProxy>.add(value: com.google.protobuf.UnittestImportLite.ImportEnumLite) {
-      _builder.addRepeatedImportEnum(value)
-    }/**
-     * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-     * @param value The repeatedImportEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedImportEnum")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestImportLite.ImportEnumLite, RepeatedImportEnumProxy>.plusAssign(value: com.google.protobuf.UnittestImportLite.ImportEnumLite) {
-      add(value)
-    }/**
-     * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-     * @param values The repeatedImportEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedImportEnum")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestImportLite.ImportEnumLite, RepeatedImportEnumProxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.UnittestImportLite.ImportEnumLite>) {
-      _builder.addAllRepeatedImportEnum(values)
-    }/**
-     * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-     * @param values The repeatedImportEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedImportEnum")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestImportLite.ImportEnumLite, RepeatedImportEnumProxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.UnittestImportLite.ImportEnumLite>) {
-      addAll(values)
-    }/**
-     * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedImportEnum to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedImportEnum")
-    operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestImportLite.ImportEnumLite, RepeatedImportEnumProxy>.set(index: kotlin.Int, value: com.google.protobuf.UnittestImportLite.ImportEnumLite) {
-      _builder.setRepeatedImportEnum(index, value)
-    }/**
-     * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedImportEnum")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestImportLite.ImportEnumLite, RepeatedImportEnumProxy>.clear() {
-      _builder.clearRepeatedImportEnum()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedStringPieceProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @return A list containing the repeatedStringPiece.
-     */
-    val repeatedStringPiece: com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringPieceProxy>
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedStringPieceList()
-      )
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param value The repeatedStringPiece to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedStringPiece")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringPieceProxy>.add(value: kotlin.String) {
-      _builder.addRepeatedStringPiece(value)
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param value The repeatedStringPiece to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedStringPiece")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringPieceProxy>.plusAssign(value: kotlin.String) {
-      add(value)
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param values The repeatedStringPiece to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedStringPiece")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringPieceProxy>.addAll(values: kotlin.collections.Iterable<kotlin.String>) {
-      _builder.addAllRepeatedStringPiece(values)
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param values The repeatedStringPiece to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedStringPiece")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringPieceProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.String>) {
-      addAll(values)
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedStringPiece to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedStringPiece")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringPieceProxy>.set(index: kotlin.Int, value: kotlin.String) {
-      _builder.setRepeatedStringPiece(index, value)
-    }/**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedStringPiece")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringPieceProxy>.clear() {
-      _builder.clearRepeatedStringPiece()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedCordProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @return A list containing the repeatedCord.
-     */
-    val repeatedCord: com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedCordProxy>
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedCordList()
-      )
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param value The repeatedCord to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedCord")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedCordProxy>.add(value: kotlin.String) {
-      _builder.addRepeatedCord(value)
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param value The repeatedCord to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedCord")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedCordProxy>.plusAssign(value: kotlin.String) {
-      add(value)
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param values The repeatedCord to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedCord")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedCordProxy>.addAll(values: kotlin.collections.Iterable<kotlin.String>) {
-      _builder.addAllRepeatedCord(values)
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param values The repeatedCord to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedCord")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedCordProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.String>) {
-      addAll(values)
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedCord to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedCord")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedCordProxy>.set(index: kotlin.Int, value: kotlin.String) {
-      _builder.setRepeatedCord(index, value)
-    }/**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedCord")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedCordProxy>.clear() {
-      _builder.clearRepeatedCord()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedLazyMessageProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-     val repeatedLazyMessage: com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage, RepeatedLazyMessageProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedLazyMessageList()
-      )
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     * @param value The repeatedLazyMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedLazyMessage")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage, RepeatedLazyMessageProxy>.add(value: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage) {
-      _builder.addRepeatedLazyMessage(value)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     * @param value The repeatedLazyMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedLazyMessage")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage, RepeatedLazyMessageProxy>.plusAssign(value: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage) {
-      add(value)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     * @param values The repeatedLazyMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedLazyMessage")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage, RepeatedLazyMessageProxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage>) {
-      _builder.addAllRepeatedLazyMessage(values)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     * @param values The repeatedLazyMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedLazyMessage")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage, RepeatedLazyMessageProxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage>) {
-      addAll(values)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedLazyMessage to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedLazyMessage")
-    operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage, RepeatedLazyMessageProxy>.set(index: kotlin.Int, value: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage) {
-      _builder.setRepeatedLazyMessage(index, value)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedLazyMessage")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage, RepeatedLazyMessageProxy>.clear() {
-      _builder.clearRepeatedLazyMessage()
-    }
-    /**
-     * <pre>
-     * Singular with defaults
-     * </pre>
-     *
-     * <code>optional int32 default_int32 = 61 [default = 41];</code>
-     */
-    var defaultInt32: kotlin.Int
-      @JvmName("getDefaultInt32")
-      get() = _builder.getDefaultInt32()
-      @JvmName("setDefaultInt32")
-      set(value) {
-        _builder.setDefaultInt32(value)
-      }
-    /**
-     * <pre>
-     * Singular with defaults
-     * </pre>
-     *
-     * <code>optional int32 default_int32 = 61 [default = 41];</code>
-     */
-    fun clearDefaultInt32() {
-      _builder.clearDefaultInt32()
-    }
-    /**
-     * <pre>
-     * Singular with defaults
-     * </pre>
-     *
-     * <code>optional int32 default_int32 = 61 [default = 41];</code>
-     * @return Whether the defaultInt32 field is set.
-     */
-    fun hasDefaultInt32(): kotlin.Boolean {
-      return _builder.hasDefaultInt32()
-    }
-
-    /**
-     * <code>optional int64 default_int64 = 62 [default = 42];</code>
-     */
-    var defaultInt64: kotlin.Long
-      @JvmName("getDefaultInt64")
-      get() = _builder.getDefaultInt64()
-      @JvmName("setDefaultInt64")
-      set(value) {
-        _builder.setDefaultInt64(value)
-      }
-    /**
-     * <code>optional int64 default_int64 = 62 [default = 42];</code>
-     */
-    fun clearDefaultInt64() {
-      _builder.clearDefaultInt64()
-    }
-    /**
-     * <code>optional int64 default_int64 = 62 [default = 42];</code>
-     * @return Whether the defaultInt64 field is set.
-     */
-    fun hasDefaultInt64(): kotlin.Boolean {
-      return _builder.hasDefaultInt64()
-    }
-
-    /**
-     * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-     */
-    var defaultUint32: kotlin.Int
-      @JvmName("getDefaultUint32")
-      get() = _builder.getDefaultUint32()
-      @JvmName("setDefaultUint32")
-      set(value) {
-        _builder.setDefaultUint32(value)
-      }
-    /**
-     * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-     */
-    fun clearDefaultUint32() {
-      _builder.clearDefaultUint32()
-    }
-    /**
-     * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-     * @return Whether the defaultUint32 field is set.
-     */
-    fun hasDefaultUint32(): kotlin.Boolean {
-      return _builder.hasDefaultUint32()
-    }
-
-    /**
-     * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-     */
-    var defaultUint64: kotlin.Long
-      @JvmName("getDefaultUint64")
-      get() = _builder.getDefaultUint64()
-      @JvmName("setDefaultUint64")
-      set(value) {
-        _builder.setDefaultUint64(value)
-      }
-    /**
-     * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-     */
-    fun clearDefaultUint64() {
-      _builder.clearDefaultUint64()
-    }
-    /**
-     * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-     * @return Whether the defaultUint64 field is set.
-     */
-    fun hasDefaultUint64(): kotlin.Boolean {
-      return _builder.hasDefaultUint64()
-    }
-
-    /**
-     * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-     */
-    var defaultSint32: kotlin.Int
-      @JvmName("getDefaultSint32")
-      get() = _builder.getDefaultSint32()
-      @JvmName("setDefaultSint32")
-      set(value) {
-        _builder.setDefaultSint32(value)
-      }
-    /**
-     * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-     */
-    fun clearDefaultSint32() {
-      _builder.clearDefaultSint32()
-    }
-    /**
-     * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-     * @return Whether the defaultSint32 field is set.
-     */
-    fun hasDefaultSint32(): kotlin.Boolean {
-      return _builder.hasDefaultSint32()
-    }
-
-    /**
-     * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-     */
-    var defaultSint64: kotlin.Long
-      @JvmName("getDefaultSint64")
-      get() = _builder.getDefaultSint64()
-      @JvmName("setDefaultSint64")
-      set(value) {
-        _builder.setDefaultSint64(value)
-      }
-    /**
-     * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-     */
-    fun clearDefaultSint64() {
-      _builder.clearDefaultSint64()
-    }
-    /**
-     * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-     * @return Whether the defaultSint64 field is set.
-     */
-    fun hasDefaultSint64(): kotlin.Boolean {
-      return _builder.hasDefaultSint64()
-    }
-
-    /**
-     * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-     */
-    var defaultFixed32: kotlin.Int
-      @JvmName("getDefaultFixed32")
-      get() = _builder.getDefaultFixed32()
-      @JvmName("setDefaultFixed32")
-      set(value) {
-        _builder.setDefaultFixed32(value)
-      }
-    /**
-     * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-     */
-    fun clearDefaultFixed32() {
-      _builder.clearDefaultFixed32()
-    }
-    /**
-     * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-     * @return Whether the defaultFixed32 field is set.
-     */
-    fun hasDefaultFixed32(): kotlin.Boolean {
-      return _builder.hasDefaultFixed32()
-    }
-
-    /**
-     * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-     */
-    var defaultFixed64: kotlin.Long
-      @JvmName("getDefaultFixed64")
-      get() = _builder.getDefaultFixed64()
-      @JvmName("setDefaultFixed64")
-      set(value) {
-        _builder.setDefaultFixed64(value)
-      }
-    /**
-     * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-     */
-    fun clearDefaultFixed64() {
-      _builder.clearDefaultFixed64()
-    }
-    /**
-     * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-     * @return Whether the defaultFixed64 field is set.
-     */
-    fun hasDefaultFixed64(): kotlin.Boolean {
-      return _builder.hasDefaultFixed64()
-    }
-
-    /**
-     * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-     */
-    var defaultSfixed32: kotlin.Int
-      @JvmName("getDefaultSfixed32")
-      get() = _builder.getDefaultSfixed32()
-      @JvmName("setDefaultSfixed32")
-      set(value) {
-        _builder.setDefaultSfixed32(value)
-      }
-    /**
-     * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-     */
-    fun clearDefaultSfixed32() {
-      _builder.clearDefaultSfixed32()
-    }
-    /**
-     * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-     * @return Whether the defaultSfixed32 field is set.
-     */
-    fun hasDefaultSfixed32(): kotlin.Boolean {
-      return _builder.hasDefaultSfixed32()
-    }
-
-    /**
-     * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-     */
-    var defaultSfixed64: kotlin.Long
-      @JvmName("getDefaultSfixed64")
-      get() = _builder.getDefaultSfixed64()
-      @JvmName("setDefaultSfixed64")
-      set(value) {
-        _builder.setDefaultSfixed64(value)
-      }
-    /**
-     * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-     */
-    fun clearDefaultSfixed64() {
-      _builder.clearDefaultSfixed64()
-    }
-    /**
-     * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-     * @return Whether the defaultSfixed64 field is set.
-     */
-    fun hasDefaultSfixed64(): kotlin.Boolean {
-      return _builder.hasDefaultSfixed64()
-    }
-
-    /**
-     * <code>optional float default_float = 71 [default = 51.5];</code>
-     */
-    var defaultFloat: kotlin.Float
-      @JvmName("getDefaultFloat")
-      get() = _builder.getDefaultFloat()
-      @JvmName("setDefaultFloat")
-      set(value) {
-        _builder.setDefaultFloat(value)
-      }
-    /**
-     * <code>optional float default_float = 71 [default = 51.5];</code>
-     */
-    fun clearDefaultFloat() {
-      _builder.clearDefaultFloat()
-    }
-    /**
-     * <code>optional float default_float = 71 [default = 51.5];</code>
-     * @return Whether the defaultFloat field is set.
-     */
-    fun hasDefaultFloat(): kotlin.Boolean {
-      return _builder.hasDefaultFloat()
-    }
-
-    /**
-     * <code>optional double default_double = 72 [default = 52000];</code>
-     */
-    var defaultDouble: kotlin.Double
-      @JvmName("getDefaultDouble")
-      get() = _builder.getDefaultDouble()
-      @JvmName("setDefaultDouble")
-      set(value) {
-        _builder.setDefaultDouble(value)
-      }
-    /**
-     * <code>optional double default_double = 72 [default = 52000];</code>
-     */
-    fun clearDefaultDouble() {
-      _builder.clearDefaultDouble()
-    }
-    /**
-     * <code>optional double default_double = 72 [default = 52000];</code>
-     * @return Whether the defaultDouble field is set.
-     */
-    fun hasDefaultDouble(): kotlin.Boolean {
-      return _builder.hasDefaultDouble()
-    }
-
-    /**
-     * <code>optional bool default_bool = 73 [default = true];</code>
-     */
-    var defaultBool: kotlin.Boolean
-      @JvmName("getDefaultBool")
-      get() = _builder.getDefaultBool()
-      @JvmName("setDefaultBool")
-      set(value) {
-        _builder.setDefaultBool(value)
-      }
-    /**
-     * <code>optional bool default_bool = 73 [default = true];</code>
-     */
-    fun clearDefaultBool() {
-      _builder.clearDefaultBool()
-    }
-    /**
-     * <code>optional bool default_bool = 73 [default = true];</code>
-     * @return Whether the defaultBool field is set.
-     */
-    fun hasDefaultBool(): kotlin.Boolean {
-      return _builder.hasDefaultBool()
-    }
-
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     */
-    var defaultString: kotlin.String
-      @JvmName("getDefaultString")
-      get() = _builder.getDefaultString()
-      @JvmName("setDefaultString")
-      set(value) {
-        _builder.setDefaultString(value)
-      }
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     */
-    fun clearDefaultString() {
-      _builder.clearDefaultString()
-    }
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     * @return Whether the defaultString field is set.
-     */
-    fun hasDefaultString(): kotlin.Boolean {
-      return _builder.hasDefaultString()
-    }
-
-    /**
-     * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-     */
-    var defaultBytes: com.google.protobuf.ByteString
-      @JvmName("getDefaultBytes")
-      get() = _builder.getDefaultBytes()
-      @JvmName("setDefaultBytes")
-      set(value) {
-        _builder.setDefaultBytes(value)
-      }
-    /**
-     * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-     */
-    fun clearDefaultBytes() {
-      _builder.clearDefaultBytes()
-    }
-    /**
-     * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-     * @return Whether the defaultBytes field is set.
-     */
-    fun hasDefaultBytes(): kotlin.Boolean {
-      return _builder.hasDefaultBytes()
-    }
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-     */
-    var defaultNestedEnum: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum
-      @JvmName("getDefaultNestedEnum")
-      get() = _builder.getDefaultNestedEnum()
-      @JvmName("setDefaultNestedEnum")
-      set(value) {
-        _builder.setDefaultNestedEnum(value)
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-     */
-    fun clearDefaultNestedEnum() {
-      _builder.clearDefaultNestedEnum()
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-     * @return Whether the defaultNestedEnum field is set.
-     */
-    fun hasDefaultNestedEnum(): kotlin.Boolean {
-      return _builder.hasDefaultNestedEnum()
-    }
-
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite default_foreign_enum = 82 [default = FOREIGN_LITE_BAR];</code>
-     */
-    var defaultForeignEnum: com.google.protobuf.UnittestLite.ForeignEnumLite
-      @JvmName("getDefaultForeignEnum")
-      get() = _builder.getDefaultForeignEnum()
-      @JvmName("setDefaultForeignEnum")
-      set(value) {
-        _builder.setDefaultForeignEnum(value)
-      }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite default_foreign_enum = 82 [default = FOREIGN_LITE_BAR];</code>
-     */
-    fun clearDefaultForeignEnum() {
-      _builder.clearDefaultForeignEnum()
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite default_foreign_enum = 82 [default = FOREIGN_LITE_BAR];</code>
-     * @return Whether the defaultForeignEnum field is set.
-     */
-    fun hasDefaultForeignEnum(): kotlin.Boolean {
-      return _builder.hasDefaultForeignEnum()
-    }
-
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnumLite default_import_enum = 83 [default = IMPORT_LITE_BAR];</code>
-     */
-    var defaultImportEnum: com.google.protobuf.UnittestImportLite.ImportEnumLite
-      @JvmName("getDefaultImportEnum")
-      get() = _builder.getDefaultImportEnum()
-      @JvmName("setDefaultImportEnum")
-      set(value) {
-        _builder.setDefaultImportEnum(value)
-      }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnumLite default_import_enum = 83 [default = IMPORT_LITE_BAR];</code>
-     */
-    fun clearDefaultImportEnum() {
-      _builder.clearDefaultImportEnum()
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnumLite default_import_enum = 83 [default = IMPORT_LITE_BAR];</code>
-     * @return Whether the defaultImportEnum field is set.
-     */
-    fun hasDefaultImportEnum(): kotlin.Boolean {
-      return _builder.hasDefaultImportEnum()
-    }
-
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     */
-    var defaultStringPiece: kotlin.String
-      @JvmName("getDefaultStringPiece")
-      get() = _builder.getDefaultStringPiece()
-      @JvmName("setDefaultStringPiece")
-      set(value) {
-        _builder.setDefaultStringPiece(value)
-      }
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     */
-    fun clearDefaultStringPiece() {
-      _builder.clearDefaultStringPiece()
-    }
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     * @return Whether the defaultStringPiece field is set.
-     */
-    fun hasDefaultStringPiece(): kotlin.Boolean {
-      return _builder.hasDefaultStringPiece()
-    }
-
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     */
-    var defaultCord: kotlin.String
-      @JvmName("getDefaultCord")
-      get() = _builder.getDefaultCord()
-      @JvmName("setDefaultCord")
-      set(value) {
-        _builder.setDefaultCord(value)
-      }
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     */
-    fun clearDefaultCord() {
-      _builder.clearDefaultCord()
-    }
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     * @return Whether the defaultCord field is set.
-     */
-    fun hasDefaultCord(): kotlin.Boolean {
-      return _builder.hasDefaultCord()
-    }
-
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     */
-    var oneofUint32: kotlin.Int
-      @JvmName("getOneofUint32")
-      get() = _builder.getOneofUint32()
-      @JvmName("setOneofUint32")
-      set(value) {
-        _builder.setOneofUint32(value)
-      }
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     */
-    fun clearOneofUint32() {
-      _builder.clearOneofUint32()
-    }
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     * @return Whether the oneofUint32 field is set.
-     */
-    fun hasOneofUint32(): kotlin.Boolean {
-      return _builder.hasOneofUint32()
-    }
-
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_nested_message = 112;</code>
-     */
-    var oneofNestedMessage: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage
-      @JvmName("getOneofNestedMessage")
-      get() = _builder.getOneofNestedMessage()
-      @JvmName("setOneofNestedMessage")
-      set(value) {
-        _builder.setOneofNestedMessage(value)
-      }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_nested_message = 112;</code>
-     */
-    fun clearOneofNestedMessage() {
-      _builder.clearOneofNestedMessage()
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_nested_message = 112;</code>
-     * @return Whether the oneofNestedMessage field is set.
-     */
-    fun hasOneofNestedMessage(): kotlin.Boolean {
-      return _builder.hasOneofNestedMessage()
-    }
-
-    /**
-     * <code>string oneof_string = 113;</code>
-     */
-    var oneofString: kotlin.String
-      @JvmName("getOneofString")
-      get() = _builder.getOneofString()
-      @JvmName("setOneofString")
-      set(value) {
-        _builder.setOneofString(value)
-      }
-    /**
-     * <code>string oneof_string = 113;</code>
-     */
-    fun clearOneofString() {
-      _builder.clearOneofString()
-    }
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return Whether the oneofString field is set.
-     */
-    fun hasOneofString(): kotlin.Boolean {
-      return _builder.hasOneofString()
-    }
-
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     */
-    var oneofBytes: com.google.protobuf.ByteString
-      @JvmName("getOneofBytes")
-      get() = _builder.getOneofBytes()
-      @JvmName("setOneofBytes")
-      set(value) {
-        _builder.setOneofBytes(value)
-      }
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     */
-    fun clearOneofBytes() {
-      _builder.clearOneofBytes()
-    }
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     * @return Whether the oneofBytes field is set.
-     */
-    fun hasOneofBytes(): kotlin.Boolean {
-      return _builder.hasOneofBytes()
-    }
-
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_lazy_nested_message = 115 [lazy = true];</code>
-     */
-    var oneofLazyNestedMessage: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage
-      @JvmName("getOneofLazyNestedMessage")
-      get() = _builder.getOneofLazyNestedMessage()
-      @JvmName("setOneofLazyNestedMessage")
-      set(value) {
-        _builder.setOneofLazyNestedMessage(value)
-      }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_lazy_nested_message = 115 [lazy = true];</code>
-     */
-    fun clearOneofLazyNestedMessage() {
-      _builder.clearOneofLazyNestedMessage()
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_lazy_nested_message = 115 [lazy = true];</code>
-     * @return Whether the oneofLazyNestedMessage field is set.
-     */
-    fun hasOneofLazyNestedMessage(): kotlin.Boolean {
-      return _builder.hasOneofLazyNestedMessage()
-    }
-
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage2 oneof_nested_message2 = 117;</code>
-     */
-    var oneofNestedMessage2: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2
-      @JvmName("getOneofNestedMessage2")
-      get() = _builder.getOneofNestedMessage2()
-      @JvmName("setOneofNestedMessage2")
-      set(value) {
-        _builder.setOneofNestedMessage2(value)
-      }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage2 oneof_nested_message2 = 117;</code>
-     */
-    fun clearOneofNestedMessage2() {
-      _builder.clearOneofNestedMessage2()
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage2 oneof_nested_message2 = 117;</code>
-     * @return Whether the oneofNestedMessage2 field is set.
-     */
-    fun hasOneofNestedMessage2(): kotlin.Boolean {
-      return _builder.hasOneofNestedMessage2()
-    }
-
-    /**
-     * <pre>
-     * Tests toString for non-repeated fields with a list suffix
-     * </pre>
-     *
-     * <code>optional int32 deceptively_named_list = 116;</code>
-     */
-    var deceptivelyNamedList: kotlin.Int
-      @JvmName("getDeceptivelyNamedList")
-      get() = _builder.getDeceptivelyNamedList()
-      @JvmName("setDeceptivelyNamedList")
-      set(value) {
-        _builder.setDeceptivelyNamedList(value)
-      }
-    /**
-     * <pre>
-     * Tests toString for non-repeated fields with a list suffix
-     * </pre>
-     *
-     * <code>optional int32 deceptively_named_list = 116;</code>
-     */
-    fun clearDeceptivelyNamedList() {
-      _builder.clearDeceptivelyNamedList()
-    }
-    /**
-     * <pre>
-     * Tests toString for non-repeated fields with a list suffix
-     * </pre>
-     *
-     * <code>optional int32 deceptively_named_list = 116;</code>
-     * @return Whether the deceptivelyNamedList field is set.
-     */
-    fun hasDeceptivelyNamedList(): kotlin.Boolean {
-      return _builder.hasDeceptivelyNamedList()
-    }
-    val oneofFieldCase: com.google.protobuf.UnittestLite.TestAllTypesLite.OneofFieldCase
-      @JvmName("getOneofFieldCase")
-      get() = _builder.getOneofFieldCase()
-
-    fun clearOneofField() {
-      _builder.clearOneofField()
-    }
-  }
-  @kotlin.jvm.JvmSynthetic
-  inline fun nestedMessage(block: com.google.protobuf.TestAllTypesLiteKt.NestedMessageKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage =
-    com.google.protobuf.TestAllTypesLiteKt.NestedMessageKt.Dsl._create(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.newBuilder()).apply { block() }._build()
-  object NestedMessageKt {
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    @com.google.protobuf.kotlin.ProtoDslMarker
-    class Dsl private constructor(
-      @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.Builder
-    ) {
-      companion object {
-        @kotlin.jvm.JvmSynthetic
-        @kotlin.PublishedApi
-        internal fun _create(builder: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.Builder): Dsl = Dsl(builder)
-      }
-
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _build(): com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage = _builder.build()
-
-      /**
-       * <code>optional int32 bb = 1;</code>
-       */
-      var bb: kotlin.Int
-        @JvmName("getBb")
-        get() = _builder.getBb()
-        @JvmName("setBb")
-        set(value) {
-          _builder.setBb(value)
-        }
-      /**
-       * <code>optional int32 bb = 1;</code>
-       */
-      fun clearBb() {
-        _builder.clearBb()
-      }
-      /**
-       * <code>optional int32 bb = 1;</code>
-       * @return Whether the bb field is set.
-       */
-      fun hasBb(): kotlin.Boolean {
-        return _builder.hasBb()
-      }
-
-      /**
-       * <code>optional int64 cc = 2;</code>
-       */
-      var cc: kotlin.Long
-        @JvmName("getCc")
-        get() = _builder.getCc()
-        @JvmName("setCc")
-        set(value) {
-          _builder.setCc(value)
-        }
-      /**
-       * <code>optional int64 cc = 2;</code>
-       */
-      fun clearCc() {
-        _builder.clearCc()
-      }
-      /**
-       * <code>optional int64 cc = 2;</code>
-       * @return Whether the cc field is set.
-       */
-      fun hasCc(): kotlin.Boolean {
-        return _builder.hasCc()
-      }
-    }
-  }
-  @kotlin.jvm.JvmSynthetic
-  inline fun nestedMessage2(block: com.google.protobuf.TestAllTypesLiteKt.NestedMessage2Kt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 =
-    com.google.protobuf.TestAllTypesLiteKt.NestedMessage2Kt.Dsl._create(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2.newBuilder()).apply { block() }._build()
-  object NestedMessage2Kt {
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    @com.google.protobuf.kotlin.ProtoDslMarker
-    class Dsl private constructor(
-      @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2.Builder
-    ) {
-      companion object {
-        @kotlin.jvm.JvmSynthetic
-        @kotlin.PublishedApi
-        internal fun _create(builder: com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2.Builder): Dsl = Dsl(builder)
-      }
-
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _build(): com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 = _builder.build()
-
-      /**
-       * <code>optional int32 dd = 1;</code>
-       */
-      var dd: kotlin.Int
-        @JvmName("getDd")
-        get() = _builder.getDd()
-        @JvmName("setDd")
-        set(value) {
-          _builder.setDd(value)
-        }
-      /**
-       * <code>optional int32 dd = 1;</code>
-       */
-      fun clearDd() {
-        _builder.clearDd()
-      }
-      /**
-       * <code>optional int32 dd = 1;</code>
-       * @return Whether the dd field is set.
-       */
-      fun hasDd(): kotlin.Boolean {
-        return _builder.hasDd()
-      }
-    }
-  }
-  @kotlin.jvm.JvmSynthetic
-  inline fun optionalGroup(block: com.google.protobuf.TestAllTypesLiteKt.OptionalGroupKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup =
-    com.google.protobuf.TestAllTypesLiteKt.OptionalGroupKt.Dsl._create(com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup.newBuilder()).apply { block() }._build()
-  object OptionalGroupKt {
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    @com.google.protobuf.kotlin.ProtoDslMarker
-    class Dsl private constructor(
-      @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup.Builder
-    ) {
-      companion object {
-        @kotlin.jvm.JvmSynthetic
-        @kotlin.PublishedApi
-        internal fun _create(builder: com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup.Builder): Dsl = Dsl(builder)
-      }
-
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _build(): com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup = _builder.build()
-
-      /**
-       * <code>optional int32 a = 17;</code>
-       */
-      var a: kotlin.Int
-        @JvmName("getA")
-        get() = _builder.getA()
-        @JvmName("setA")
-        set(value) {
-          _builder.setA(value)
-        }
-      /**
-       * <code>optional int32 a = 17;</code>
-       */
-      fun clearA() {
-        _builder.clearA()
-      }
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return Whether the a field is set.
-       */
-      fun hasA(): kotlin.Boolean {
-        return _builder.hasA()
-      }
-    }
-  }
-  @kotlin.jvm.JvmSynthetic
-  inline fun repeatedGroup(block: com.google.protobuf.TestAllTypesLiteKt.RepeatedGroupKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup =
-    com.google.protobuf.TestAllTypesLiteKt.RepeatedGroupKt.Dsl._create(com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup.newBuilder()).apply { block() }._build()
-  object RepeatedGroupKt {
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    @com.google.protobuf.kotlin.ProtoDslMarker
-    class Dsl private constructor(
-      @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup.Builder
-    ) {
-      companion object {
-        @kotlin.jvm.JvmSynthetic
-        @kotlin.PublishedApi
-        internal fun _create(builder: com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup.Builder): Dsl = Dsl(builder)
-      }
-
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _build(): com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup = _builder.build()
-
-      /**
-       * <code>optional int32 a = 47;</code>
-       */
-      var a: kotlin.Int
-        @JvmName("getA")
-        get() = _builder.getA()
-        @JvmName("setA")
-        set(value) {
-          _builder.setA(value)
-        }
-      /**
-       * <code>optional int32 a = 47;</code>
-       */
-      fun clearA() {
-        _builder.clearA()
-      }
-      /**
-       * <code>optional int32 a = 47;</code>
-       * @return Whether the a field is set.
-       */
-      fun hasA(): kotlin.Boolean {
-        return _builder.hasA()
-      }
-    }
-  }
-}
-inline fun com.google.protobuf.UnittestLite.TestAllTypesLite.copy(block: com.google.protobuf.TestAllTypesLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestAllTypesLite =
-  com.google.protobuf.TestAllTypesLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
-inline fun com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.copy(block: com.google.protobuf.TestAllTypesLiteKt.NestedMessageKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage =
-  com.google.protobuf.TestAllTypesLiteKt.NestedMessageKt.Dsl._create(this.toBuilder()).apply { block() }._build()
-inline fun com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2.copy(block: com.google.protobuf.TestAllTypesLiteKt.NestedMessage2Kt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 =
-  com.google.protobuf.TestAllTypesLiteKt.NestedMessage2Kt.Dsl._create(this.toBuilder()).apply { block() }._build()
-inline fun com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup.copy(block: com.google.protobuf.TestAllTypesLiteKt.OptionalGroupKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup =
-  com.google.protobuf.TestAllTypesLiteKt.OptionalGroupKt.Dsl._create(this.toBuilder()).apply { block() }._build()
-inline fun com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup.copy(block: com.google.protobuf.TestAllTypesLiteKt.RepeatedGroupKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup =
-  com.google.protobuf.TestAllTypesLiteKt.RepeatedGroupKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestDeprecatedLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestDeprecatedLiteKt.kt
deleted file mode 100644
index 354a39f..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestDeprecatedLiteKt.kt
+++ /dev/null
@@ -1,123 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testDeprecatedLite(block: com.google.protobuf.TestDeprecatedLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestDeprecatedLite =
-  com.google.protobuf.TestDeprecatedLiteKt.Dsl._create(com.google.protobuf.UnittestLite.TestDeprecatedLite.newBuilder()).apply { block() }._build()
-object TestDeprecatedLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestDeprecatedLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.TestDeprecatedLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.TestDeprecatedLite = _builder.build()
-
-    /**
-     * <code>optional int32 deprecated_field = 1 [deprecated = true];</code>
-     */
-    @kotlin.Deprecated(message = "Field deprecatedField is deprecated") var deprecatedField: kotlin.Int
-      @JvmName("getDeprecatedField")
-      get() = _builder.getDeprecatedField()
-      @JvmName("setDeprecatedField")
-      set(value) {
-        _builder.setDeprecatedField(value)
-      }
-    /**
-     * <code>optional int32 deprecated_field = 1 [deprecated = true];</code>
-     */
-    fun clearDeprecatedField() {
-      _builder.clearDeprecatedField()
-    }
-    /**
-     * <code>optional int32 deprecated_field = 1 [deprecated = true];</code>
-     * @return Whether the deprecatedField field is set.
-     */
-    fun hasDeprecatedField(): kotlin.Boolean {
-      return _builder.hasDeprecatedField()
-    }
-
-    /**
-     * <code>required int32 deprecated_field2 = 2 [deprecated = true];</code>
-     */
-    @kotlin.Deprecated(message = "Field deprecatedField2 is deprecated") var deprecatedField2: kotlin.Int
-      @JvmName("getDeprecatedField2")
-      get() = _builder.getDeprecatedField2()
-      @JvmName("setDeprecatedField2")
-      set(value) {
-        _builder.setDeprecatedField2(value)
-      }
-    /**
-     * <code>required int32 deprecated_field2 = 2 [deprecated = true];</code>
-     */
-    fun clearDeprecatedField2() {
-      _builder.clearDeprecatedField2()
-    }
-    /**
-     * <code>required int32 deprecated_field2 = 2 [deprecated = true];</code>
-     * @return Whether the deprecatedField2 field is set.
-     */
-    fun hasDeprecatedField2(): kotlin.Boolean {
-      return _builder.hasDeprecatedField2()
-    }
-
-    /**
-     * <code>optional string deprecated_field3 = 3 [deprecated = true];</code>
-     */
-    @kotlin.Deprecated(message = "Field deprecatedField3 is deprecated") var deprecatedField3: kotlin.String
-      @JvmName("getDeprecatedField3")
-      get() = _builder.getDeprecatedField3()
-      @JvmName("setDeprecatedField3")
-      set(value) {
-        _builder.setDeprecatedField3(value)
-      }
-    /**
-     * <code>optional string deprecated_field3 = 3 [deprecated = true];</code>
-     */
-    fun clearDeprecatedField3() {
-      _builder.clearDeprecatedField3()
-    }
-    /**
-     * <code>optional string deprecated_field3 = 3 [deprecated = true];</code>
-     * @return Whether the deprecatedField3 field is set.
-     */
-    fun hasDeprecatedField3(): kotlin.Boolean {
-      return _builder.hasDeprecatedField3()
-    }
-
-    /**
-     * <code>optional .protobuf_unittest.TestDeprecatedLite deprecated_field4 = 4 [deprecated = true];</code>
-     */
-    @kotlin.Deprecated(message = "Field deprecatedField4 is deprecated") var deprecatedField4: com.google.protobuf.UnittestLite.TestDeprecatedLite
-      @JvmName("getDeprecatedField4")
-      get() = _builder.getDeprecatedField4()
-      @JvmName("setDeprecatedField4")
-      set(value) {
-        _builder.setDeprecatedField4(value)
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestDeprecatedLite deprecated_field4 = 4 [deprecated = true];</code>
-     */
-    fun clearDeprecatedField4() {
-      _builder.clearDeprecatedField4()
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestDeprecatedLite deprecated_field4 = 4 [deprecated = true];</code>
-     * @return Whether the deprecatedField4 field is set.
-     */
-    fun hasDeprecatedField4(): kotlin.Boolean {
-      return _builder.hasDeprecatedField4()
-    }
-  }
-}
-inline fun com.google.protobuf.UnittestLite.TestDeprecatedLite.copy(block: com.google.protobuf.TestDeprecatedLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestDeprecatedLite =
-  com.google.protobuf.TestDeprecatedLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestEmptyMessageLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestEmptyMessageLiteKt.kt
deleted file mode 100644
index 2030e70..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestEmptyMessageLiteKt.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testEmptyMessageLite(block: com.google.protobuf.TestEmptyMessageLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestEmptyMessageLite =
-  com.google.protobuf.TestEmptyMessageLiteKt.Dsl._create(com.google.protobuf.UnittestLite.TestEmptyMessageLite.newBuilder()).apply { block() }._build()
-object TestEmptyMessageLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestEmptyMessageLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.TestEmptyMessageLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.TestEmptyMessageLite = _builder.build()
-  }
-}
-inline fun com.google.protobuf.UnittestLite.TestEmptyMessageLite.copy(block: com.google.protobuf.TestEmptyMessageLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestEmptyMessageLite =
-  com.google.protobuf.TestEmptyMessageLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestEmptyMessageWithExtensionsLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestEmptyMessageWithExtensionsLiteKt.kt
deleted file mode 100644
index 3df8cb3..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestEmptyMessageWithExtensionsLiteKt.kt
+++ /dev/null
@@ -1,118 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testEmptyMessageWithExtensionsLite(block: com.google.protobuf.TestEmptyMessageWithExtensionsLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite =
-  com.google.protobuf.TestEmptyMessageWithExtensionsLiteKt.Dsl._create(com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite.newBuilder()).apply { block() }._build()
-object TestEmptyMessageWithExtensionsLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite = _builder.build()
-    @Suppress("UNCHECKED_CAST")
-    @kotlin.jvm.JvmSynthetic
-    operator fun <T> get(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite, T>): T {
-      return if (extension.isRepeated) {
-        get(extension as com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite, List<*>>) as T
-      } else {
-        _builder.getExtension(extension)
-      }
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    @kotlin.jvm.JvmName("-getRepeatedExtension")
-    operator fun <E> get(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite, List<E>>
-    ): com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite> {
-      return com.google.protobuf.kotlin.ExtensionList(extension, _builder.getExtension(extension))
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    operator fun contains(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite, *>): Boolean {
-      return _builder.hasExtension(extension)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun clear(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite, *>) {
-      _builder.clearExtension(extension)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun <T> setExtension(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite, T>, value: T) {
-      _builder.setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <T : Comparable<T>> set(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite, T>,
-      value: T
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun set(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite, com.google.protobuf.ByteString>,
-      value: com.google.protobuf.ByteString
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <T : com.google.protobuf.MessageLite> set(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite, T>,
-      value: T
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite>.add(value: E) {
-      _builder.addExtension(this.extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite>.plusAssign(value: E) {
-      add(value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite>.addAll(values: Iterable<E>) {
-      for (value in values) {
-        add(value)
-      }
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite>.plusAssign(values: Iterable<E>) {
-      addAll(values)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite>.set(index: Int, value: E) {
-      _builder.setExtension(this.extension, index, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline fun com.google.protobuf.kotlin.ExtensionList<*, com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite>.clear() {
-      clear(extension)
-    }
-
-  }
-}
-inline fun com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite.copy(block: com.google.protobuf.TestEmptyMessageWithExtensionsLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite =
-  com.google.protobuf.TestEmptyMessageWithExtensionsLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestHugeFieldNumbersLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestHugeFieldNumbersLiteKt.kt
deleted file mode 100644
index a58de63..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestHugeFieldNumbersLiteKt.kt
+++ /dev/null
@@ -1,621 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testHugeFieldNumbersLite(block: com.google.protobuf.TestHugeFieldNumbersLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite =
-  com.google.protobuf.TestHugeFieldNumbersLiteKt.Dsl._create(com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.newBuilder()).apply { block() }._build()
-object TestHugeFieldNumbersLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite = _builder.build()
-
-    /**
-     * <code>optional int32 optional_int32 = 536870000;</code>
-     */
-    var optionalInt32: kotlin.Int
-      @JvmName("getOptionalInt32")
-      get() = _builder.getOptionalInt32()
-      @JvmName("setOptionalInt32")
-      set(value) {
-        _builder.setOptionalInt32(value)
-      }
-    /**
-     * <code>optional int32 optional_int32 = 536870000;</code>
-     */
-    fun clearOptionalInt32() {
-      _builder.clearOptionalInt32()
-    }
-    /**
-     * <code>optional int32 optional_int32 = 536870000;</code>
-     * @return Whether the optionalInt32 field is set.
-     */
-    fun hasOptionalInt32(): kotlin.Boolean {
-      return _builder.hasOptionalInt32()
-    }
-
-    /**
-     * <code>optional int32 fixed_32 = 536870001;</code>
-     */
-    var fixed32: kotlin.Int
-      @JvmName("getFixed32")
-      get() = _builder.getFixed32()
-      @JvmName("setFixed32")
-      set(value) {
-        _builder.setFixed32(value)
-      }
-    /**
-     * <code>optional int32 fixed_32 = 536870001;</code>
-     */
-    fun clearFixed32() {
-      _builder.clearFixed32()
-    }
-    /**
-     * <code>optional int32 fixed_32 = 536870001;</code>
-     * @return Whether the fixed32 field is set.
-     */
-    fun hasFixed32(): kotlin.Boolean {
-      return _builder.hasFixed32()
-    }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedInt32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     */
-     val repeatedInt32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedInt32List()
-      )
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @param value The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedInt32(value)
-    }/**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @param value The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedInt32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @param values The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedInt32(values)
-    }/**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @param values The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedInt32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedInt32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedInt32(index, value)
-    }/**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.clear() {
-      _builder.clearRepeatedInt32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedInt32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     */
-     val packedInt32: com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedInt32List()
-      )
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @param value The packedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>.add(value: kotlin.Int) {
-      _builder.addPackedInt32(value)
-    }/**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @param value The packedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedInt32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @param values The packedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllPackedInt32(values)
-    }/**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @param values The packedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedInt32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedInt32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedInt32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setPackedInt32(index, value)
-    }/**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>.clear() {
-      _builder.clearPackedInt32()
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite optional_enum = 536870004;</code>
-     */
-    var optionalEnum: com.google.protobuf.UnittestLite.ForeignEnumLite
-      @JvmName("getOptionalEnum")
-      get() = _builder.getOptionalEnum()
-      @JvmName("setOptionalEnum")
-      set(value) {
-        _builder.setOptionalEnum(value)
-      }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite optional_enum = 536870004;</code>
-     */
-    fun clearOptionalEnum() {
-      _builder.clearOptionalEnum()
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite optional_enum = 536870004;</code>
-     * @return Whether the optionalEnum field is set.
-     */
-    fun hasOptionalEnum(): kotlin.Boolean {
-      return _builder.hasOptionalEnum()
-    }
-
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     */
-    var optionalString: kotlin.String
-      @JvmName("getOptionalString")
-      get() = _builder.getOptionalString()
-      @JvmName("setOptionalString")
-      set(value) {
-        _builder.setOptionalString(value)
-      }
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     */
-    fun clearOptionalString() {
-      _builder.clearOptionalString()
-    }
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     * @return Whether the optionalString field is set.
-     */
-    fun hasOptionalString(): kotlin.Boolean {
-      return _builder.hasOptionalString()
-    }
-
-    /**
-     * <code>optional bytes optional_bytes = 536870006;</code>
-     */
-    var optionalBytes: com.google.protobuf.ByteString
-      @JvmName("getOptionalBytes")
-      get() = _builder.getOptionalBytes()
-      @JvmName("setOptionalBytes")
-      set(value) {
-        _builder.setOptionalBytes(value)
-      }
-    /**
-     * <code>optional bytes optional_bytes = 536870006;</code>
-     */
-    fun clearOptionalBytes() {
-      _builder.clearOptionalBytes()
-    }
-    /**
-     * <code>optional bytes optional_bytes = 536870006;</code>
-     * @return Whether the optionalBytes field is set.
-     */
-    fun hasOptionalBytes(): kotlin.Boolean {
-      return _builder.hasOptionalBytes()
-    }
-
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_message = 536870007;</code>
-     */
-    var optionalMessage: com.google.protobuf.UnittestLite.ForeignMessageLite
-      @JvmName("getOptionalMessage")
-      get() = _builder.getOptionalMessage()
-      @JvmName("setOptionalMessage")
-      set(value) {
-        _builder.setOptionalMessage(value)
-      }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_message = 536870007;</code>
-     */
-    fun clearOptionalMessage() {
-      _builder.clearOptionalMessage()
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_message = 536870007;</code>
-     * @return Whether the optionalMessage field is set.
-     */
-    fun hasOptionalMessage(): kotlin.Boolean {
-      return _builder.hasOptionalMessage()
-    }
-
-    /**
-     * <code>optional group OptionalGroup = 536870008 { ... }</code>
-     */
-    var optionalGroup: com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup
-      @JvmName("getOptionalGroup")
-      get() = _builder.getOptionalGroup()
-      @JvmName("setOptionalGroup")
-      set(value) {
-        _builder.setOptionalGroup(value)
-      }
-    /**
-     * <code>optional group OptionalGroup = 536870008 { ... }</code>
-     */
-    fun clearOptionalGroup() {
-      _builder.clearOptionalGroup()
-    }
-    /**
-     * <code>optional group OptionalGroup = 536870008 { ... }</code>
-     * @return Whether the optionalgroup field is set.
-     */
-    fun hasOptionalGroup(): kotlin.Boolean {
-      return _builder.hasOptionalGroup()
-    }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class StringStringMapProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-     val stringStringMap: com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, StringStringMapProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getStringStringMapMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getStringStringMapMap()
-      )
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    @JvmName("putStringStringMap")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, StringStringMapProxy>
-      .put(key: kotlin.String, value: kotlin.String) {
-         _builder.putStringStringMap(key, value)
-       }
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setStringStringMap")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, StringStringMapProxy>
-      .set(key: kotlin.String, value: kotlin.String) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeStringStringMap")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, StringStringMapProxy>
-      .remove(key: kotlin.String) {
-         _builder.removeStringStringMap(key)
-       }
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllStringStringMap")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, StringStringMapProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.String, kotlin.String>) {
-         _builder.putAllStringStringMap(map)
-       }
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearStringStringMap")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, StringStringMapProxy>
-      .clear() {
-         _builder.clearStringStringMap()
-       }
-
-    /**
-     * <code>uint32 oneof_uint32 = 536870011;</code>
-     */
-    var oneofUint32: kotlin.Int
-      @JvmName("getOneofUint32")
-      get() = _builder.getOneofUint32()
-      @JvmName("setOneofUint32")
-      set(value) {
-        _builder.setOneofUint32(value)
-      }
-    /**
-     * <code>uint32 oneof_uint32 = 536870011;</code>
-     */
-    fun clearOneofUint32() {
-      _builder.clearOneofUint32()
-    }
-    /**
-     * <code>uint32 oneof_uint32 = 536870011;</code>
-     * @return Whether the oneofUint32 field is set.
-     */
-    fun hasOneofUint32(): kotlin.Boolean {
-      return _builder.hasOneofUint32()
-    }
-
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_test_all_types = 536870012;</code>
-     */
-    var oneofTestAllTypes: com.google.protobuf.UnittestLite.TestAllTypesLite
-      @JvmName("getOneofTestAllTypes")
-      get() = _builder.getOneofTestAllTypes()
-      @JvmName("setOneofTestAllTypes")
-      set(value) {
-        _builder.setOneofTestAllTypes(value)
-      }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_test_all_types = 536870012;</code>
-     */
-    fun clearOneofTestAllTypes() {
-      _builder.clearOneofTestAllTypes()
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_test_all_types = 536870012;</code>
-     * @return Whether the oneofTestAllTypes field is set.
-     */
-    fun hasOneofTestAllTypes(): kotlin.Boolean {
-      return _builder.hasOneofTestAllTypes()
-    }
-
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     */
-    var oneofString: kotlin.String
-      @JvmName("getOneofString")
-      get() = _builder.getOneofString()
-      @JvmName("setOneofString")
-      set(value) {
-        _builder.setOneofString(value)
-      }
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     */
-    fun clearOneofString() {
-      _builder.clearOneofString()
-    }
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     * @return Whether the oneofString field is set.
-     */
-    fun hasOneofString(): kotlin.Boolean {
-      return _builder.hasOneofString()
-    }
-
-    /**
-     * <code>bytes oneof_bytes = 536870014;</code>
-     */
-    var oneofBytes: com.google.protobuf.ByteString
-      @JvmName("getOneofBytes")
-      get() = _builder.getOneofBytes()
-      @JvmName("setOneofBytes")
-      set(value) {
-        _builder.setOneofBytes(value)
-      }
-    /**
-     * <code>bytes oneof_bytes = 536870014;</code>
-     */
-    fun clearOneofBytes() {
-      _builder.clearOneofBytes()
-    }
-    /**
-     * <code>bytes oneof_bytes = 536870014;</code>
-     * @return Whether the oneofBytes field is set.
-     */
-    fun hasOneofBytes(): kotlin.Boolean {
-      return _builder.hasOneofBytes()
-    }
-    val oneofFieldCase: com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OneofFieldCase
-      @JvmName("getOneofFieldCase")
-      get() = _builder.getOneofFieldCase()
-
-    fun clearOneofField() {
-      _builder.clearOneofField()
-    }
-    @Suppress("UNCHECKED_CAST")
-    @kotlin.jvm.JvmSynthetic
-    operator fun <T> get(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite, T>): T {
-      return if (extension.isRepeated) {
-        get(extension as com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite, List<*>>) as T
-      } else {
-        _builder.getExtension(extension)
-      }
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    @kotlin.jvm.JvmName("-getRepeatedExtension")
-    operator fun <E> get(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite, List<E>>
-    ): com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite> {
-      return com.google.protobuf.kotlin.ExtensionList(extension, _builder.getExtension(extension))
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    operator fun contains(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite, *>): Boolean {
-      return _builder.hasExtension(extension)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun clear(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite, *>) {
-      _builder.clearExtension(extension)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun <T> setExtension(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite, T>, value: T) {
-      _builder.setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <T : Comparable<T>> set(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite, T>,
-      value: T
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun set(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite, com.google.protobuf.ByteString>,
-      value: com.google.protobuf.ByteString
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <T : com.google.protobuf.MessageLite> set(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite, T>,
-      value: T
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite>.add(value: E) {
-      _builder.addExtension(this.extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite>.plusAssign(value: E) {
-      add(value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite>.addAll(values: Iterable<E>) {
-      for (value in values) {
-        add(value)
-      }
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite>.plusAssign(values: Iterable<E>) {
-      addAll(values)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite>.set(index: Int, value: E) {
-      _builder.setExtension(this.extension, index, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline fun com.google.protobuf.kotlin.ExtensionList<*, com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite>.clear() {
-      clear(extension)
-    }
-
-  }
-  @kotlin.jvm.JvmSynthetic
-  inline fun optionalGroup(block: com.google.protobuf.TestHugeFieldNumbersLiteKt.OptionalGroupKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup =
-    com.google.protobuf.TestHugeFieldNumbersLiteKt.OptionalGroupKt.Dsl._create(com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup.newBuilder()).apply { block() }._build()
-  object OptionalGroupKt {
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    @com.google.protobuf.kotlin.ProtoDslMarker
-    class Dsl private constructor(
-      @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup.Builder
-    ) {
-      companion object {
-        @kotlin.jvm.JvmSynthetic
-        @kotlin.PublishedApi
-        internal fun _create(builder: com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup.Builder): Dsl = Dsl(builder)
-      }
-
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _build(): com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup = _builder.build()
-
-      /**
-       * <code>optional int32 group_a = 536870009;</code>
-       */
-      var groupA: kotlin.Int
-        @JvmName("getGroupA")
-        get() = _builder.getGroupA()
-        @JvmName("setGroupA")
-        set(value) {
-          _builder.setGroupA(value)
-        }
-      /**
-       * <code>optional int32 group_a = 536870009;</code>
-       */
-      fun clearGroupA() {
-        _builder.clearGroupA()
-      }
-      /**
-       * <code>optional int32 group_a = 536870009;</code>
-       * @return Whether the groupA field is set.
-       */
-      fun hasGroupA(): kotlin.Boolean {
-        return _builder.hasGroupA()
-      }
-    }
-  }
-}
-inline fun com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.copy(block: com.google.protobuf.TestHugeFieldNumbersLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite =
-  com.google.protobuf.TestHugeFieldNumbersLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
-inline fun com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup.copy(block: com.google.protobuf.TestHugeFieldNumbersLiteKt.OptionalGroupKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup =
-  com.google.protobuf.TestHugeFieldNumbersLiteKt.OptionalGroupKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestNestedExtensionLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestNestedExtensionLiteKt.kt
deleted file mode 100644
index 627fd35..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestNestedExtensionLiteKt.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testNestedExtensionLite(block: com.google.protobuf.TestNestedExtensionLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestNestedExtensionLite =
-  com.google.protobuf.TestNestedExtensionLiteKt.Dsl._create(com.google.protobuf.UnittestLite.TestNestedExtensionLite.newBuilder()).apply { block() }._build()
-object TestNestedExtensionLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestNestedExtensionLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.TestNestedExtensionLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.TestNestedExtensionLite = _builder.build()
-  }
-}
-inline fun com.google.protobuf.UnittestLite.TestNestedExtensionLite.copy(block: com.google.protobuf.TestNestedExtensionLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestNestedExtensionLite =
-  com.google.protobuf.TestNestedExtensionLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestOneofParsingLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestOneofParsingLiteKt.kt
deleted file mode 100644
index e21921f..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestOneofParsingLiteKt.kt
+++ /dev/null
@@ -1,250 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testOneofParsingLite(block: com.google.protobuf.TestOneofParsingLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestOneofParsingLite =
-  com.google.protobuf.TestOneofParsingLiteKt.Dsl._create(com.google.protobuf.UnittestLite.TestOneofParsingLite.newBuilder()).apply { block() }._build()
-object TestOneofParsingLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestOneofParsingLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.TestOneofParsingLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.TestOneofParsingLite = _builder.build()
-
-    /**
-     * <code>int32 oneof_int32 = 1;</code>
-     */
-    var oneofInt32: kotlin.Int
-      @JvmName("getOneofInt32")
-      get() = _builder.getOneofInt32()
-      @JvmName("setOneofInt32")
-      set(value) {
-        _builder.setOneofInt32(value)
-      }
-    /**
-     * <code>int32 oneof_int32 = 1;</code>
-     */
-    fun clearOneofInt32() {
-      _builder.clearOneofInt32()
-    }
-    /**
-     * <code>int32 oneof_int32 = 1;</code>
-     * @return Whether the oneofInt32 field is set.
-     */
-    fun hasOneofInt32(): kotlin.Boolean {
-      return _builder.hasOneofInt32()
-    }
-
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_submessage = 2;</code>
-     */
-    var oneofSubmessage: com.google.protobuf.UnittestLite.TestAllTypesLite
-      @JvmName("getOneofSubmessage")
-      get() = _builder.getOneofSubmessage()
-      @JvmName("setOneofSubmessage")
-      set(value) {
-        _builder.setOneofSubmessage(value)
-      }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_submessage = 2;</code>
-     */
-    fun clearOneofSubmessage() {
-      _builder.clearOneofSubmessage()
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_submessage = 2;</code>
-     * @return Whether the oneofSubmessage field is set.
-     */
-    fun hasOneofSubmessage(): kotlin.Boolean {
-      return _builder.hasOneofSubmessage()
-    }
-
-    /**
-     * <code>string oneof_string = 3;</code>
-     */
-    var oneofString: kotlin.String
-      @JvmName("getOneofString")
-      get() = _builder.getOneofString()
-      @JvmName("setOneofString")
-      set(value) {
-        _builder.setOneofString(value)
-      }
-    /**
-     * <code>string oneof_string = 3;</code>
-     */
-    fun clearOneofString() {
-      _builder.clearOneofString()
-    }
-    /**
-     * <code>string oneof_string = 3;</code>
-     * @return Whether the oneofString field is set.
-     */
-    fun hasOneofString(): kotlin.Boolean {
-      return _builder.hasOneofString()
-    }
-
-    /**
-     * <code>bytes oneof_bytes = 4 [default = "default bytes"];</code>
-     */
-    var oneofBytes: com.google.protobuf.ByteString
-      @JvmName("getOneofBytes")
-      get() = _builder.getOneofBytes()
-      @JvmName("setOneofBytes")
-      set(value) {
-        _builder.setOneofBytes(value)
-      }
-    /**
-     * <code>bytes oneof_bytes = 4 [default = "default bytes"];</code>
-     */
-    fun clearOneofBytes() {
-      _builder.clearOneofBytes()
-    }
-    /**
-     * <code>bytes oneof_bytes = 4 [default = "default bytes"];</code>
-     * @return Whether the oneofBytes field is set.
-     */
-    fun hasOneofBytes(): kotlin.Boolean {
-      return _builder.hasOneofBytes()
-    }
-
-    /**
-     * <code>string oneof_string_cord = 5 [default = "default Cord", ctype = CORD];</code>
-     */
-    var oneofStringCord: kotlin.String
-      @JvmName("getOneofStringCord")
-      get() = _builder.getOneofStringCord()
-      @JvmName("setOneofStringCord")
-      set(value) {
-        _builder.setOneofStringCord(value)
-      }
-    /**
-     * <code>string oneof_string_cord = 5 [default = "default Cord", ctype = CORD];</code>
-     */
-    fun clearOneofStringCord() {
-      _builder.clearOneofStringCord()
-    }
-    /**
-     * <code>string oneof_string_cord = 5 [default = "default Cord", ctype = CORD];</code>
-     * @return Whether the oneofStringCord field is set.
-     */
-    fun hasOneofStringCord(): kotlin.Boolean {
-      return _builder.hasOneofStringCord()
-    }
-
-    /**
-     * <code>bytes oneof_bytes_cord = 6 [ctype = CORD];</code>
-     */
-    var oneofBytesCord: com.google.protobuf.ByteString
-      @JvmName("getOneofBytesCord")
-      get() = _builder.getOneofBytesCord()
-      @JvmName("setOneofBytesCord")
-      set(value) {
-        _builder.setOneofBytesCord(value)
-      }
-    /**
-     * <code>bytes oneof_bytes_cord = 6 [ctype = CORD];</code>
-     */
-    fun clearOneofBytesCord() {
-      _builder.clearOneofBytesCord()
-    }
-    /**
-     * <code>bytes oneof_bytes_cord = 6 [ctype = CORD];</code>
-     * @return Whether the oneofBytesCord field is set.
-     */
-    fun hasOneofBytesCord(): kotlin.Boolean {
-      return _builder.hasOneofBytesCord()
-    }
-
-    /**
-     * <code>string oneof_string_string_piece = 7 [ctype = STRING_PIECE];</code>
-     */
-    var oneofStringStringPiece: kotlin.String
-      @JvmName("getOneofStringStringPiece")
-      get() = _builder.getOneofStringStringPiece()
-      @JvmName("setOneofStringStringPiece")
-      set(value) {
-        _builder.setOneofStringStringPiece(value)
-      }
-    /**
-     * <code>string oneof_string_string_piece = 7 [ctype = STRING_PIECE];</code>
-     */
-    fun clearOneofStringStringPiece() {
-      _builder.clearOneofStringStringPiece()
-    }
-    /**
-     * <code>string oneof_string_string_piece = 7 [ctype = STRING_PIECE];</code>
-     * @return Whether the oneofStringStringPiece field is set.
-     */
-    fun hasOneofStringStringPiece(): kotlin.Boolean {
-      return _builder.hasOneofStringStringPiece()
-    }
-
-    /**
-     * <code>bytes oneof_bytes_string_piece = 8 [default = "default StringPiece", ctype = STRING_PIECE];</code>
-     */
-    var oneofBytesStringPiece: com.google.protobuf.ByteString
-      @JvmName("getOneofBytesStringPiece")
-      get() = _builder.getOneofBytesStringPiece()
-      @JvmName("setOneofBytesStringPiece")
-      set(value) {
-        _builder.setOneofBytesStringPiece(value)
-      }
-    /**
-     * <code>bytes oneof_bytes_string_piece = 8 [default = "default StringPiece", ctype = STRING_PIECE];</code>
-     */
-    fun clearOneofBytesStringPiece() {
-      _builder.clearOneofBytesStringPiece()
-    }
-    /**
-     * <code>bytes oneof_bytes_string_piece = 8 [default = "default StringPiece", ctype = STRING_PIECE];</code>
-     * @return Whether the oneofBytesStringPiece field is set.
-     */
-    fun hasOneofBytesStringPiece(): kotlin.Boolean {
-      return _builder.hasOneofBytesStringPiece()
-    }
-
-    /**
-     * <code>.protobuf_unittest.V2EnumLite oneof_enum = 9;</code>
-     */
-    var oneofEnum: com.google.protobuf.UnittestLite.V2EnumLite
-      @JvmName("getOneofEnum")
-      get() = _builder.getOneofEnum()
-      @JvmName("setOneofEnum")
-      set(value) {
-        _builder.setOneofEnum(value)
-      }
-    /**
-     * <code>.protobuf_unittest.V2EnumLite oneof_enum = 9;</code>
-     */
-    fun clearOneofEnum() {
-      _builder.clearOneofEnum()
-    }
-    /**
-     * <code>.protobuf_unittest.V2EnumLite oneof_enum = 9;</code>
-     * @return Whether the oneofEnum field is set.
-     */
-    fun hasOneofEnum(): kotlin.Boolean {
-      return _builder.hasOneofEnum()
-    }
-    val oneofFieldCase: com.google.protobuf.UnittestLite.TestOneofParsingLite.OneofFieldCase
-      @JvmName("getOneofFieldCase")
-      get() = _builder.getOneofFieldCase()
-
-    fun clearOneofField() {
-      _builder.clearOneofField()
-    }
-  }
-}
-inline fun com.google.protobuf.UnittestLite.TestOneofParsingLite.copy(block: com.google.protobuf.TestOneofParsingLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestOneofParsingLite =
-  com.google.protobuf.TestOneofParsingLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestPackedExtensionsLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestPackedExtensionsLiteKt.kt
deleted file mode 100644
index d327754..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestPackedExtensionsLiteKt.kt
+++ /dev/null
@@ -1,118 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testPackedExtensionsLite(block: com.google.protobuf.TestPackedExtensionsLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestPackedExtensionsLite =
-  com.google.protobuf.TestPackedExtensionsLiteKt.Dsl._create(com.google.protobuf.UnittestLite.TestPackedExtensionsLite.newBuilder()).apply { block() }._build()
-object TestPackedExtensionsLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestPackedExtensionsLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.TestPackedExtensionsLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.TestPackedExtensionsLite = _builder.build()
-    @Suppress("UNCHECKED_CAST")
-    @kotlin.jvm.JvmSynthetic
-    operator fun <T> get(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestPackedExtensionsLite, T>): T {
-      return if (extension.isRepeated) {
-        get(extension as com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestPackedExtensionsLite, List<*>>) as T
-      } else {
-        _builder.getExtension(extension)
-      }
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    @kotlin.jvm.JvmName("-getRepeatedExtension")
-    operator fun <E> get(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestPackedExtensionsLite, List<E>>
-    ): com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestPackedExtensionsLite> {
-      return com.google.protobuf.kotlin.ExtensionList(extension, _builder.getExtension(extension))
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    operator fun contains(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestPackedExtensionsLite, *>): Boolean {
-      return _builder.hasExtension(extension)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun clear(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestPackedExtensionsLite, *>) {
-      _builder.clearExtension(extension)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun <T> setExtension(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestPackedExtensionsLite, T>, value: T) {
-      _builder.setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <T : Comparable<T>> set(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestPackedExtensionsLite, T>,
-      value: T
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun set(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestPackedExtensionsLite, com.google.protobuf.ByteString>,
-      value: com.google.protobuf.ByteString
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <T : com.google.protobuf.MessageLite> set(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestPackedExtensionsLite, T>,
-      value: T
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestPackedExtensionsLite>.add(value: E) {
-      _builder.addExtension(this.extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestPackedExtensionsLite>.plusAssign(value: E) {
-      add(value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestPackedExtensionsLite>.addAll(values: Iterable<E>) {
-      for (value in values) {
-        add(value)
-      }
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestPackedExtensionsLite>.plusAssign(values: Iterable<E>) {
-      addAll(values)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestPackedExtensionsLite>.set(index: Int, value: E) {
-      _builder.setExtension(this.extension, index, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline fun com.google.protobuf.kotlin.ExtensionList<*, com.google.protobuf.UnittestLite.TestPackedExtensionsLite>.clear() {
-      clear(extension)
-    }
-
-  }
-}
-inline fun com.google.protobuf.UnittestLite.TestPackedExtensionsLite.copy(block: com.google.protobuf.TestPackedExtensionsLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestPackedExtensionsLite =
-  com.google.protobuf.TestPackedExtensionsLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestPackedTypesLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestPackedTypesLiteKt.kt
deleted file mode 100644
index ac38006..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestPackedTypesLiteKt.kt
+++ /dev/null
@@ -1,909 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testPackedTypesLite(block: com.google.protobuf.TestPackedTypesLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestPackedTypesLite =
-  com.google.protobuf.TestPackedTypesLiteKt.Dsl._create(com.google.protobuf.UnittestLite.TestPackedTypesLite.newBuilder()).apply { block() }._build()
-object TestPackedTypesLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestPackedTypesLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.TestPackedTypesLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.TestPackedTypesLite = _builder.build()
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedInt32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     */
-     val packedInt32: com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedInt32List()
-      )
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param value The packedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>.add(value: kotlin.Int) {
-      _builder.addPackedInt32(value)
-    }/**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param value The packedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedInt32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param values The packedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllPackedInt32(values)
-    }/**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param values The packedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedInt32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedInt32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedInt32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setPackedInt32(index, value)
-    }/**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>.clear() {
-      _builder.clearPackedInt32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedInt64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     */
-     val packedInt64: com.google.protobuf.kotlin.DslList<kotlin.Long, PackedInt64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedInt64List()
-      )
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param value The packedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedInt64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedInt64Proxy>.add(value: kotlin.Long) {
-      _builder.addPackedInt64(value)
-    }/**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param value The packedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedInt64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedInt64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param values The packedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedInt64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedInt64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllPackedInt64(values)
-    }/**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param values The packedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedInt64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedInt64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedInt64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedInt64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedInt64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setPackedInt64(index, value)
-    }/**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedInt64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedInt64Proxy>.clear() {
-      _builder.clearPackedInt64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedUint32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     */
-     val packedUint32: com.google.protobuf.kotlin.DslList<kotlin.Int, PackedUint32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedUint32List()
-      )
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param value The packedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedUint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedUint32Proxy>.add(value: kotlin.Int) {
-      _builder.addPackedUint32(value)
-    }/**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param value The packedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedUint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedUint32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param values The packedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedUint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedUint32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllPackedUint32(values)
-    }/**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param values The packedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedUint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedUint32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedUint32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedUint32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedUint32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setPackedUint32(index, value)
-    }/**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedUint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedUint32Proxy>.clear() {
-      _builder.clearPackedUint32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedUint64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     */
-     val packedUint64: com.google.protobuf.kotlin.DslList<kotlin.Long, PackedUint64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedUint64List()
-      )
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param value The packedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedUint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedUint64Proxy>.add(value: kotlin.Long) {
-      _builder.addPackedUint64(value)
-    }/**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param value The packedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedUint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedUint64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param values The packedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedUint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedUint64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllPackedUint64(values)
-    }/**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param values The packedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedUint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedUint64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedUint64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedUint64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedUint64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setPackedUint64(index, value)
-    }/**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedUint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedUint64Proxy>.clear() {
-      _builder.clearPackedUint64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedSint32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     */
-     val packedSint32: com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSint32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedSint32List()
-      )
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param value The packedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedSint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSint32Proxy>.add(value: kotlin.Int) {
-      _builder.addPackedSint32(value)
-    }/**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param value The packedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedSint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSint32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param values The packedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedSint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSint32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllPackedSint32(values)
-    }/**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param values The packedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedSint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSint32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSint32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedSint32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSint32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setPackedSint32(index, value)
-    }/**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedSint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSint32Proxy>.clear() {
-      _builder.clearPackedSint32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedSint64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     */
-     val packedSint64: com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSint64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedSint64List()
-      )
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param value The packedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedSint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSint64Proxy>.add(value: kotlin.Long) {
-      _builder.addPackedSint64(value)
-    }/**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param value The packedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedSint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSint64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param values The packedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedSint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSint64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllPackedSint64(values)
-    }/**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param values The packedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedSint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSint64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSint64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedSint64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSint64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setPackedSint64(index, value)
-    }/**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedSint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSint64Proxy>.clear() {
-      _builder.clearPackedSint64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedFixed32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     */
-     val packedFixed32: com.google.protobuf.kotlin.DslList<kotlin.Int, PackedFixed32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedFixed32List()
-      )
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param value The packedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedFixed32Proxy>.add(value: kotlin.Int) {
-      _builder.addPackedFixed32(value)
-    }/**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param value The packedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedFixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedFixed32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param values The packedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedFixed32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllPackedFixed32(values)
-    }/**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param values The packedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedFixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedFixed32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedFixed32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedFixed32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedFixed32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setPackedFixed32(index, value)
-    }/**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedFixed32Proxy>.clear() {
-      _builder.clearPackedFixed32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedFixed64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     */
-     val packedFixed64: com.google.protobuf.kotlin.DslList<kotlin.Long, PackedFixed64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedFixed64List()
-      )
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param value The packedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedFixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedFixed64Proxy>.add(value: kotlin.Long) {
-      _builder.addPackedFixed64(value)
-    }/**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param value The packedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedFixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedFixed64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param values The packedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedFixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedFixed64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllPackedFixed64(values)
-    }/**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param values The packedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedFixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedFixed64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedFixed64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedFixed64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedFixed64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setPackedFixed64(index, value)
-    }/**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedFixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedFixed64Proxy>.clear() {
-      _builder.clearPackedFixed64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedSfixed32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     */
-     val packedSfixed32: com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSfixed32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedSfixed32List()
-      )
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param value The packedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedSfixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSfixed32Proxy>.add(value: kotlin.Int) {
-      _builder.addPackedSfixed32(value)
-    }/**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param value The packedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedSfixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSfixed32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param values The packedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedSfixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSfixed32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllPackedSfixed32(values)
-    }/**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param values The packedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedSfixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSfixed32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSfixed32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedSfixed32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSfixed32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setPackedSfixed32(index, value)
-    }/**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedSfixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSfixed32Proxy>.clear() {
-      _builder.clearPackedSfixed32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedSfixed64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     */
-     val packedSfixed64: com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSfixed64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedSfixed64List()
-      )
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param value The packedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedSfixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSfixed64Proxy>.add(value: kotlin.Long) {
-      _builder.addPackedSfixed64(value)
-    }/**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param value The packedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedSfixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSfixed64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param values The packedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedSfixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSfixed64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllPackedSfixed64(values)
-    }/**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param values The packedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedSfixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSfixed64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSfixed64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedSfixed64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSfixed64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setPackedSfixed64(index, value)
-    }/**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedSfixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSfixed64Proxy>.clear() {
-      _builder.clearPackedSfixed64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedFloatProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     */
-     val packedFloat: com.google.protobuf.kotlin.DslList<kotlin.Float, PackedFloatProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedFloatList()
-      )
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param value The packedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedFloat")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Float, PackedFloatProxy>.add(value: kotlin.Float) {
-      _builder.addPackedFloat(value)
-    }/**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param value The packedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedFloat")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Float, PackedFloatProxy>.plusAssign(value: kotlin.Float) {
-      add(value)
-    }/**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param values The packedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedFloat")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Float, PackedFloatProxy>.addAll(values: kotlin.collections.Iterable<kotlin.Float>) {
-      _builder.addAllPackedFloat(values)
-    }/**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param values The packedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedFloat")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Float, PackedFloatProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Float>) {
-      addAll(values)
-    }/**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedFloat to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedFloat")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Float, PackedFloatProxy>.set(index: kotlin.Int, value: kotlin.Float) {
-      _builder.setPackedFloat(index, value)
-    }/**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedFloat")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Float, PackedFloatProxy>.clear() {
-      _builder.clearPackedFloat()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedDoubleProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     */
-     val packedDouble: com.google.protobuf.kotlin.DslList<kotlin.Double, PackedDoubleProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedDoubleList()
-      )
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param value The packedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedDouble")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Double, PackedDoubleProxy>.add(value: kotlin.Double) {
-      _builder.addPackedDouble(value)
-    }/**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param value The packedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedDouble")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Double, PackedDoubleProxy>.plusAssign(value: kotlin.Double) {
-      add(value)
-    }/**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param values The packedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedDouble")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Double, PackedDoubleProxy>.addAll(values: kotlin.collections.Iterable<kotlin.Double>) {
-      _builder.addAllPackedDouble(values)
-    }/**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param values The packedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedDouble")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Double, PackedDoubleProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Double>) {
-      addAll(values)
-    }/**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedDouble to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedDouble")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Double, PackedDoubleProxy>.set(index: kotlin.Int, value: kotlin.Double) {
-      _builder.setPackedDouble(index, value)
-    }/**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedDouble")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Double, PackedDoubleProxy>.clear() {
-      _builder.clearPackedDouble()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedBoolProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     */
-     val packedBool: com.google.protobuf.kotlin.DslList<kotlin.Boolean, PackedBoolProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedBoolList()
-      )
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param value The packedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedBool")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, PackedBoolProxy>.add(value: kotlin.Boolean) {
-      _builder.addPackedBool(value)
-    }/**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param value The packedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedBool")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, PackedBoolProxy>.plusAssign(value: kotlin.Boolean) {
-      add(value)
-    }/**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param values The packedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedBool")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, PackedBoolProxy>.addAll(values: kotlin.collections.Iterable<kotlin.Boolean>) {
-      _builder.addAllPackedBool(values)
-    }/**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param values The packedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedBool")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, PackedBoolProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Boolean>) {
-      addAll(values)
-    }/**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedBool to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedBool")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, PackedBoolProxy>.set(index: kotlin.Int, value: kotlin.Boolean) {
-      _builder.setPackedBool(index, value)
-    }/**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedBool")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, PackedBoolProxy>.clear() {
-      _builder.clearPackedBool()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedEnumProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-     */
-     val packedEnum: com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignEnumLite, PackedEnumProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedEnumList()
-      )
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-     * @param value The packedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedEnum")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignEnumLite, PackedEnumProxy>.add(value: com.google.protobuf.UnittestLite.ForeignEnumLite) {
-      _builder.addPackedEnum(value)
-    }/**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-     * @param value The packedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedEnum")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignEnumLite, PackedEnumProxy>.plusAssign(value: com.google.protobuf.UnittestLite.ForeignEnumLite) {
-      add(value)
-    }/**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-     * @param values The packedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedEnum")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignEnumLite, PackedEnumProxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.ForeignEnumLite>) {
-      _builder.addAllPackedEnum(values)
-    }/**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-     * @param values The packedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedEnum")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignEnumLite, PackedEnumProxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.ForeignEnumLite>) {
-      addAll(values)
-    }/**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedEnum to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedEnum")
-    operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignEnumLite, PackedEnumProxy>.set(index: kotlin.Int, value: com.google.protobuf.UnittestLite.ForeignEnumLite) {
-      _builder.setPackedEnum(index, value)
-    }/**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedEnum")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.ForeignEnumLite, PackedEnumProxy>.clear() {
-      _builder.clearPackedEnum()
-    }}
-}
-inline fun com.google.protobuf.UnittestLite.TestPackedTypesLite.copy(block: com.google.protobuf.TestPackedTypesLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestPackedTypesLite =
-  com.google.protobuf.TestPackedTypesLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestParsingMergeLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestParsingMergeLiteKt.kt
deleted file mode 100644
index d119860..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestParsingMergeLiteKt.kt
+++ /dev/null
@@ -1,963 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testParsingMergeLite(block: com.google.protobuf.TestParsingMergeLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestParsingMergeLite =
-  com.google.protobuf.TestParsingMergeLiteKt.Dsl._create(com.google.protobuf.UnittestLite.TestParsingMergeLite.newBuilder()).apply { block() }._build()
-object TestParsingMergeLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestParsingMergeLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.TestParsingMergeLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.TestParsingMergeLite = _builder.build()
-
-    /**
-     * <code>required .protobuf_unittest.TestAllTypesLite required_all_types = 1;</code>
-     */
-    var requiredAllTypes: com.google.protobuf.UnittestLite.TestAllTypesLite
-      @JvmName("getRequiredAllTypes")
-      get() = _builder.getRequiredAllTypes()
-      @JvmName("setRequiredAllTypes")
-      set(value) {
-        _builder.setRequiredAllTypes(value)
-      }
-    /**
-     * <code>required .protobuf_unittest.TestAllTypesLite required_all_types = 1;</code>
-     */
-    fun clearRequiredAllTypes() {
-      _builder.clearRequiredAllTypes()
-    }
-    /**
-     * <code>required .protobuf_unittest.TestAllTypesLite required_all_types = 1;</code>
-     * @return Whether the requiredAllTypes field is set.
-     */
-    fun hasRequiredAllTypes(): kotlin.Boolean {
-      return _builder.hasRequiredAllTypes()
-    }
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite optional_all_types = 2;</code>
-     */
-    var optionalAllTypes: com.google.protobuf.UnittestLite.TestAllTypesLite
-      @JvmName("getOptionalAllTypes")
-      get() = _builder.getOptionalAllTypes()
-      @JvmName("setOptionalAllTypes")
-      set(value) {
-        _builder.setOptionalAllTypes(value)
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite optional_all_types = 2;</code>
-     */
-    fun clearOptionalAllTypes() {
-      _builder.clearOptionalAllTypes()
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite optional_all_types = 2;</code>
-     * @return Whether the optionalAllTypes field is set.
-     */
-    fun hasOptionalAllTypes(): kotlin.Boolean {
-      return _builder.hasOptionalAllTypes()
-    }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedAllTypesProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     */
-     val repeatedAllTypes: com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, RepeatedAllTypesProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedAllTypesList()
-      )
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     * @param value The repeatedAllTypes to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedAllTypes")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, RepeatedAllTypesProxy>.add(value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-      _builder.addRepeatedAllTypes(value)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     * @param value The repeatedAllTypes to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedAllTypes")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, RepeatedAllTypesProxy>.plusAssign(value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-      add(value)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     * @param values The repeatedAllTypes to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedAllTypes")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, RepeatedAllTypesProxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite>) {
-      _builder.addAllRepeatedAllTypes(values)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     * @param values The repeatedAllTypes to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedAllTypes")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, RepeatedAllTypesProxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite>) {
-      addAll(values)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedAllTypes to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedAllTypes")
-    operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, RepeatedAllTypesProxy>.set(index: kotlin.Int, value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-      _builder.setRepeatedAllTypes(index, value)
-    }/**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedAllTypes")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, RepeatedAllTypesProxy>.clear() {
-      _builder.clearRepeatedAllTypes()
-    }
-    /**
-     * <code>optional group OptionalGroup = 10 { ... }</code>
-     */
-    var optionalGroup: com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup
-      @JvmName("getOptionalGroup")
-      get() = _builder.getOptionalGroup()
-      @JvmName("setOptionalGroup")
-      set(value) {
-        _builder.setOptionalGroup(value)
-      }
-    /**
-     * <code>optional group OptionalGroup = 10 { ... }</code>
-     */
-    fun clearOptionalGroup() {
-      _builder.clearOptionalGroup()
-    }
-    /**
-     * <code>optional group OptionalGroup = 10 { ... }</code>
-     * @return Whether the optionalgroup field is set.
-     */
-    fun hasOptionalGroup(): kotlin.Boolean {
-      return _builder.hasOptionalGroup()
-    }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedGroupProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-     val repeatedGroup: com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup, RepeatedGroupProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedGroupList()
-      )
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     * @param value The repeatedgroup to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedGroup")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup, RepeatedGroupProxy>.add(value: com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup) {
-      _builder.addRepeatedGroup(value)
-    }/**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     * @param value The repeatedgroup to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedGroup")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup, RepeatedGroupProxy>.plusAssign(value: com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup) {
-      add(value)
-    }/**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     * @param values The repeatedgroup to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedGroup")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup, RepeatedGroupProxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup>) {
-      _builder.addAllRepeatedGroup(values)
-    }/**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     * @param values The repeatedgroup to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedGroup")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup, RepeatedGroupProxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup>) {
-      addAll(values)
-    }/**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedgroup to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedGroup")
-    operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup, RepeatedGroupProxy>.set(index: kotlin.Int, value: com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup) {
-      _builder.setRepeatedGroup(index, value)
-    }/**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedGroup")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup, RepeatedGroupProxy>.clear() {
-      _builder.clearRepeatedGroup()
-    }@Suppress("UNCHECKED_CAST")
-    @kotlin.jvm.JvmSynthetic
-    operator fun <T> get(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestParsingMergeLite, T>): T {
-      return if (extension.isRepeated) {
-        get(extension as com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestParsingMergeLite, List<*>>) as T
-      } else {
-        _builder.getExtension(extension)
-      }
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    @kotlin.jvm.JvmName("-getRepeatedExtension")
-    operator fun <E> get(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestParsingMergeLite, List<E>>
-    ): com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestParsingMergeLite> {
-      return com.google.protobuf.kotlin.ExtensionList(extension, _builder.getExtension(extension))
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    operator fun contains(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestParsingMergeLite, *>): Boolean {
-      return _builder.hasExtension(extension)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun clear(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestParsingMergeLite, *>) {
-      _builder.clearExtension(extension)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun <T> setExtension(extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestParsingMergeLite, T>, value: T) {
-      _builder.setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <T : Comparable<T>> set(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestParsingMergeLite, T>,
-      value: T
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun set(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestParsingMergeLite, com.google.protobuf.ByteString>,
-      value: com.google.protobuf.ByteString
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <T : com.google.protobuf.MessageLite> set(
-      extension: com.google.protobuf.ExtensionLite<com.google.protobuf.UnittestLite.TestParsingMergeLite, T>,
-      value: T
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestParsingMergeLite>.add(value: E) {
-      _builder.addExtension(this.extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestParsingMergeLite>.plusAssign(value: E) {
-      add(value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestParsingMergeLite>.addAll(values: Iterable<E>) {
-      for (value in values) {
-        add(value)
-      }
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestParsingMergeLite>.plusAssign(values: Iterable<E>) {
-      addAll(values)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, com.google.protobuf.UnittestLite.TestParsingMergeLite>.set(index: Int, value: E) {
-      _builder.setExtension(this.extension, index, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline fun com.google.protobuf.kotlin.ExtensionList<*, com.google.protobuf.UnittestLite.TestParsingMergeLite>.clear() {
-      clear(extension)
-    }
-
-  }
-  @kotlin.jvm.JvmSynthetic
-  inline fun repeatedFieldsGenerator(block: com.google.protobuf.TestParsingMergeLiteKt.RepeatedFieldsGeneratorKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator =
-    com.google.protobuf.TestParsingMergeLiteKt.RepeatedFieldsGeneratorKt.Dsl._create(com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.newBuilder()).apply { block() }._build()
-  object RepeatedFieldsGeneratorKt {
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    @com.google.protobuf.kotlin.ProtoDslMarker
-    class Dsl private constructor(
-      @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Builder
-    ) {
-      companion object {
-        @kotlin.jvm.JvmSynthetic
-        @kotlin.PublishedApi
-        internal fun _create(builder: com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Builder): Dsl = Dsl(builder)
-      }
-
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _build(): com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator = _builder.build()
-
-      /**
-       * An uninstantiable, behaviorless type to represent the field in
-       * generics.
-       */
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      class Field1Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       */
-       val field1: com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field1Proxy>
-        @kotlin.jvm.JvmSynthetic
-        get() = com.google.protobuf.kotlin.DslList(
-          _builder.getField1List()
-        )
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       * @param value The field1 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("addField1")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field1Proxy>.add(value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-        _builder.addField1(value)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       * @param value The field1 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("plusAssignField1")
-      inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field1Proxy>.plusAssign(value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-        add(value)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       * @param values The field1 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("addAllField1")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field1Proxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite>) {
-        _builder.addAllField1(values)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       * @param values The field1 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("plusAssignAllField1")
-      inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field1Proxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite>) {
-        addAll(values)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       * @param index The index to set the value at.
-       * @param value The field1 to set.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("setField1")
-      operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field1Proxy>.set(index: kotlin.Int, value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-        _builder.setField1(index, value)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("clearField1")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field1Proxy>.clear() {
-        _builder.clearField1()
-      }
-      /**
-       * An uninstantiable, behaviorless type to represent the field in
-       * generics.
-       */
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      class Field2Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       */
-       val field2: com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field2Proxy>
-        @kotlin.jvm.JvmSynthetic
-        get() = com.google.protobuf.kotlin.DslList(
-          _builder.getField2List()
-        )
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       * @param value The field2 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("addField2")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field2Proxy>.add(value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-        _builder.addField2(value)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       * @param value The field2 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("plusAssignField2")
-      inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field2Proxy>.plusAssign(value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-        add(value)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       * @param values The field2 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("addAllField2")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field2Proxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite>) {
-        _builder.addAllField2(values)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       * @param values The field2 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("plusAssignAllField2")
-      inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field2Proxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite>) {
-        addAll(values)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       * @param index The index to set the value at.
-       * @param value The field2 to set.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("setField2")
-      operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field2Proxy>.set(index: kotlin.Int, value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-        _builder.setField2(index, value)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("clearField2")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field2Proxy>.clear() {
-        _builder.clearField2()
-      }
-      /**
-       * An uninstantiable, behaviorless type to represent the field in
-       * generics.
-       */
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      class Field3Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       */
-       val field3: com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field3Proxy>
-        @kotlin.jvm.JvmSynthetic
-        get() = com.google.protobuf.kotlin.DslList(
-          _builder.getField3List()
-        )
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       * @param value The field3 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("addField3")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field3Proxy>.add(value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-        _builder.addField3(value)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       * @param value The field3 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("plusAssignField3")
-      inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field3Proxy>.plusAssign(value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-        add(value)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       * @param values The field3 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("addAllField3")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field3Proxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite>) {
-        _builder.addAllField3(values)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       * @param values The field3 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("plusAssignAllField3")
-      inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field3Proxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite>) {
-        addAll(values)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       * @param index The index to set the value at.
-       * @param value The field3 to set.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("setField3")
-      operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field3Proxy>.set(index: kotlin.Int, value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-        _builder.setField3(index, value)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("clearField3")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Field3Proxy>.clear() {
-        _builder.clearField3()
-      }
-      /**
-       * An uninstantiable, behaviorless type to represent the field in
-       * generics.
-       */
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      class Group1Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-       val group1: com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1, Group1Proxy>
-        @kotlin.jvm.JvmSynthetic
-        get() = com.google.protobuf.kotlin.DslList(
-          _builder.getGroup1List()
-        )
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       * @param value The group1 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("addGroup1")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1, Group1Proxy>.add(value: com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1) {
-        _builder.addGroup1(value)
-      }/**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       * @param value The group1 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("plusAssignGroup1")
-      inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1, Group1Proxy>.plusAssign(value: com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1) {
-        add(value)
-      }/**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       * @param values The group1 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("addAllGroup1")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1, Group1Proxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1>) {
-        _builder.addAllGroup1(values)
-      }/**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       * @param values The group1 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("plusAssignAllGroup1")
-      inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1, Group1Proxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1>) {
-        addAll(values)
-      }/**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       * @param index The index to set the value at.
-       * @param value The group1 to set.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("setGroup1")
-      operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1, Group1Proxy>.set(index: kotlin.Int, value: com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1) {
-        _builder.setGroup1(index, value)
-      }/**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("clearGroup1")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1, Group1Proxy>.clear() {
-        _builder.clearGroup1()
-      }
-      /**
-       * An uninstantiable, behaviorless type to represent the field in
-       * generics.
-       */
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      class Group2Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-       val group2: com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2, Group2Proxy>
-        @kotlin.jvm.JvmSynthetic
-        get() = com.google.protobuf.kotlin.DslList(
-          _builder.getGroup2List()
-        )
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       * @param value The group2 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("addGroup2")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2, Group2Proxy>.add(value: com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2) {
-        _builder.addGroup2(value)
-      }/**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       * @param value The group2 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("plusAssignGroup2")
-      inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2, Group2Proxy>.plusAssign(value: com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2) {
-        add(value)
-      }/**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       * @param values The group2 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("addAllGroup2")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2, Group2Proxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2>) {
-        _builder.addAllGroup2(values)
-      }/**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       * @param values The group2 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("plusAssignAllGroup2")
-      inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2, Group2Proxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2>) {
-        addAll(values)
-      }/**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       * @param index The index to set the value at.
-       * @param value The group2 to set.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("setGroup2")
-      operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2, Group2Proxy>.set(index: kotlin.Int, value: com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2) {
-        _builder.setGroup2(index, value)
-      }/**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("clearGroup2")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2, Group2Proxy>.clear() {
-        _builder.clearGroup2()
-      }
-      /**
-       * An uninstantiable, behaviorless type to represent the field in
-       * generics.
-       */
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      class Ext1Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       */
-       val ext1: com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Ext1Proxy>
-        @kotlin.jvm.JvmSynthetic
-        get() = com.google.protobuf.kotlin.DslList(
-          _builder.getExt1List()
-        )
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       * @param value The ext1 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("addExt1")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Ext1Proxy>.add(value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-        _builder.addExt1(value)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       * @param value The ext1 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("plusAssignExt1")
-      inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Ext1Proxy>.plusAssign(value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-        add(value)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       * @param values The ext1 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("addAllExt1")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Ext1Proxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite>) {
-        _builder.addAllExt1(values)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       * @param values The ext1 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("plusAssignAllExt1")
-      inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Ext1Proxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite>) {
-        addAll(values)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       * @param index The index to set the value at.
-       * @param value The ext1 to set.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("setExt1")
-      operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Ext1Proxy>.set(index: kotlin.Int, value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-        _builder.setExt1(index, value)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("clearExt1")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Ext1Proxy>.clear() {
-        _builder.clearExt1()
-      }
-      /**
-       * An uninstantiable, behaviorless type to represent the field in
-       * generics.
-       */
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      class Ext2Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       */
-       val ext2: com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Ext2Proxy>
-        @kotlin.jvm.JvmSynthetic
-        get() = com.google.protobuf.kotlin.DslList(
-          _builder.getExt2List()
-        )
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       * @param value The ext2 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("addExt2")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Ext2Proxy>.add(value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-        _builder.addExt2(value)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       * @param value The ext2 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("plusAssignExt2")
-      inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Ext2Proxy>.plusAssign(value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-        add(value)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       * @param values The ext2 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("addAllExt2")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Ext2Proxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite>) {
-        _builder.addAllExt2(values)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       * @param values The ext2 to add.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("plusAssignAllExt2")
-      inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Ext2Proxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.UnittestLite.TestAllTypesLite>) {
-        addAll(values)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       * @param index The index to set the value at.
-       * @param value The ext2 to set.
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("setExt2")
-      operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Ext2Proxy>.set(index: kotlin.Int, value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-        _builder.setExt2(index, value)
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       */
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.jvm.JvmName("clearExt2")
-      fun com.google.protobuf.kotlin.DslList<com.google.protobuf.UnittestLite.TestAllTypesLite, Ext2Proxy>.clear() {
-        _builder.clearExt2()
-      }}
-    @kotlin.jvm.JvmSynthetic
-    inline fun group1(block: com.google.protobuf.TestParsingMergeLiteKt.RepeatedFieldsGeneratorKt.Group1Kt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 =
-      com.google.protobuf.TestParsingMergeLiteKt.RepeatedFieldsGeneratorKt.Group1Kt.Dsl._create(com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1.newBuilder()).apply { block() }._build()
-    object Group1Kt {
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      @com.google.protobuf.kotlin.ProtoDslMarker
-      class Dsl private constructor(
-        @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1.Builder
-      ) {
-        companion object {
-          @kotlin.jvm.JvmSynthetic
-          @kotlin.PublishedApi
-          internal fun _create(builder: com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1.Builder): Dsl = Dsl(builder)
-        }
-
-        @kotlin.jvm.JvmSynthetic
-        @kotlin.PublishedApi
-        internal fun _build(): com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 = _builder.build()
-
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 11;</code>
-         */
-        var field1: com.google.protobuf.UnittestLite.TestAllTypesLite
-          @JvmName("getField1")
-          get() = _builder.getField1()
-          @JvmName("setField1")
-          set(value) {
-            _builder.setField1(value)
-          }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 11;</code>
-         */
-        fun clearField1() {
-          _builder.clearField1()
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 11;</code>
-         * @return Whether the field1 field is set.
-         */
-        fun hasField1(): kotlin.Boolean {
-          return _builder.hasField1()
-        }
-      }
-    }
-    @kotlin.jvm.JvmSynthetic
-    inline fun group2(block: com.google.protobuf.TestParsingMergeLiteKt.RepeatedFieldsGeneratorKt.Group2Kt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 =
-      com.google.protobuf.TestParsingMergeLiteKt.RepeatedFieldsGeneratorKt.Group2Kt.Dsl._create(com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2.newBuilder()).apply { block() }._build()
-    object Group2Kt {
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      @com.google.protobuf.kotlin.ProtoDslMarker
-      class Dsl private constructor(
-        @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2.Builder
-      ) {
-        companion object {
-          @kotlin.jvm.JvmSynthetic
-          @kotlin.PublishedApi
-          internal fun _create(builder: com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2.Builder): Dsl = Dsl(builder)
-        }
-
-        @kotlin.jvm.JvmSynthetic
-        @kotlin.PublishedApi
-        internal fun _build(): com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 = _builder.build()
-
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 21;</code>
-         */
-        var field1: com.google.protobuf.UnittestLite.TestAllTypesLite
-          @JvmName("getField1")
-          get() = _builder.getField1()
-          @JvmName("setField1")
-          set(value) {
-            _builder.setField1(value)
-          }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 21;</code>
-         */
-        fun clearField1() {
-          _builder.clearField1()
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 21;</code>
-         * @return Whether the field1 field is set.
-         */
-        fun hasField1(): kotlin.Boolean {
-          return _builder.hasField1()
-        }
-      }
-    }
-  }
-  @kotlin.jvm.JvmSynthetic
-  inline fun optionalGroup(block: com.google.protobuf.TestParsingMergeLiteKt.OptionalGroupKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup =
-    com.google.protobuf.TestParsingMergeLiteKt.OptionalGroupKt.Dsl._create(com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup.newBuilder()).apply { block() }._build()
-  object OptionalGroupKt {
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    @com.google.protobuf.kotlin.ProtoDslMarker
-    class Dsl private constructor(
-      @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup.Builder
-    ) {
-      companion object {
-        @kotlin.jvm.JvmSynthetic
-        @kotlin.PublishedApi
-        internal fun _create(builder: com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup.Builder): Dsl = Dsl(builder)
-      }
-
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _build(): com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup = _builder.build()
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite optional_group_all_types = 11;</code>
-       */
-      var optionalGroupAllTypes: com.google.protobuf.UnittestLite.TestAllTypesLite
-        @JvmName("getOptionalGroupAllTypes")
-        get() = _builder.getOptionalGroupAllTypes()
-        @JvmName("setOptionalGroupAllTypes")
-        set(value) {
-          _builder.setOptionalGroupAllTypes(value)
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite optional_group_all_types = 11;</code>
-       */
-      fun clearOptionalGroupAllTypes() {
-        _builder.clearOptionalGroupAllTypes()
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite optional_group_all_types = 11;</code>
-       * @return Whether the optionalGroupAllTypes field is set.
-       */
-      fun hasOptionalGroupAllTypes(): kotlin.Boolean {
-        return _builder.hasOptionalGroupAllTypes()
-      }
-    }
-  }
-  @kotlin.jvm.JvmSynthetic
-  inline fun repeatedGroup(block: com.google.protobuf.TestParsingMergeLiteKt.RepeatedGroupKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup =
-    com.google.protobuf.TestParsingMergeLiteKt.RepeatedGroupKt.Dsl._create(com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup.newBuilder()).apply { block() }._build()
-  object RepeatedGroupKt {
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    @com.google.protobuf.kotlin.ProtoDslMarker
-    class Dsl private constructor(
-      @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup.Builder
-    ) {
-      companion object {
-        @kotlin.jvm.JvmSynthetic
-        @kotlin.PublishedApi
-        internal fun _create(builder: com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup.Builder): Dsl = Dsl(builder)
-      }
-
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _build(): com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup = _builder.build()
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite repeated_group_all_types = 21;</code>
-       */
-      var repeatedGroupAllTypes: com.google.protobuf.UnittestLite.TestAllTypesLite
-        @JvmName("getRepeatedGroupAllTypes")
-        get() = _builder.getRepeatedGroupAllTypes()
-        @JvmName("setRepeatedGroupAllTypes")
-        set(value) {
-          _builder.setRepeatedGroupAllTypes(value)
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite repeated_group_all_types = 21;</code>
-       */
-      fun clearRepeatedGroupAllTypes() {
-        _builder.clearRepeatedGroupAllTypes()
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite repeated_group_all_types = 21;</code>
-       * @return Whether the repeatedGroupAllTypes field is set.
-       */
-      fun hasRepeatedGroupAllTypes(): kotlin.Boolean {
-        return _builder.hasRepeatedGroupAllTypes()
-      }
-    }
-  }
-}
-inline fun com.google.protobuf.UnittestLite.TestParsingMergeLite.copy(block: com.google.protobuf.TestParsingMergeLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestParsingMergeLite =
-  com.google.protobuf.TestParsingMergeLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
-inline fun com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.copy(block: com.google.protobuf.TestParsingMergeLiteKt.RepeatedFieldsGeneratorKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator =
-  com.google.protobuf.TestParsingMergeLiteKt.RepeatedFieldsGeneratorKt.Dsl._create(this.toBuilder()).apply { block() }._build()
-inline fun com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1.copy(block: com.google.protobuf.TestParsingMergeLiteKt.RepeatedFieldsGeneratorKt.Group1Kt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 =
-  com.google.protobuf.TestParsingMergeLiteKt.RepeatedFieldsGeneratorKt.Group1Kt.Dsl._create(this.toBuilder()).apply { block() }._build()
-inline fun com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2.copy(block: com.google.protobuf.TestParsingMergeLiteKt.RepeatedFieldsGeneratorKt.Group2Kt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 =
-  com.google.protobuf.TestParsingMergeLiteKt.RepeatedFieldsGeneratorKt.Group2Kt.Dsl._create(this.toBuilder()).apply { block() }._build()
-inline fun com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup.copy(block: com.google.protobuf.TestParsingMergeLiteKt.OptionalGroupKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup =
-  com.google.protobuf.TestParsingMergeLiteKt.OptionalGroupKt.Dsl._create(this.toBuilder()).apply { block() }._build()
-inline fun com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup.copy(block: com.google.protobuf.TestParsingMergeLiteKt.RepeatedGroupKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup =
-  com.google.protobuf.TestParsingMergeLiteKt.RepeatedGroupKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestUtil.java b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestUtil.java
deleted file mode 100644
index 525eb6b..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestUtil.java
+++ /dev/null
@@ -1,2696 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.UnittestLite.defaultBoolExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultBytesExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultCordExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultDoubleExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultFixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultFixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultFloatExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultForeignEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultImportEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultInt32ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultInt64ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultNestedEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultSfixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultSfixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultSint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultSint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultStringExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultStringPieceExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultUint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultUint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.oneofBytesExtensionLite;
-import static com.google.protobuf.UnittestLite.oneofNestedMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.oneofStringExtensionLite;
-import static com.google.protobuf.UnittestLite.oneofUint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalBoolExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalBytesExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalCordExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalDoubleExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalFixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalFixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalFloatExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalForeignEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalForeignMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalGroupExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalImportEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalImportMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalInt32ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalInt64ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalLazyMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalNestedEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalNestedMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalPublicImportMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalSfixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalSfixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalSint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalSint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalStringExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalStringPieceExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalUint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalUint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedBoolExtensionLite;
-import static com.google.protobuf.UnittestLite.packedDoubleExtensionLite;
-import static com.google.protobuf.UnittestLite.packedEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.packedFixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedFixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedFloatExtensionLite;
-import static com.google.protobuf.UnittestLite.packedInt32ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedInt64ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedSfixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedSfixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedSint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedSint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedUint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedUint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedBoolExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedBytesExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedCordExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedDoubleExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedFixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedFixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedFloatExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedForeignEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedForeignMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedGroupExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedImportEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedImportMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedInt32ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedInt64ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedLazyMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedNestedEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedNestedMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedSfixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedSfixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedSint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedSint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedStringExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedStringPieceExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedUint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedUint64ExtensionLite;
-import static protobuf_unittest.UnittestProto.defaultBoolExtension;
-import static protobuf_unittest.UnittestProto.defaultBytesExtension;
-import static protobuf_unittest.UnittestProto.defaultCordExtension;
-import static protobuf_unittest.UnittestProto.defaultDoubleExtension;
-import static protobuf_unittest.UnittestProto.defaultFixed32Extension;
-import static protobuf_unittest.UnittestProto.defaultFixed64Extension;
-import static protobuf_unittest.UnittestProto.defaultFloatExtension;
-import static protobuf_unittest.UnittestProto.defaultForeignEnumExtension;
-import static protobuf_unittest.UnittestProto.defaultImportEnumExtension;
-import static protobuf_unittest.UnittestProto.defaultInt32Extension;
-import static protobuf_unittest.UnittestProto.defaultInt64Extension;
-import static protobuf_unittest.UnittestProto.defaultNestedEnumExtension;
-import static protobuf_unittest.UnittestProto.defaultSfixed32Extension;
-import static protobuf_unittest.UnittestProto.defaultSfixed64Extension;
-import static protobuf_unittest.UnittestProto.defaultSint32Extension;
-import static protobuf_unittest.UnittestProto.defaultSint64Extension;
-import static protobuf_unittest.UnittestProto.defaultStringExtension;
-import static protobuf_unittest.UnittestProto.defaultStringPieceExtension;
-import static protobuf_unittest.UnittestProto.defaultUint32Extension;
-import static protobuf_unittest.UnittestProto.defaultUint64Extension;
-import static protobuf_unittest.UnittestProto.oneofBytesExtension;
-import static protobuf_unittest.UnittestProto.oneofNestedMessageExtension;
-import static protobuf_unittest.UnittestProto.oneofStringExtension;
-import static protobuf_unittest.UnittestProto.oneofUint32Extension;
-import static protobuf_unittest.UnittestProto.optionalBoolExtension;
-import static protobuf_unittest.UnittestProto.optionalBytesExtension;
-import static protobuf_unittest.UnittestProto.optionalCordExtension;
-import static protobuf_unittest.UnittestProto.optionalDoubleExtension;
-import static protobuf_unittest.UnittestProto.optionalFixed32Extension;
-import static protobuf_unittest.UnittestProto.optionalFixed64Extension;
-import static protobuf_unittest.UnittestProto.optionalFloatExtension;
-import static protobuf_unittest.UnittestProto.optionalForeignEnumExtension;
-import static protobuf_unittest.UnittestProto.optionalForeignMessageExtension;
-import static protobuf_unittest.UnittestProto.optionalGroupExtension;
-import static protobuf_unittest.UnittestProto.optionalImportEnumExtension;
-import static protobuf_unittest.UnittestProto.optionalImportMessageExtension;
-import static protobuf_unittest.UnittestProto.optionalInt32Extension;
-import static protobuf_unittest.UnittestProto.optionalInt64Extension;
-import static protobuf_unittest.UnittestProto.optionalLazyMessageExtension;
-import static protobuf_unittest.UnittestProto.optionalNestedEnumExtension;
-import static protobuf_unittest.UnittestProto.optionalNestedMessageExtension;
-import static protobuf_unittest.UnittestProto.optionalPublicImportMessageExtension;
-import static protobuf_unittest.UnittestProto.optionalSfixed32Extension;
-import static protobuf_unittest.UnittestProto.optionalSfixed64Extension;
-import static protobuf_unittest.UnittestProto.optionalSint32Extension;
-import static protobuf_unittest.UnittestProto.optionalSint64Extension;
-import static protobuf_unittest.UnittestProto.optionalStringExtension;
-import static protobuf_unittest.UnittestProto.optionalStringPieceExtension;
-import static protobuf_unittest.UnittestProto.optionalUint32Extension;
-import static protobuf_unittest.UnittestProto.optionalUint64Extension;
-import static protobuf_unittest.UnittestProto.packedBoolExtension;
-import static protobuf_unittest.UnittestProto.packedDoubleExtension;
-import static protobuf_unittest.UnittestProto.packedEnumExtension;
-import static protobuf_unittest.UnittestProto.packedFixed32Extension;
-import static protobuf_unittest.UnittestProto.packedFixed64Extension;
-import static protobuf_unittest.UnittestProto.packedFloatExtension;
-import static protobuf_unittest.UnittestProto.packedInt32Extension;
-import static protobuf_unittest.UnittestProto.packedInt64Extension;
-import static protobuf_unittest.UnittestProto.packedSfixed32Extension;
-import static protobuf_unittest.UnittestProto.packedSfixed64Extension;
-import static protobuf_unittest.UnittestProto.packedSint32Extension;
-import static protobuf_unittest.UnittestProto.packedSint64Extension;
-import static protobuf_unittest.UnittestProto.packedUint32Extension;
-import static protobuf_unittest.UnittestProto.packedUint64Extension;
-import static protobuf_unittest.UnittestProto.repeatedBoolExtension;
-import static protobuf_unittest.UnittestProto.repeatedBytesExtension;
-import static protobuf_unittest.UnittestProto.repeatedCordExtension;
-import static protobuf_unittest.UnittestProto.repeatedDoubleExtension;
-import static protobuf_unittest.UnittestProto.repeatedFixed32Extension;
-import static protobuf_unittest.UnittestProto.repeatedFixed64Extension;
-import static protobuf_unittest.UnittestProto.repeatedFloatExtension;
-import static protobuf_unittest.UnittestProto.repeatedForeignEnumExtension;
-import static protobuf_unittest.UnittestProto.repeatedForeignMessageExtension;
-import static protobuf_unittest.UnittestProto.repeatedGroupExtension;
-import static protobuf_unittest.UnittestProto.repeatedImportEnumExtension;
-import static protobuf_unittest.UnittestProto.repeatedImportMessageExtension;
-import static protobuf_unittest.UnittestProto.repeatedInt32Extension;
-import static protobuf_unittest.UnittestProto.repeatedInt64Extension;
-import static protobuf_unittest.UnittestProto.repeatedLazyMessageExtension;
-import static protobuf_unittest.UnittestProto.repeatedNestedEnumExtension;
-import static protobuf_unittest.UnittestProto.repeatedNestedMessageExtension;
-import static protobuf_unittest.UnittestProto.repeatedSfixed32Extension;
-import static protobuf_unittest.UnittestProto.repeatedSfixed64Extension;
-import static protobuf_unittest.UnittestProto.repeatedSint32Extension;
-import static protobuf_unittest.UnittestProto.repeatedSint64Extension;
-import static protobuf_unittest.UnittestProto.repeatedStringExtension;
-import static protobuf_unittest.UnittestProto.repeatedStringPieceExtension;
-import static protobuf_unittest.UnittestProto.repeatedUint32Extension;
-import static protobuf_unittest.UnittestProto.repeatedUint64Extension;
-
-import com.google.protobuf.UnittestImportLite.ImportEnumLite;
-import com.google.protobuf.UnittestLite.ForeignEnumLite;
-import com.google.protobuf.UnittestLite.TestAllExtensionsLiteOrBuilder;
-import com.google.protobuf.UnittestLite.TestAllTypesLite;
-import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
-import com.google.protobuf.test.UnittestImport.ImportEnum;
-import com.google.protobuf.test.UnittestImport.ImportMessage;
-import com.google.protobuf.test.UnittestImportPublic.PublicImportMessage;
-import protobuf_unittest.UnittestProto;
-import protobuf_unittest.UnittestProto.ForeignEnum;
-import protobuf_unittest.UnittestProto.ForeignMessage;
-import protobuf_unittest.UnittestProto.OptionalGroup_extension;
-import protobuf_unittest.UnittestProto.RepeatedGroup_extension;
-import protobuf_unittest.UnittestProto.TestAllExtensions;
-import protobuf_unittest.UnittestProto.TestAllExtensionsOrBuilder;
-import protobuf_unittest.UnittestProto.TestAllTypes;
-import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder;
-import protobuf_unittest.UnittestProto.TestOneof2;
-import protobuf_unittest.UnittestProto.TestPackedExtensions;
-import protobuf_unittest.UnittestProto.TestPackedTypes;
-import protobuf_unittest.UnittestProto.TestRequired;
-import protobuf_unittest.UnittestProto.TestUnpackedTypes;
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.logging.Handler;
-import java.util.logging.LogRecord;
-import junit.framework.Assert;
-
-/**
- * Contains methods for setting all fields of {@code TestAllTypes} to some values as well as
- * checking that all the fields are set to those values. These are useful for testing various
- * protocol message features, e.g. set all fields of a message, serialize it, parse it, and check
- * that all fields are set.
- *
- * <p>This code is not to be used outside of {@code com.google.protobuf} and subpackages.
- *
- * @author kenton@google.com Kenton Varda
- */
-public final class TestUtil {
-  private TestUtil() {}
-
-  public static final TestRequired TEST_REQUIRED_UNINITIALIZED =
-      TestRequired.newBuilder().setA(1).buildPartial();
-  public static final TestRequired TEST_REQUIRED_INITIALIZED =
-      TestRequired.newBuilder().setA(1).setB(2).setC(3).build();
-
-  /** Helper to convert a String to ByteString. */
-  public static ByteString toBytes(String str) {
-    return ByteString.copyFromUtf8(str);
-  }
-
-
-  /**
-   * Get a {@code TestAllTypes} with all fields set as they would be by {@link
-   * #setAllFields(TestAllTypes.Builder)}.
-   */
-  public static TestAllTypes getAllSet() {
-    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
-    setAllFields(builder);
-    return builder.build();
-  }
-
-  /**
-   * Get a {@code TestAllTypes.Builder} with all fields set as they would be by {@link
-   * #setAllFields(TestAllTypes.Builder)}.
-   */
-  public static TestAllTypes.Builder getAllSetBuilder() {
-    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
-    setAllFields(builder);
-    return builder;
-  }
-
-  /**
-   * Get a {@code TestAllExtensions} with all fields set as they would be by {@link
-   * #setAllExtensions(TestAllExtensions.Builder)}.
-   */
-  public static TestAllExtensions getAllExtensionsSet() {
-    TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
-    setAllExtensions(builder);
-    return builder.build();
-  }
-
-  public static TestPackedTypes getPackedSet() {
-    TestPackedTypes.Builder builder = TestPackedTypes.newBuilder();
-    setPackedFields(builder);
-    return builder.build();
-  }
-
-  public static TestUnpackedTypes getUnpackedSet() {
-    TestUnpackedTypes.Builder builder = TestUnpackedTypes.newBuilder();
-    setUnpackedFields(builder);
-    return builder.build();
-  }
-
-  public static TestPackedExtensions getPackedExtensionsSet() {
-    TestPackedExtensions.Builder builder = TestPackedExtensions.newBuilder();
-    setPackedExtensions(builder);
-    return builder.build();
-  }
-
-  /** Set every field of {@code message} to the values expected by {@code assertAllFieldsSet()}. */
-  public static void setAllFields(TestAllTypes.Builder message) {
-    message.setOptionalInt32(101);
-    message.setOptionalInt64(102);
-    message.setOptionalUint32(103);
-    message.setOptionalUint64(104);
-    message.setOptionalSint32(105);
-    message.setOptionalSint64(106);
-    message.setOptionalFixed32(107);
-    message.setOptionalFixed64(108);
-    message.setOptionalSfixed32(109);
-    message.setOptionalSfixed64(110);
-    message.setOptionalFloat(111);
-    message.setOptionalDouble(112);
-    message.setOptionalBool(true);
-    message.setOptionalString("115");
-    message.setOptionalBytes(toBytes("116"));
-
-    message.setOptionalGroup(TestAllTypes.OptionalGroup.newBuilder().setA(117).build());
-    message.setOptionalNestedMessage(TestAllTypes.NestedMessage.newBuilder().setBb(118).build());
-    message.setOptionalForeignMessage(ForeignMessage.newBuilder().setC(119).build());
-    message.setOptionalImportMessage(ImportMessage.newBuilder().setD(120).build());
-    message.setOptionalPublicImportMessage(PublicImportMessage.newBuilder().setE(126).build());
-    message.setOptionalLazyMessage(TestAllTypes.NestedMessage.newBuilder().setBb(127).build());
-
-    message.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAZ);
-    message.setOptionalForeignEnum(ForeignEnum.FOREIGN_BAZ);
-    message.setOptionalImportEnum(ImportEnum.IMPORT_BAZ);
-
-    message.setOptionalStringPiece("124");
-    message.setOptionalCord("125");
-
-    // -----------------------------------------------------------------
-
-    message.addRepeatedInt32(201);
-    message.addRepeatedInt64(202);
-    message.addRepeatedUint32(203);
-    message.addRepeatedUint64(204);
-    message.addRepeatedSint32(205);
-    message.addRepeatedSint64(206);
-    message.addRepeatedFixed32(207);
-    message.addRepeatedFixed64(208);
-    message.addRepeatedSfixed32(209);
-    message.addRepeatedSfixed64(210);
-    message.addRepeatedFloat(211);
-    message.addRepeatedDouble(212);
-    message.addRepeatedBool(true);
-    message.addRepeatedString("215");
-    message.addRepeatedBytes(toBytes("216"));
-
-    message.addRepeatedGroup(TestAllTypes.RepeatedGroup.newBuilder().setA(217).build());
-    message.addRepeatedNestedMessage(TestAllTypes.NestedMessage.newBuilder().setBb(218).build());
-    message.addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(219).build());
-    message.addRepeatedImportMessage(ImportMessage.newBuilder().setD(220).build());
-    message.addRepeatedLazyMessage(TestAllTypes.NestedMessage.newBuilder().setBb(227).build());
-
-    message.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR);
-    message.addRepeatedForeignEnum(ForeignEnum.FOREIGN_BAR);
-    message.addRepeatedImportEnum(ImportEnum.IMPORT_BAR);
-
-    message.addRepeatedStringPiece("224");
-    message.addRepeatedCord("225");
-
-    // Add a second one of each field.
-    message.addRepeatedInt32(301);
-    message.addRepeatedInt64(302);
-    message.addRepeatedUint32(303);
-    message.addRepeatedUint64(304);
-    message.addRepeatedSint32(305);
-    message.addRepeatedSint64(306);
-    message.addRepeatedFixed32(307);
-    message.addRepeatedFixed64(308);
-    message.addRepeatedSfixed32(309);
-    message.addRepeatedSfixed64(310);
-    message.addRepeatedFloat(311);
-    message.addRepeatedDouble(312);
-    message.addRepeatedBool(false);
-    message.addRepeatedString("315");
-    message.addRepeatedBytes(toBytes("316"));
-
-    message.addRepeatedGroup(TestAllTypes.RepeatedGroup.newBuilder().setA(317).build());
-    message.addRepeatedNestedMessage(TestAllTypes.NestedMessage.newBuilder().setBb(318).build());
-    message.addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(319).build());
-    message.addRepeatedImportMessage(ImportMessage.newBuilder().setD(320).build());
-    message.addRepeatedLazyMessage(TestAllTypes.NestedMessage.newBuilder().setBb(327).build());
-
-    message.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ);
-    message.addRepeatedForeignEnum(ForeignEnum.FOREIGN_BAZ);
-    message.addRepeatedImportEnum(ImportEnum.IMPORT_BAZ);
-
-    message.addRepeatedStringPiece("324");
-    message.addRepeatedCord("325");
-
-    // -----------------------------------------------------------------
-
-    message.setDefaultInt32(401);
-    message.setDefaultInt64(402);
-    message.setDefaultUint32(403);
-    message.setDefaultUint64(404);
-    message.setDefaultSint32(405);
-    message.setDefaultSint64(406);
-    message.setDefaultFixed32(407);
-    message.setDefaultFixed64(408);
-    message.setDefaultSfixed32(409);
-    message.setDefaultSfixed64(410);
-    message.setDefaultFloat(411);
-    message.setDefaultDouble(412);
-    message.setDefaultBool(false);
-    message.setDefaultString("415");
-    message.setDefaultBytes(toBytes("416"));
-
-    message.setDefaultNestedEnum(TestAllTypes.NestedEnum.FOO);
-    message.setDefaultForeignEnum(ForeignEnum.FOREIGN_FOO);
-    message.setDefaultImportEnum(ImportEnum.IMPORT_FOO);
-
-    message.setDefaultStringPiece("424");
-    message.setDefaultCord("425");
-
-    message.setOneofUint32(601);
-    message.setOneofNestedMessage(TestAllTypes.NestedMessage.newBuilder().setBb(602).build());
-    message.setOneofString("603");
-    message.setOneofBytes(toBytes("604"));
-  }
-
-  // -------------------------------------------------------------------
-
-  /**
-   * Modify the repeated fields of {@code message} to contain the values expected by {@code
-   * assertRepeatedFieldsModified()}.
-   */
-  public static void modifyRepeatedFields(TestAllTypes.Builder message) {
-    message.setRepeatedInt32(1, 501);
-    message.setRepeatedInt64(1, 502);
-    message.setRepeatedUint32(1, 503);
-    message.setRepeatedUint64(1, 504);
-    message.setRepeatedSint32(1, 505);
-    message.setRepeatedSint64(1, 506);
-    message.setRepeatedFixed32(1, 507);
-    message.setRepeatedFixed64(1, 508);
-    message.setRepeatedSfixed32(1, 509);
-    message.setRepeatedSfixed64(1, 510);
-    message.setRepeatedFloat(1, 511);
-    message.setRepeatedDouble(1, 512);
-    message.setRepeatedBool(1, true);
-    message.setRepeatedString(1, "515");
-    message.setRepeatedBytes(1, toBytes("516"));
-
-    message.setRepeatedGroup(1, TestAllTypes.RepeatedGroup.newBuilder().setA(517).build());
-    message.setRepeatedNestedMessage(1, TestAllTypes.NestedMessage.newBuilder().setBb(518).build());
-    message.setRepeatedForeignMessage(1, ForeignMessage.newBuilder().setC(519).build());
-    message.setRepeatedImportMessage(1, ImportMessage.newBuilder().setD(520).build());
-    message.setRepeatedLazyMessage(1, TestAllTypes.NestedMessage.newBuilder().setBb(527).build());
-
-    message.setRepeatedNestedEnum(1, TestAllTypes.NestedEnum.FOO);
-    message.setRepeatedForeignEnum(1, ForeignEnum.FOREIGN_FOO);
-    message.setRepeatedImportEnum(1, ImportEnum.IMPORT_FOO);
-
-    message.setRepeatedStringPiece(1, "524");
-    message.setRepeatedCord(1, "525");
-  }
-
-  // -------------------------------------------------------------------
-
-  /**
-   * Assert (using {@code junit.framework.Assert}} that all fields of {@code message} are set to the
-   * values assigned by {@code setAllFields}.
-   */
-  public static void assertAllFieldsSet(TestAllTypesOrBuilder message) {
-    Assert.assertTrue(message.hasOptionalInt32());
-    Assert.assertTrue(message.hasOptionalInt64());
-    Assert.assertTrue(message.hasOptionalUint32());
-    Assert.assertTrue(message.hasOptionalUint64());
-    Assert.assertTrue(message.hasOptionalSint32());
-    Assert.assertTrue(message.hasOptionalSint64());
-    Assert.assertTrue(message.hasOptionalFixed32());
-    Assert.assertTrue(message.hasOptionalFixed64());
-    Assert.assertTrue(message.hasOptionalSfixed32());
-    Assert.assertTrue(message.hasOptionalSfixed64());
-    Assert.assertTrue(message.hasOptionalFloat());
-    Assert.assertTrue(message.hasOptionalDouble());
-    Assert.assertTrue(message.hasOptionalBool());
-    Assert.assertTrue(message.hasOptionalString());
-    Assert.assertTrue(message.hasOptionalBytes());
-
-    Assert.assertTrue(message.hasOptionalGroup());
-    Assert.assertTrue(message.hasOptionalNestedMessage());
-    Assert.assertTrue(message.hasOptionalForeignMessage());
-    Assert.assertTrue(message.hasOptionalImportMessage());
-
-    Assert.assertTrue(message.getOptionalGroup().hasA());
-    Assert.assertTrue(message.getOptionalNestedMessage().hasBb());
-    Assert.assertTrue(message.getOptionalForeignMessage().hasC());
-    Assert.assertTrue(message.getOptionalImportMessage().hasD());
-
-    Assert.assertTrue(message.hasOptionalNestedEnum());
-    Assert.assertTrue(message.hasOptionalForeignEnum());
-    Assert.assertTrue(message.hasOptionalImportEnum());
-
-    Assert.assertTrue(message.hasOptionalStringPiece());
-    Assert.assertTrue(message.hasOptionalCord());
-
-    Assert.assertEquals(101, message.getOptionalInt32());
-    Assert.assertEquals(102, message.getOptionalInt64());
-    Assert.assertEquals(103, message.getOptionalUint32());
-    Assert.assertEquals(104, message.getOptionalUint64());
-    Assert.assertEquals(105, message.getOptionalSint32());
-    Assert.assertEquals(106, message.getOptionalSint64());
-    Assert.assertEquals(107, message.getOptionalFixed32());
-    Assert.assertEquals(108, message.getOptionalFixed64());
-    Assert.assertEquals(109, message.getOptionalSfixed32());
-    Assert.assertEquals(110, message.getOptionalSfixed64());
-    Assert.assertEquals(111, message.getOptionalFloat(), 0.0);
-    Assert.assertEquals(112, message.getOptionalDouble(), 0.0);
-    Assert.assertEquals(true, message.getOptionalBool());
-    Assert.assertEquals("115", message.getOptionalString());
-    Assert.assertEquals(toBytes("116"), message.getOptionalBytes());
-
-    Assert.assertEquals(117, message.getOptionalGroup().getA());
-    Assert.assertEquals(118, message.getOptionalNestedMessage().getBb());
-    Assert.assertEquals(119, message.getOptionalForeignMessage().getC());
-    Assert.assertEquals(120, message.getOptionalImportMessage().getD());
-    Assert.assertEquals(126, message.getOptionalPublicImportMessage().getE());
-    Assert.assertEquals(127, message.getOptionalLazyMessage().getBb());
-
-    Assert.assertEquals(TestAllTypes.NestedEnum.BAZ, message.getOptionalNestedEnum());
-    Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getOptionalForeignEnum());
-    Assert.assertEquals(ImportEnum.IMPORT_BAZ, message.getOptionalImportEnum());
-
-    Assert.assertEquals("124", message.getOptionalStringPiece());
-    Assert.assertEquals("125", message.getOptionalCord());
-
-    // -----------------------------------------------------------------
-
-    Assert.assertEquals(2, message.getRepeatedInt32Count());
-    Assert.assertEquals(2, message.getRepeatedInt64Count());
-    Assert.assertEquals(2, message.getRepeatedUint32Count());
-    Assert.assertEquals(2, message.getRepeatedUint64Count());
-    Assert.assertEquals(2, message.getRepeatedSint32Count());
-    Assert.assertEquals(2, message.getRepeatedSint64Count());
-    Assert.assertEquals(2, message.getRepeatedFixed32Count());
-    Assert.assertEquals(2, message.getRepeatedFixed64Count());
-    Assert.assertEquals(2, message.getRepeatedSfixed32Count());
-    Assert.assertEquals(2, message.getRepeatedSfixed64Count());
-    Assert.assertEquals(2, message.getRepeatedFloatCount());
-    Assert.assertEquals(2, message.getRepeatedDoubleCount());
-    Assert.assertEquals(2, message.getRepeatedBoolCount());
-    Assert.assertEquals(2, message.getRepeatedStringCount());
-    Assert.assertEquals(2, message.getRepeatedBytesCount());
-
-    Assert.assertEquals(2, message.getRepeatedGroupCount());
-    Assert.assertEquals(2, message.getRepeatedNestedMessageCount());
-    Assert.assertEquals(2, message.getRepeatedForeignMessageCount());
-    Assert.assertEquals(2, message.getRepeatedImportMessageCount());
-    Assert.assertEquals(2, message.getRepeatedLazyMessageCount());
-    Assert.assertEquals(2, message.getRepeatedNestedEnumCount());
-    Assert.assertEquals(2, message.getRepeatedForeignEnumCount());
-    Assert.assertEquals(2, message.getRepeatedImportEnumCount());
-
-    Assert.assertEquals(2, message.getRepeatedStringPieceCount());
-    Assert.assertEquals(2, message.getRepeatedCordCount());
-
-    Assert.assertEquals(201, message.getRepeatedInt32(0));
-    Assert.assertEquals(202, message.getRepeatedInt64(0));
-    Assert.assertEquals(203, message.getRepeatedUint32(0));
-    Assert.assertEquals(204, message.getRepeatedUint64(0));
-    Assert.assertEquals(205, message.getRepeatedSint32(0));
-    Assert.assertEquals(206, message.getRepeatedSint64(0));
-    Assert.assertEquals(207, message.getRepeatedFixed32(0));
-    Assert.assertEquals(208, message.getRepeatedFixed64(0));
-    Assert.assertEquals(209, message.getRepeatedSfixed32(0));
-    Assert.assertEquals(210, message.getRepeatedSfixed64(0));
-    Assert.assertEquals(211, message.getRepeatedFloat(0), 0.0);
-    Assert.assertEquals(212, message.getRepeatedDouble(0), 0.0);
-    Assert.assertEquals(true, message.getRepeatedBool(0));
-    Assert.assertEquals("215", message.getRepeatedString(0));
-    Assert.assertEquals(toBytes("216"), message.getRepeatedBytes(0));
-
-    Assert.assertEquals(217, message.getRepeatedGroup(0).getA());
-    Assert.assertEquals(218, message.getRepeatedNestedMessage(0).getBb());
-    Assert.assertEquals(219, message.getRepeatedForeignMessage(0).getC());
-    Assert.assertEquals(220, message.getRepeatedImportMessage(0).getD());
-    Assert.assertEquals(227, message.getRepeatedLazyMessage(0).getBb());
-
-    Assert.assertEquals(TestAllTypes.NestedEnum.BAR, message.getRepeatedNestedEnum(0));
-    Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getRepeatedForeignEnum(0));
-    Assert.assertEquals(ImportEnum.IMPORT_BAR, message.getRepeatedImportEnum(0));
-
-    Assert.assertEquals("224", message.getRepeatedStringPiece(0));
-    Assert.assertEquals("225", message.getRepeatedCord(0));
-
-    Assert.assertEquals(301, message.getRepeatedInt32(1));
-    Assert.assertEquals(302, message.getRepeatedInt64(1));
-    Assert.assertEquals(303, message.getRepeatedUint32(1));
-    Assert.assertEquals(304, message.getRepeatedUint64(1));
-    Assert.assertEquals(305, message.getRepeatedSint32(1));
-    Assert.assertEquals(306, message.getRepeatedSint64(1));
-    Assert.assertEquals(307, message.getRepeatedFixed32(1));
-    Assert.assertEquals(308, message.getRepeatedFixed64(1));
-    Assert.assertEquals(309, message.getRepeatedSfixed32(1));
-    Assert.assertEquals(310, message.getRepeatedSfixed64(1));
-    Assert.assertEquals(311, message.getRepeatedFloat(1), 0.0);
-    Assert.assertEquals(312, message.getRepeatedDouble(1), 0.0);
-    Assert.assertEquals(false, message.getRepeatedBool(1));
-    Assert.assertEquals("315", message.getRepeatedString(1));
-    Assert.assertEquals(toBytes("316"), message.getRepeatedBytes(1));
-
-    Assert.assertEquals(317, message.getRepeatedGroup(1).getA());
-    Assert.assertEquals(318, message.getRepeatedNestedMessage(1).getBb());
-    Assert.assertEquals(319, message.getRepeatedForeignMessage(1).getC());
-    Assert.assertEquals(320, message.getRepeatedImportMessage(1).getD());
-    Assert.assertEquals(327, message.getRepeatedLazyMessage(1).getBb());
-
-    Assert.assertEquals(TestAllTypes.NestedEnum.BAZ, message.getRepeatedNestedEnum(1));
-    Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getRepeatedForeignEnum(1));
-    Assert.assertEquals(ImportEnum.IMPORT_BAZ, message.getRepeatedImportEnum(1));
-
-    Assert.assertEquals("324", message.getRepeatedStringPiece(1));
-    Assert.assertEquals("325", message.getRepeatedCord(1));
-
-    // -----------------------------------------------------------------
-
-    Assert.assertTrue(message.hasDefaultInt32());
-    Assert.assertTrue(message.hasDefaultInt64());
-    Assert.assertTrue(message.hasDefaultUint32());
-    Assert.assertTrue(message.hasDefaultUint64());
-    Assert.assertTrue(message.hasDefaultSint32());
-    Assert.assertTrue(message.hasDefaultSint64());
-    Assert.assertTrue(message.hasDefaultFixed32());
-    Assert.assertTrue(message.hasDefaultFixed64());
-    Assert.assertTrue(message.hasDefaultSfixed32());
-    Assert.assertTrue(message.hasDefaultSfixed64());
-    Assert.assertTrue(message.hasDefaultFloat());
-    Assert.assertTrue(message.hasDefaultDouble());
-    Assert.assertTrue(message.hasDefaultBool());
-    Assert.assertTrue(message.hasDefaultString());
-    Assert.assertTrue(message.hasDefaultBytes());
-
-    Assert.assertTrue(message.hasDefaultNestedEnum());
-    Assert.assertTrue(message.hasDefaultForeignEnum());
-    Assert.assertTrue(message.hasDefaultImportEnum());
-
-    Assert.assertTrue(message.hasDefaultStringPiece());
-    Assert.assertTrue(message.hasDefaultCord());
-
-    Assert.assertEquals(401, message.getDefaultInt32());
-    Assert.assertEquals(402, message.getDefaultInt64());
-    Assert.assertEquals(403, message.getDefaultUint32());
-    Assert.assertEquals(404, message.getDefaultUint64());
-    Assert.assertEquals(405, message.getDefaultSint32());
-    Assert.assertEquals(406, message.getDefaultSint64());
-    Assert.assertEquals(407, message.getDefaultFixed32());
-    Assert.assertEquals(408, message.getDefaultFixed64());
-    Assert.assertEquals(409, message.getDefaultSfixed32());
-    Assert.assertEquals(410, message.getDefaultSfixed64());
-    Assert.assertEquals(411, message.getDefaultFloat(), 0.0);
-    Assert.assertEquals(412, message.getDefaultDouble(), 0.0);
-    Assert.assertEquals(false, message.getDefaultBool());
-    Assert.assertEquals("415", message.getDefaultString());
-    Assert.assertEquals(toBytes("416"), message.getDefaultBytes());
-
-    Assert.assertEquals(TestAllTypes.NestedEnum.FOO, message.getDefaultNestedEnum());
-    Assert.assertEquals(ForeignEnum.FOREIGN_FOO, message.getDefaultForeignEnum());
-    Assert.assertEquals(ImportEnum.IMPORT_FOO, message.getDefaultImportEnum());
-
-    Assert.assertEquals("424", message.getDefaultStringPiece());
-    Assert.assertEquals("425", message.getDefaultCord());
-
-    Assert.assertEquals(TestAllTypes.OneofFieldCase.ONEOF_BYTES, message.getOneofFieldCase());
-    Assert.assertFalse(message.hasOneofUint32());
-    Assert.assertFalse(message.hasOneofNestedMessage());
-    Assert.assertFalse(message.hasOneofString());
-    Assert.assertTrue(message.hasOneofBytes());
-
-    Assert.assertEquals(toBytes("604"), message.getOneofBytes());
-  }
-
-  // -------------------------------------------------------------------
-  /**
-   * Assert (using {@code junit.framework.Assert}} that all fields of {@code message} are cleared,
-   * and that getting the fields returns their default values.
-   */
-  public static void assertClear(TestAllTypesOrBuilder message) {
-    // hasBlah() should initially be false for all optional fields.
-    Assert.assertFalse(message.hasOptionalInt32());
-    Assert.assertFalse(message.hasOptionalInt64());
-    Assert.assertFalse(message.hasOptionalUint32());
-    Assert.assertFalse(message.hasOptionalUint64());
-    Assert.assertFalse(message.hasOptionalSint32());
-    Assert.assertFalse(message.hasOptionalSint64());
-    Assert.assertFalse(message.hasOptionalFixed32());
-    Assert.assertFalse(message.hasOptionalFixed64());
-    Assert.assertFalse(message.hasOptionalSfixed32());
-    Assert.assertFalse(message.hasOptionalSfixed64());
-    Assert.assertFalse(message.hasOptionalFloat());
-    Assert.assertFalse(message.hasOptionalDouble());
-    Assert.assertFalse(message.hasOptionalBool());
-    Assert.assertFalse(message.hasOptionalString());
-    Assert.assertFalse(message.hasOptionalBytes());
-
-    Assert.assertFalse(message.hasOptionalGroup());
-    Assert.assertFalse(message.hasOptionalNestedMessage());
-    Assert.assertFalse(message.hasOptionalForeignMessage());
-    Assert.assertFalse(message.hasOptionalImportMessage());
-
-    Assert.assertFalse(message.hasOptionalNestedEnum());
-    Assert.assertFalse(message.hasOptionalForeignEnum());
-    Assert.assertFalse(message.hasOptionalImportEnum());
-
-    Assert.assertFalse(message.hasOptionalStringPiece());
-    Assert.assertFalse(message.hasOptionalCord());
-
-    // Optional fields without defaults are set to zero or something like it.
-    Assert.assertEquals(0, message.getOptionalInt32());
-    Assert.assertEquals(0, message.getOptionalInt64());
-    Assert.assertEquals(0, message.getOptionalUint32());
-    Assert.assertEquals(0, message.getOptionalUint64());
-    Assert.assertEquals(0, message.getOptionalSint32());
-    Assert.assertEquals(0, message.getOptionalSint64());
-    Assert.assertEquals(0, message.getOptionalFixed32());
-    Assert.assertEquals(0, message.getOptionalFixed64());
-    Assert.assertEquals(0, message.getOptionalSfixed32());
-    Assert.assertEquals(0, message.getOptionalSfixed64());
-    Assert.assertEquals(0, message.getOptionalFloat(), 0.0);
-    Assert.assertEquals(0, message.getOptionalDouble(), 0.0);
-    Assert.assertEquals(false, message.getOptionalBool());
-    Assert.assertEquals("", message.getOptionalString());
-    Assert.assertEquals(ByteString.EMPTY, message.getOptionalBytes());
-
-    // Embedded messages should also be clear.
-    Assert.assertFalse(message.getOptionalGroup().hasA());
-    Assert.assertFalse(message.getOptionalNestedMessage().hasBb());
-    Assert.assertFalse(message.getOptionalForeignMessage().hasC());
-    Assert.assertFalse(message.getOptionalImportMessage().hasD());
-    Assert.assertFalse(message.getOptionalPublicImportMessage().hasE());
-    Assert.assertFalse(message.getOptionalLazyMessage().hasBb());
-
-    Assert.assertEquals(0, message.getOptionalGroup().getA());
-    Assert.assertEquals(0, message.getOptionalNestedMessage().getBb());
-    Assert.assertEquals(0, message.getOptionalForeignMessage().getC());
-    Assert.assertEquals(0, message.getOptionalImportMessage().getD());
-    Assert.assertEquals(0, message.getOptionalPublicImportMessage().getE());
-    Assert.assertEquals(0, message.getOptionalLazyMessage().getBb());
-
-    // Enums without defaults are set to the first value in the enum.
-    Assert.assertEquals(TestAllTypes.NestedEnum.FOO, message.getOptionalNestedEnum());
-    Assert.assertEquals(ForeignEnum.FOREIGN_FOO, message.getOptionalForeignEnum());
-    Assert.assertEquals(ImportEnum.IMPORT_FOO, message.getOptionalImportEnum());
-
-    Assert.assertEquals("", message.getOptionalStringPiece());
-    Assert.assertEquals("", message.getOptionalCord());
-
-    // Repeated fields are empty.
-    Assert.assertEquals(0, message.getRepeatedInt32Count());
-    Assert.assertEquals(0, message.getRepeatedInt64Count());
-    Assert.assertEquals(0, message.getRepeatedUint32Count());
-    Assert.assertEquals(0, message.getRepeatedUint64Count());
-    Assert.assertEquals(0, message.getRepeatedSint32Count());
-    Assert.assertEquals(0, message.getRepeatedSint64Count());
-    Assert.assertEquals(0, message.getRepeatedFixed32Count());
-    Assert.assertEquals(0, message.getRepeatedFixed64Count());
-    Assert.assertEquals(0, message.getRepeatedSfixed32Count());
-    Assert.assertEquals(0, message.getRepeatedSfixed64Count());
-    Assert.assertEquals(0, message.getRepeatedFloatCount());
-    Assert.assertEquals(0, message.getRepeatedDoubleCount());
-    Assert.assertEquals(0, message.getRepeatedBoolCount());
-    Assert.assertEquals(0, message.getRepeatedStringCount());
-    Assert.assertEquals(0, message.getRepeatedBytesCount());
-
-    Assert.assertEquals(0, message.getRepeatedGroupCount());
-    Assert.assertEquals(0, message.getRepeatedNestedMessageCount());
-    Assert.assertEquals(0, message.getRepeatedForeignMessageCount());
-    Assert.assertEquals(0, message.getRepeatedImportMessageCount());
-    Assert.assertEquals(0, message.getRepeatedLazyMessageCount());
-    Assert.assertEquals(0, message.getRepeatedNestedEnumCount());
-    Assert.assertEquals(0, message.getRepeatedForeignEnumCount());
-    Assert.assertEquals(0, message.getRepeatedImportEnumCount());
-
-    Assert.assertEquals(0, message.getRepeatedStringPieceCount());
-    Assert.assertEquals(0, message.getRepeatedCordCount());
-
-    // hasBlah() should also be false for all default fields.
-    Assert.assertFalse(message.hasDefaultInt32());
-    Assert.assertFalse(message.hasDefaultInt64());
-    Assert.assertFalse(message.hasDefaultUint32());
-    Assert.assertFalse(message.hasDefaultUint64());
-    Assert.assertFalse(message.hasDefaultSint32());
-    Assert.assertFalse(message.hasDefaultSint64());
-    Assert.assertFalse(message.hasDefaultFixed32());
-    Assert.assertFalse(message.hasDefaultFixed64());
-    Assert.assertFalse(message.hasDefaultSfixed32());
-    Assert.assertFalse(message.hasDefaultSfixed64());
-    Assert.assertFalse(message.hasDefaultFloat());
-    Assert.assertFalse(message.hasDefaultDouble());
-    Assert.assertFalse(message.hasDefaultBool());
-    Assert.assertFalse(message.hasDefaultString());
-    Assert.assertFalse(message.hasDefaultBytes());
-
-    Assert.assertFalse(message.hasDefaultNestedEnum());
-    Assert.assertFalse(message.hasDefaultForeignEnum());
-    Assert.assertFalse(message.hasDefaultImportEnum());
-
-    Assert.assertFalse(message.hasDefaultStringPiece());
-    Assert.assertFalse(message.hasDefaultCord());
-
-    // Fields with defaults have their default values (duh).
-    Assert.assertEquals(41, message.getDefaultInt32());
-    Assert.assertEquals(42, message.getDefaultInt64());
-    Assert.assertEquals(43, message.getDefaultUint32());
-    Assert.assertEquals(44, message.getDefaultUint64());
-    Assert.assertEquals(-45, message.getDefaultSint32());
-    Assert.assertEquals(46, message.getDefaultSint64());
-    Assert.assertEquals(47, message.getDefaultFixed32());
-    Assert.assertEquals(48, message.getDefaultFixed64());
-    Assert.assertEquals(49, message.getDefaultSfixed32());
-    Assert.assertEquals(-50, message.getDefaultSfixed64());
-    Assert.assertEquals(51.5, message.getDefaultFloat(), 0.0);
-    Assert.assertEquals(52e3, message.getDefaultDouble(), 0.0);
-    Assert.assertEquals(true, message.getDefaultBool());
-    Assert.assertEquals("hello", message.getDefaultString());
-    Assert.assertEquals(toBytes("world"), message.getDefaultBytes());
-
-    Assert.assertEquals(TestAllTypes.NestedEnum.BAR, message.getDefaultNestedEnum());
-    Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getDefaultForeignEnum());
-    Assert.assertEquals(ImportEnum.IMPORT_BAR, message.getDefaultImportEnum());
-
-    Assert.assertEquals("abc", message.getDefaultStringPiece());
-    Assert.assertEquals("123", message.getDefaultCord());
-
-    Assert.assertFalse(message.hasOneofUint32());
-    Assert.assertFalse(message.hasOneofNestedMessage());
-    Assert.assertFalse(message.hasOneofString());
-    Assert.assertFalse(message.hasOneofBytes());
-  }
-
-  // -------------------------------------------------------------------
-
-  /**
-   * Assert (using {@code junit.framework.Assert}} that all fields of {@code message} are set to the
-   * values assigned by {@code setAllFields} followed by {@code modifyRepeatedFields}.
-   */
-  public static void assertRepeatedFieldsModified(TestAllTypesOrBuilder message) {
-    // ModifyRepeatedFields only sets the second repeated element of each
-    // field.  In addition to verifying this, we also verify that the first
-    // element and size were *not* modified.
-    Assert.assertEquals(2, message.getRepeatedInt32Count());
-    Assert.assertEquals(2, message.getRepeatedInt64Count());
-    Assert.assertEquals(2, message.getRepeatedUint32Count());
-    Assert.assertEquals(2, message.getRepeatedUint64Count());
-    Assert.assertEquals(2, message.getRepeatedSint32Count());
-    Assert.assertEquals(2, message.getRepeatedSint64Count());
-    Assert.assertEquals(2, message.getRepeatedFixed32Count());
-    Assert.assertEquals(2, message.getRepeatedFixed64Count());
-    Assert.assertEquals(2, message.getRepeatedSfixed32Count());
-    Assert.assertEquals(2, message.getRepeatedSfixed64Count());
-    Assert.assertEquals(2, message.getRepeatedFloatCount());
-    Assert.assertEquals(2, message.getRepeatedDoubleCount());
-    Assert.assertEquals(2, message.getRepeatedBoolCount());
-    Assert.assertEquals(2, message.getRepeatedStringCount());
-    Assert.assertEquals(2, message.getRepeatedBytesCount());
-
-    Assert.assertEquals(2, message.getRepeatedGroupCount());
-    Assert.assertEquals(2, message.getRepeatedNestedMessageCount());
-    Assert.assertEquals(2, message.getRepeatedForeignMessageCount());
-    Assert.assertEquals(2, message.getRepeatedImportMessageCount());
-    Assert.assertEquals(2, message.getRepeatedLazyMessageCount());
-    Assert.assertEquals(2, message.getRepeatedNestedEnumCount());
-    Assert.assertEquals(2, message.getRepeatedForeignEnumCount());
-    Assert.assertEquals(2, message.getRepeatedImportEnumCount());
-
-    Assert.assertEquals(2, message.getRepeatedStringPieceCount());
-    Assert.assertEquals(2, message.getRepeatedCordCount());
-
-    Assert.assertEquals(201, message.getRepeatedInt32(0));
-    Assert.assertEquals(202L, message.getRepeatedInt64(0));
-    Assert.assertEquals(203, message.getRepeatedUint32(0));
-    Assert.assertEquals(204L, message.getRepeatedUint64(0));
-    Assert.assertEquals(205, message.getRepeatedSint32(0));
-    Assert.assertEquals(206L, message.getRepeatedSint64(0));
-    Assert.assertEquals(207, message.getRepeatedFixed32(0));
-    Assert.assertEquals(208L, message.getRepeatedFixed64(0));
-    Assert.assertEquals(209, message.getRepeatedSfixed32(0));
-    Assert.assertEquals(210L, message.getRepeatedSfixed64(0));
-    Assert.assertEquals(211F, message.getRepeatedFloat(0));
-    Assert.assertEquals(212D, message.getRepeatedDouble(0));
-    Assert.assertEquals(true, message.getRepeatedBool(0));
-    Assert.assertEquals("215", message.getRepeatedString(0));
-    Assert.assertEquals(toBytes("216"), message.getRepeatedBytes(0));
-
-    Assert.assertEquals(217, message.getRepeatedGroup(0).getA());
-    Assert.assertEquals(218, message.getRepeatedNestedMessage(0).getBb());
-    Assert.assertEquals(219, message.getRepeatedForeignMessage(0).getC());
-    Assert.assertEquals(220, message.getRepeatedImportMessage(0).getD());
-    Assert.assertEquals(227, message.getRepeatedLazyMessage(0).getBb());
-
-    Assert.assertEquals(TestAllTypes.NestedEnum.BAR, message.getRepeatedNestedEnum(0));
-    Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getRepeatedForeignEnum(0));
-    Assert.assertEquals(ImportEnum.IMPORT_BAR, message.getRepeatedImportEnum(0));
-
-    Assert.assertEquals("224", message.getRepeatedStringPiece(0));
-    Assert.assertEquals("225", message.getRepeatedCord(0));
-
-    // Actually verify the second (modified) elements now.
-    Assert.assertEquals(501, message.getRepeatedInt32(1));
-    Assert.assertEquals(502L, message.getRepeatedInt64(1));
-    Assert.assertEquals(503, message.getRepeatedUint32(1));
-    Assert.assertEquals(504L, message.getRepeatedUint64(1));
-    Assert.assertEquals(505, message.getRepeatedSint32(1));
-    Assert.assertEquals(506L, message.getRepeatedSint64(1));
-    Assert.assertEquals(507, message.getRepeatedFixed32(1));
-    Assert.assertEquals(508L, message.getRepeatedFixed64(1));
-    Assert.assertEquals(509, message.getRepeatedSfixed32(1));
-    Assert.assertEquals(510L, message.getRepeatedSfixed64(1));
-    Assert.assertEquals(511F, message.getRepeatedFloat(1));
-    Assert.assertEquals(512D, message.getRepeatedDouble(1));
-    Assert.assertEquals(true, message.getRepeatedBool(1));
-    Assert.assertEquals("515", message.getRepeatedString(1));
-    Assert.assertEquals(toBytes("516"), message.getRepeatedBytes(1));
-
-    Assert.assertEquals(517, message.getRepeatedGroup(1).getA());
-    Assert.assertEquals(518, message.getRepeatedNestedMessage(1).getBb());
-    Assert.assertEquals(519, message.getRepeatedForeignMessage(1).getC());
-    Assert.assertEquals(520, message.getRepeatedImportMessage(1).getD());
-    Assert.assertEquals(527, message.getRepeatedLazyMessage(1).getBb());
-
-    Assert.assertEquals(TestAllTypes.NestedEnum.FOO, message.getRepeatedNestedEnum(1));
-    Assert.assertEquals(ForeignEnum.FOREIGN_FOO, message.getRepeatedForeignEnum(1));
-    Assert.assertEquals(ImportEnum.IMPORT_FOO, message.getRepeatedImportEnum(1));
-
-    Assert.assertEquals("524", message.getRepeatedStringPiece(1));
-    Assert.assertEquals("525", message.getRepeatedCord(1));
-  }
-
-  /** Set every field of {@code message} to a unique value. */
-  public static void setPackedFields(TestPackedTypes.Builder message) {
-    message.addPackedInt32(601);
-    message.addPackedInt64(602);
-    message.addPackedUint32(603);
-    message.addPackedUint64(604);
-    message.addPackedSint32(605);
-    message.addPackedSint64(606);
-    message.addPackedFixed32(607);
-    message.addPackedFixed64(608);
-    message.addPackedSfixed32(609);
-    message.addPackedSfixed64(610);
-    message.addPackedFloat(611);
-    message.addPackedDouble(612);
-    message.addPackedBool(true);
-    message.addPackedEnum(ForeignEnum.FOREIGN_BAR);
-    // Add a second one of each field.
-    message.addPackedInt32(701);
-    message.addPackedInt64(702);
-    message.addPackedUint32(703);
-    message.addPackedUint64(704);
-    message.addPackedSint32(705);
-    message.addPackedSint64(706);
-    message.addPackedFixed32(707);
-    message.addPackedFixed64(708);
-    message.addPackedSfixed32(709);
-    message.addPackedSfixed64(710);
-    message.addPackedFloat(711);
-    message.addPackedDouble(712);
-    message.addPackedBool(false);
-    message.addPackedEnum(ForeignEnum.FOREIGN_BAZ);
-  }
-
-  /**
-   * Set every field of {@code message} to a unique value. Must correspond with the values applied
-   * by {@code setPackedFields}.
-   */
-  public static void setUnpackedFields(TestUnpackedTypes.Builder message) {
-    message.addUnpackedInt32(601);
-    message.addUnpackedInt64(602);
-    message.addUnpackedUint32(603);
-    message.addUnpackedUint64(604);
-    message.addUnpackedSint32(605);
-    message.addUnpackedSint64(606);
-    message.addUnpackedFixed32(607);
-    message.addUnpackedFixed64(608);
-    message.addUnpackedSfixed32(609);
-    message.addUnpackedSfixed64(610);
-    message.addUnpackedFloat(611);
-    message.addUnpackedDouble(612);
-    message.addUnpackedBool(true);
-    message.addUnpackedEnum(ForeignEnum.FOREIGN_BAR);
-    // Add a second one of each field.
-    message.addUnpackedInt32(701);
-    message.addUnpackedInt64(702);
-    message.addUnpackedUint32(703);
-    message.addUnpackedUint64(704);
-    message.addUnpackedSint32(705);
-    message.addUnpackedSint64(706);
-    message.addUnpackedFixed32(707);
-    message.addUnpackedFixed64(708);
-    message.addUnpackedSfixed32(709);
-    message.addUnpackedSfixed64(710);
-    message.addUnpackedFloat(711);
-    message.addUnpackedDouble(712);
-    message.addUnpackedBool(false);
-    message.addUnpackedEnum(ForeignEnum.FOREIGN_BAZ);
-  }
-
-  /**
-   * Assert (using {@code junit.framework.Assert}} that all fields of {@code message} are set to the
-   * values assigned by {@code setPackedFields}.
-   */
-  public static void assertPackedFieldsSet(TestPackedTypes message) {
-    Assert.assertEquals(2, message.getPackedInt32Count());
-    Assert.assertEquals(2, message.getPackedInt64Count());
-    Assert.assertEquals(2, message.getPackedUint32Count());
-    Assert.assertEquals(2, message.getPackedUint64Count());
-    Assert.assertEquals(2, message.getPackedSint32Count());
-    Assert.assertEquals(2, message.getPackedSint64Count());
-    Assert.assertEquals(2, message.getPackedFixed32Count());
-    Assert.assertEquals(2, message.getPackedFixed64Count());
-    Assert.assertEquals(2, message.getPackedSfixed32Count());
-    Assert.assertEquals(2, message.getPackedSfixed64Count());
-    Assert.assertEquals(2, message.getPackedFloatCount());
-    Assert.assertEquals(2, message.getPackedDoubleCount());
-    Assert.assertEquals(2, message.getPackedBoolCount());
-    Assert.assertEquals(2, message.getPackedEnumCount());
-    Assert.assertEquals(601, message.getPackedInt32(0));
-    Assert.assertEquals(602, message.getPackedInt64(0));
-    Assert.assertEquals(603, message.getPackedUint32(0));
-    Assert.assertEquals(604, message.getPackedUint64(0));
-    Assert.assertEquals(605, message.getPackedSint32(0));
-    Assert.assertEquals(606, message.getPackedSint64(0));
-    Assert.assertEquals(607, message.getPackedFixed32(0));
-    Assert.assertEquals(608, message.getPackedFixed64(0));
-    Assert.assertEquals(609, message.getPackedSfixed32(0));
-    Assert.assertEquals(610, message.getPackedSfixed64(0));
-    Assert.assertEquals(611, message.getPackedFloat(0), 0.0);
-    Assert.assertEquals(612, message.getPackedDouble(0), 0.0);
-    Assert.assertEquals(true, message.getPackedBool(0));
-    Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getPackedEnum(0));
-    Assert.assertEquals(701, message.getPackedInt32(1));
-    Assert.assertEquals(702, message.getPackedInt64(1));
-    Assert.assertEquals(703, message.getPackedUint32(1));
-    Assert.assertEquals(704, message.getPackedUint64(1));
-    Assert.assertEquals(705, message.getPackedSint32(1));
-    Assert.assertEquals(706, message.getPackedSint64(1));
-    Assert.assertEquals(707, message.getPackedFixed32(1));
-    Assert.assertEquals(708, message.getPackedFixed64(1));
-    Assert.assertEquals(709, message.getPackedSfixed32(1));
-    Assert.assertEquals(710, message.getPackedSfixed64(1));
-    Assert.assertEquals(711, message.getPackedFloat(1), 0.0);
-    Assert.assertEquals(712, message.getPackedDouble(1), 0.0);
-    Assert.assertEquals(false, message.getPackedBool(1));
-    Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getPackedEnum(1));
-  }
-
-  /**
-   * Assert (using {@code junit.framework.Assert}} that all fields of {@code message} are set to the
-   * values assigned by {@code setUnpackedFields}.
-   */
-  public static void assertUnpackedFieldsSet(TestUnpackedTypes message) {
-    Assert.assertEquals(2, message.getUnpackedInt32Count());
-    Assert.assertEquals(2, message.getUnpackedInt64Count());
-    Assert.assertEquals(2, message.getUnpackedUint32Count());
-    Assert.assertEquals(2, message.getUnpackedUint64Count());
-    Assert.assertEquals(2, message.getUnpackedSint32Count());
-    Assert.assertEquals(2, message.getUnpackedSint64Count());
-    Assert.assertEquals(2, message.getUnpackedFixed32Count());
-    Assert.assertEquals(2, message.getUnpackedFixed64Count());
-    Assert.assertEquals(2, message.getUnpackedSfixed32Count());
-    Assert.assertEquals(2, message.getUnpackedSfixed64Count());
-    Assert.assertEquals(2, message.getUnpackedFloatCount());
-    Assert.assertEquals(2, message.getUnpackedDoubleCount());
-    Assert.assertEquals(2, message.getUnpackedBoolCount());
-    Assert.assertEquals(2, message.getUnpackedEnumCount());
-    Assert.assertEquals(601, message.getUnpackedInt32(0));
-    Assert.assertEquals(602, message.getUnpackedInt64(0));
-    Assert.assertEquals(603, message.getUnpackedUint32(0));
-    Assert.assertEquals(604, message.getUnpackedUint64(0));
-    Assert.assertEquals(605, message.getUnpackedSint32(0));
-    Assert.assertEquals(606, message.getUnpackedSint64(0));
-    Assert.assertEquals(607, message.getUnpackedFixed32(0));
-    Assert.assertEquals(608, message.getUnpackedFixed64(0));
-    Assert.assertEquals(609, message.getUnpackedSfixed32(0));
-    Assert.assertEquals(610, message.getUnpackedSfixed64(0));
-    Assert.assertEquals(611, message.getUnpackedFloat(0), 0.0);
-    Assert.assertEquals(612, message.getUnpackedDouble(0), 0.0);
-    Assert.assertEquals(true, message.getUnpackedBool(0));
-    Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getUnpackedEnum(0));
-    Assert.assertEquals(701, message.getUnpackedInt32(1));
-    Assert.assertEquals(702, message.getUnpackedInt64(1));
-    Assert.assertEquals(703, message.getUnpackedUint32(1));
-    Assert.assertEquals(704, message.getUnpackedUint64(1));
-    Assert.assertEquals(705, message.getUnpackedSint32(1));
-    Assert.assertEquals(706, message.getUnpackedSint64(1));
-    Assert.assertEquals(707, message.getUnpackedFixed32(1));
-    Assert.assertEquals(708, message.getUnpackedFixed64(1));
-    Assert.assertEquals(709, message.getUnpackedSfixed32(1));
-    Assert.assertEquals(710, message.getUnpackedSfixed64(1));
-    Assert.assertEquals(711, message.getUnpackedFloat(1), 0.0);
-    Assert.assertEquals(712, message.getUnpackedDouble(1), 0.0);
-    Assert.assertEquals(false, message.getUnpackedBool(1));
-    Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getUnpackedEnum(1));
-  }
-
-  // ===================================================================
-  // Like above, but for extensions
-
-  // Java gets confused with things like assertEquals(int, Integer):  it can't
-  // decide whether to call assertEquals(int, int) or assertEquals(Object,
-  // Object).  So we define these methods to help it.
-  private static void assertEqualsExactType(int a, int b) {
-    Assert.assertEquals(a, b);
-  }
-
-  private static void assertEqualsExactType(long a, long b) {
-    Assert.assertEquals(a, b);
-  }
-
-  private static void assertEqualsExactType(float a, float b) {
-    Assert.assertEquals(a, b, 0.0);
-  }
-
-  private static void assertEqualsExactType(double a, double b) {
-    Assert.assertEquals(a, b, 0.0);
-  }
-
-  private static void assertEqualsExactType(boolean a, boolean b) {
-    Assert.assertEquals(a, b);
-  }
-
-  private static void assertEqualsExactType(String a, String b) {
-    Assert.assertEquals(a, b);
-  }
-
-  private static void assertEqualsExactType(ByteString a, ByteString b) {
-    Assert.assertEquals(a, b);
-  }
-
-  private static void assertEqualsExactType(TestAllTypes.NestedEnum a, TestAllTypes.NestedEnum b) {
-    Assert.assertEquals(a, b);
-  }
-
-  private static void assertEqualsExactType(ForeignEnum a, ForeignEnum b) {
-    Assert.assertEquals(a, b);
-  }
-
-  private static void assertEqualsExactType(ImportEnum a, ImportEnum b) {
-    Assert.assertEquals(a, b);
-  }
-
-  private static void assertEqualsExactType(
-      TestAllTypesLite.NestedEnum a, TestAllTypesLite.NestedEnum b) {
-    Assert.assertEquals(a, b);
-  }
-
-  private static void assertEqualsExactType(ForeignEnumLite a, ForeignEnumLite b) {
-    Assert.assertEquals(a, b);
-  }
-
-  private static void assertEqualsExactType(ImportEnumLite a, ImportEnumLite b) {
-    Assert.assertEquals(a, b);
-  }
-
-  /**
-   * Get an unmodifiable {@link ExtensionRegistry} containing all the extensions of {@code
-   * TestAllExtensions}.
-   */
-  public static ExtensionRegistryLite getExtensionRegistry() {
-    ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance();
-    registerAllExtensions(registry);
-    return registry.getUnmodifiable();
-  }
-
-
-  /**
-   * Register all of {@code TestAllExtensions}'s extensions with the given {@link
-   * ExtensionRegistry}.
-   */
-  public static void registerAllExtensions(ExtensionRegistryLite registry) {
-    UnittestProto.registerAllExtensions(registry);
-    TestUtilLite.registerAllExtensionsLite(registry);
-  }
-
-  /**
-   * Set every field of {@code message} to the values expected by {@code assertAllExtensionsSet()}.
-   */
-  public static void setAllExtensions(TestAllExtensions.Builder message) {
-    message.setExtension(optionalInt32Extension, 101);
-    message.setExtension(optionalInt64Extension, 102L);
-    message.setExtension(optionalUint32Extension, 103);
-    message.setExtension(optionalUint64Extension, 104L);
-    message.setExtension(optionalSint32Extension, 105);
-    message.setExtension(optionalSint64Extension, 106L);
-    message.setExtension(optionalFixed32Extension, 107);
-    message.setExtension(optionalFixed64Extension, 108L);
-    message.setExtension(optionalSfixed32Extension, 109);
-    message.setExtension(optionalSfixed64Extension, 110L);
-    message.setExtension(optionalFloatExtension, 111F);
-    message.setExtension(optionalDoubleExtension, 112D);
-    message.setExtension(optionalBoolExtension, true);
-    message.setExtension(optionalStringExtension, "115");
-    message.setExtension(optionalBytesExtension, toBytes("116"));
-
-    message.setExtension(
-        optionalGroupExtension, OptionalGroup_extension.newBuilder().setA(117).build());
-    message.setExtension(
-        optionalNestedMessageExtension, TestAllTypes.NestedMessage.newBuilder().setBb(118).build());
-    message.setExtension(
-        optionalForeignMessageExtension, ForeignMessage.newBuilder().setC(119).build());
-    message.setExtension(
-        optionalImportMessageExtension, ImportMessage.newBuilder().setD(120).build());
-    message.setExtension(
-        optionalPublicImportMessageExtension, PublicImportMessage.newBuilder().setE(126).build());
-    message.setExtension(
-        optionalLazyMessageExtension, TestAllTypes.NestedMessage.newBuilder().setBb(127).build());
-
-    message.setExtension(optionalNestedEnumExtension, TestAllTypes.NestedEnum.BAZ);
-    message.setExtension(optionalForeignEnumExtension, ForeignEnum.FOREIGN_BAZ);
-    message.setExtension(optionalImportEnumExtension, ImportEnum.IMPORT_BAZ);
-
-    message.setExtension(optionalStringPieceExtension, "124");
-    message.setExtension(optionalCordExtension, "125");
-
-    // -----------------------------------------------------------------
-
-    message.addExtension(repeatedInt32Extension, 201);
-    message.addExtension(repeatedInt64Extension, 202L);
-    message.addExtension(repeatedUint32Extension, 203);
-    message.addExtension(repeatedUint64Extension, 204L);
-    message.addExtension(repeatedSint32Extension, 205);
-    message.addExtension(repeatedSint64Extension, 206L);
-    message.addExtension(repeatedFixed32Extension, 207);
-    message.addExtension(repeatedFixed64Extension, 208L);
-    message.addExtension(repeatedSfixed32Extension, 209);
-    message.addExtension(repeatedSfixed64Extension, 210L);
-    message.addExtension(repeatedFloatExtension, 211F);
-    message.addExtension(repeatedDoubleExtension, 212D);
-    message.addExtension(repeatedBoolExtension, true);
-    message.addExtension(repeatedStringExtension, "215");
-    message.addExtension(repeatedBytesExtension, toBytes("216"));
-
-    message.addExtension(
-        repeatedGroupExtension, RepeatedGroup_extension.newBuilder().setA(217).build());
-    message.addExtension(
-        repeatedNestedMessageExtension, TestAllTypes.NestedMessage.newBuilder().setBb(218).build());
-    message.addExtension(
-        repeatedForeignMessageExtension, ForeignMessage.newBuilder().setC(219).build());
-    message.addExtension(
-        repeatedImportMessageExtension, ImportMessage.newBuilder().setD(220).build());
-    message.addExtension(
-        repeatedLazyMessageExtension, TestAllTypes.NestedMessage.newBuilder().setBb(227).build());
-
-    message.addExtension(repeatedNestedEnumExtension, TestAllTypes.NestedEnum.BAR);
-    message.addExtension(repeatedForeignEnumExtension, ForeignEnum.FOREIGN_BAR);
-    message.addExtension(repeatedImportEnumExtension, ImportEnum.IMPORT_BAR);
-
-    message.addExtension(repeatedStringPieceExtension, "224");
-    message.addExtension(repeatedCordExtension, "225");
-
-    // Add a second one of each field.
-    message.addExtension(repeatedInt32Extension, 301);
-    message.addExtension(repeatedInt64Extension, 302L);
-    message.addExtension(repeatedUint32Extension, 303);
-    message.addExtension(repeatedUint64Extension, 304L);
-    message.addExtension(repeatedSint32Extension, 305);
-    message.addExtension(repeatedSint64Extension, 306L);
-    message.addExtension(repeatedFixed32Extension, 307);
-    message.addExtension(repeatedFixed64Extension, 308L);
-    message.addExtension(repeatedSfixed32Extension, 309);
-    message.addExtension(repeatedSfixed64Extension, 310L);
-    message.addExtension(repeatedFloatExtension, 311F);
-    message.addExtension(repeatedDoubleExtension, 312D);
-    message.addExtension(repeatedBoolExtension, false);
-    message.addExtension(repeatedStringExtension, "315");
-    message.addExtension(repeatedBytesExtension, toBytes("316"));
-
-    message.addExtension(
-        repeatedGroupExtension, RepeatedGroup_extension.newBuilder().setA(317).build());
-    message.addExtension(
-        repeatedNestedMessageExtension, TestAllTypes.NestedMessage.newBuilder().setBb(318).build());
-    message.addExtension(
-        repeatedForeignMessageExtension, ForeignMessage.newBuilder().setC(319).build());
-    message.addExtension(
-        repeatedImportMessageExtension, ImportMessage.newBuilder().setD(320).build());
-    message.addExtension(
-        repeatedLazyMessageExtension, TestAllTypes.NestedMessage.newBuilder().setBb(327).build());
-
-    message.addExtension(repeatedNestedEnumExtension, TestAllTypes.NestedEnum.BAZ);
-    message.addExtension(repeatedForeignEnumExtension, ForeignEnum.FOREIGN_BAZ);
-    message.addExtension(repeatedImportEnumExtension, ImportEnum.IMPORT_BAZ);
-
-    message.addExtension(repeatedStringPieceExtension, "324");
-    message.addExtension(repeatedCordExtension, "325");
-
-    // -----------------------------------------------------------------
-
-    message.setExtension(defaultInt32Extension, 401);
-    message.setExtension(defaultInt64Extension, 402L);
-    message.setExtension(defaultUint32Extension, 403);
-    message.setExtension(defaultUint64Extension, 404L);
-    message.setExtension(defaultSint32Extension, 405);
-    message.setExtension(defaultSint64Extension, 406L);
-    message.setExtension(defaultFixed32Extension, 407);
-    message.setExtension(defaultFixed64Extension, 408L);
-    message.setExtension(defaultSfixed32Extension, 409);
-    message.setExtension(defaultSfixed64Extension, 410L);
-    message.setExtension(defaultFloatExtension, 411F);
-    message.setExtension(defaultDoubleExtension, 412D);
-    message.setExtension(defaultBoolExtension, false);
-    message.setExtension(defaultStringExtension, "415");
-    message.setExtension(defaultBytesExtension, toBytes("416"));
-
-    message.setExtension(defaultNestedEnumExtension, TestAllTypes.NestedEnum.FOO);
-    message.setExtension(defaultForeignEnumExtension, ForeignEnum.FOREIGN_FOO);
-    message.setExtension(defaultImportEnumExtension, ImportEnum.IMPORT_FOO);
-
-    message.setExtension(defaultStringPieceExtension, "424");
-    message.setExtension(defaultCordExtension, "425");
-
-    message.setExtension(oneofUint32Extension, 601);
-    message.setExtension(
-        oneofNestedMessageExtension, TestAllTypes.NestedMessage.newBuilder().setBb(602).build());
-    message.setExtension(oneofStringExtension, "603");
-    message.setExtension(oneofBytesExtension, toBytes("604"));
-  }
-
-  // -------------------------------------------------------------------
-
-  /**
-   * Modify the repeated extensions of {@code message} to contain the values expected by {@code
-   * assertRepeatedExtensionsModified()}.
-   */
-  public static void modifyRepeatedExtensions(TestAllExtensions.Builder message) {
-    message.setExtension(repeatedInt32Extension, 1, 501);
-    message.setExtension(repeatedInt64Extension, 1, 502L);
-    message.setExtension(repeatedUint32Extension, 1, 503);
-    message.setExtension(repeatedUint64Extension, 1, 504L);
-    message.setExtension(repeatedSint32Extension, 1, 505);
-    message.setExtension(repeatedSint64Extension, 1, 506L);
-    message.setExtension(repeatedFixed32Extension, 1, 507);
-    message.setExtension(repeatedFixed64Extension, 1, 508L);
-    message.setExtension(repeatedSfixed32Extension, 1, 509);
-    message.setExtension(repeatedSfixed64Extension, 1, 510L);
-    message.setExtension(repeatedFloatExtension, 1, 511F);
-    message.setExtension(repeatedDoubleExtension, 1, 512D);
-    message.setExtension(repeatedBoolExtension, 1, true);
-    message.setExtension(repeatedStringExtension, 1, "515");
-    message.setExtension(repeatedBytesExtension, 1, toBytes("516"));
-
-    message.setExtension(
-        repeatedGroupExtension, 1, RepeatedGroup_extension.newBuilder().setA(517).build());
-    message.setExtension(
-        repeatedNestedMessageExtension,
-        1,
-        TestAllTypes.NestedMessage.newBuilder().setBb(518).build());
-    message.setExtension(
-        repeatedForeignMessageExtension, 1, ForeignMessage.newBuilder().setC(519).build());
-    message.setExtension(
-        repeatedImportMessageExtension, 1, ImportMessage.newBuilder().setD(520).build());
-    message.setExtension(
-        repeatedLazyMessageExtension,
-        1,
-        TestAllTypes.NestedMessage.newBuilder().setBb(527).build());
-
-    message.setExtension(repeatedNestedEnumExtension, 1, TestAllTypes.NestedEnum.FOO);
-    message.setExtension(repeatedForeignEnumExtension, 1, ForeignEnum.FOREIGN_FOO);
-    message.setExtension(repeatedImportEnumExtension, 1, ImportEnum.IMPORT_FOO);
-
-    message.setExtension(repeatedStringPieceExtension, 1, "524");
-    message.setExtension(repeatedCordExtension, 1, "525");
-  }
-
-  // -------------------------------------------------------------------
-
-  /**
-   * Assert (using {@code junit.framework.Assert}} that all extensions of {@code message} are set to
-   * the values assigned by {@code setAllExtensions}.
-   */
-  public static void assertAllExtensionsSet(TestAllExtensionsOrBuilder message) {
-    Assert.assertTrue(message.hasExtension(optionalInt32Extension));
-    Assert.assertTrue(message.hasExtension(optionalInt64Extension));
-    Assert.assertTrue(message.hasExtension(optionalUint32Extension));
-    Assert.assertTrue(message.hasExtension(optionalUint64Extension));
-    Assert.assertTrue(message.hasExtension(optionalSint32Extension));
-    Assert.assertTrue(message.hasExtension(optionalSint64Extension));
-    Assert.assertTrue(message.hasExtension(optionalFixed32Extension));
-    Assert.assertTrue(message.hasExtension(optionalFixed64Extension));
-    Assert.assertTrue(message.hasExtension(optionalSfixed32Extension));
-    Assert.assertTrue(message.hasExtension(optionalSfixed64Extension));
-    Assert.assertTrue(message.hasExtension(optionalFloatExtension));
-    Assert.assertTrue(message.hasExtension(optionalDoubleExtension));
-    Assert.assertTrue(message.hasExtension(optionalBoolExtension));
-    Assert.assertTrue(message.hasExtension(optionalStringExtension));
-    Assert.assertTrue(message.hasExtension(optionalBytesExtension));
-
-    Assert.assertTrue(message.hasExtension(optionalGroupExtension));
-    Assert.assertTrue(message.hasExtension(optionalNestedMessageExtension));
-    Assert.assertTrue(message.hasExtension(optionalForeignMessageExtension));
-    Assert.assertTrue(message.hasExtension(optionalImportMessageExtension));
-
-    Assert.assertTrue(message.getExtension(optionalGroupExtension).hasA());
-    Assert.assertTrue(message.getExtension(optionalNestedMessageExtension).hasBb());
-    Assert.assertTrue(message.getExtension(optionalForeignMessageExtension).hasC());
-    Assert.assertTrue(message.getExtension(optionalImportMessageExtension).hasD());
-
-    Assert.assertTrue(message.hasExtension(optionalNestedEnumExtension));
-    Assert.assertTrue(message.hasExtension(optionalForeignEnumExtension));
-    Assert.assertTrue(message.hasExtension(optionalImportEnumExtension));
-
-    Assert.assertTrue(message.hasExtension(optionalStringPieceExtension));
-    Assert.assertTrue(message.hasExtension(optionalCordExtension));
-
-    assertEqualsExactType(101, message.getExtension(optionalInt32Extension));
-    assertEqualsExactType(102L, message.getExtension(optionalInt64Extension));
-    assertEqualsExactType(103, message.getExtension(optionalUint32Extension));
-    assertEqualsExactType(104L, message.getExtension(optionalUint64Extension));
-    assertEqualsExactType(105, message.getExtension(optionalSint32Extension));
-    assertEqualsExactType(106L, message.getExtension(optionalSint64Extension));
-    assertEqualsExactType(107, message.getExtension(optionalFixed32Extension));
-    assertEqualsExactType(108L, message.getExtension(optionalFixed64Extension));
-    assertEqualsExactType(109, message.getExtension(optionalSfixed32Extension));
-    assertEqualsExactType(110L, message.getExtension(optionalSfixed64Extension));
-    assertEqualsExactType(111F, message.getExtension(optionalFloatExtension));
-    assertEqualsExactType(112D, message.getExtension(optionalDoubleExtension));
-    assertEqualsExactType(true, message.getExtension(optionalBoolExtension));
-    assertEqualsExactType("115", message.getExtension(optionalStringExtension));
-    assertEqualsExactType(toBytes("116"), message.getExtension(optionalBytesExtension));
-
-    assertEqualsExactType(117, message.getExtension(optionalGroupExtension).getA());
-    assertEqualsExactType(118, message.getExtension(optionalNestedMessageExtension).getBb());
-    assertEqualsExactType(119, message.getExtension(optionalForeignMessageExtension).getC());
-    assertEqualsExactType(120, message.getExtension(optionalImportMessageExtension).getD());
-    assertEqualsExactType(126, message.getExtension(optionalPublicImportMessageExtension).getE());
-    assertEqualsExactType(127, message.getExtension(optionalLazyMessageExtension).getBb());
-
-    assertEqualsExactType(
-        TestAllTypes.NestedEnum.BAZ, message.getExtension(optionalNestedEnumExtension));
-    assertEqualsExactType(
-        ForeignEnum.FOREIGN_BAZ, message.getExtension(optionalForeignEnumExtension));
-    assertEqualsExactType(ImportEnum.IMPORT_BAZ, message.getExtension(optionalImportEnumExtension));
-
-    assertEqualsExactType("124", message.getExtension(optionalStringPieceExtension));
-    assertEqualsExactType("125", message.getExtension(optionalCordExtension));
-
-    // -----------------------------------------------------------------
-
-    Assert.assertEquals(2, message.getExtensionCount(repeatedInt32Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedInt64Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedUint32Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedUint64Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedSint32Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedSint64Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtension));
-
-    Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedLazyMessageExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtension));
-
-    Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtension));
-
-    assertEqualsExactType(201, message.getExtension(repeatedInt32Extension, 0));
-    assertEqualsExactType(202L, message.getExtension(repeatedInt64Extension, 0));
-    assertEqualsExactType(203, message.getExtension(repeatedUint32Extension, 0));
-    assertEqualsExactType(204L, message.getExtension(repeatedUint64Extension, 0));
-    assertEqualsExactType(205, message.getExtension(repeatedSint32Extension, 0));
-    assertEqualsExactType(206L, message.getExtension(repeatedSint64Extension, 0));
-    assertEqualsExactType(207, message.getExtension(repeatedFixed32Extension, 0));
-    assertEqualsExactType(208L, message.getExtension(repeatedFixed64Extension, 0));
-    assertEqualsExactType(209, message.getExtension(repeatedSfixed32Extension, 0));
-    assertEqualsExactType(210L, message.getExtension(repeatedSfixed64Extension, 0));
-    assertEqualsExactType(211F, message.getExtension(repeatedFloatExtension, 0));
-    assertEqualsExactType(212D, message.getExtension(repeatedDoubleExtension, 0));
-    assertEqualsExactType(true, message.getExtension(repeatedBoolExtension, 0));
-    assertEqualsExactType("215", message.getExtension(repeatedStringExtension, 0));
-    assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtension, 0));
-
-    assertEqualsExactType(217, message.getExtension(repeatedGroupExtension, 0).getA());
-    assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtension, 0).getBb());
-    assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtension, 0).getC());
-    assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtension, 0).getD());
-    assertEqualsExactType(227, message.getExtension(repeatedLazyMessageExtension, 0).getBb());
-
-    assertEqualsExactType(
-        TestAllTypes.NestedEnum.BAR, message.getExtension(repeatedNestedEnumExtension, 0));
-    assertEqualsExactType(
-        ForeignEnum.FOREIGN_BAR, message.getExtension(repeatedForeignEnumExtension, 0));
-    assertEqualsExactType(
-        ImportEnum.IMPORT_BAR, message.getExtension(repeatedImportEnumExtension, 0));
-
-    assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtension, 0));
-    assertEqualsExactType("225", message.getExtension(repeatedCordExtension, 0));
-
-    assertEqualsExactType(301, message.getExtension(repeatedInt32Extension, 1));
-    assertEqualsExactType(302L, message.getExtension(repeatedInt64Extension, 1));
-    assertEqualsExactType(303, message.getExtension(repeatedUint32Extension, 1));
-    assertEqualsExactType(304L, message.getExtension(repeatedUint64Extension, 1));
-    assertEqualsExactType(305, message.getExtension(repeatedSint32Extension, 1));
-    assertEqualsExactType(306L, message.getExtension(repeatedSint64Extension, 1));
-    assertEqualsExactType(307, message.getExtension(repeatedFixed32Extension, 1));
-    assertEqualsExactType(308L, message.getExtension(repeatedFixed64Extension, 1));
-    assertEqualsExactType(309, message.getExtension(repeatedSfixed32Extension, 1));
-    assertEqualsExactType(310L, message.getExtension(repeatedSfixed64Extension, 1));
-    assertEqualsExactType(311F, message.getExtension(repeatedFloatExtension, 1));
-    assertEqualsExactType(312D, message.getExtension(repeatedDoubleExtension, 1));
-    assertEqualsExactType(false, message.getExtension(repeatedBoolExtension, 1));
-    assertEqualsExactType("315", message.getExtension(repeatedStringExtension, 1));
-    assertEqualsExactType(toBytes("316"), message.getExtension(repeatedBytesExtension, 1));
-
-    assertEqualsExactType(317, message.getExtension(repeatedGroupExtension, 1).getA());
-    assertEqualsExactType(318, message.getExtension(repeatedNestedMessageExtension, 1).getBb());
-    assertEqualsExactType(319, message.getExtension(repeatedForeignMessageExtension, 1).getC());
-    assertEqualsExactType(320, message.getExtension(repeatedImportMessageExtension, 1).getD());
-    assertEqualsExactType(327, message.getExtension(repeatedLazyMessageExtension, 1).getBb());
-
-    assertEqualsExactType(
-        TestAllTypes.NestedEnum.BAZ, message.getExtension(repeatedNestedEnumExtension, 1));
-    assertEqualsExactType(
-        ForeignEnum.FOREIGN_BAZ, message.getExtension(repeatedForeignEnumExtension, 1));
-    assertEqualsExactType(
-        ImportEnum.IMPORT_BAZ, message.getExtension(repeatedImportEnumExtension, 1));
-
-    assertEqualsExactType("324", message.getExtension(repeatedStringPieceExtension, 1));
-    assertEqualsExactType("325", message.getExtension(repeatedCordExtension, 1));
-
-    // -----------------------------------------------------------------
-
-    Assert.assertTrue(message.hasExtension(defaultInt32Extension));
-    Assert.assertTrue(message.hasExtension(defaultInt64Extension));
-    Assert.assertTrue(message.hasExtension(defaultUint32Extension));
-    Assert.assertTrue(message.hasExtension(defaultUint64Extension));
-    Assert.assertTrue(message.hasExtension(defaultSint32Extension));
-    Assert.assertTrue(message.hasExtension(defaultSint64Extension));
-    Assert.assertTrue(message.hasExtension(defaultFixed32Extension));
-    Assert.assertTrue(message.hasExtension(defaultFixed64Extension));
-    Assert.assertTrue(message.hasExtension(defaultSfixed32Extension));
-    Assert.assertTrue(message.hasExtension(defaultSfixed64Extension));
-    Assert.assertTrue(message.hasExtension(defaultFloatExtension));
-    Assert.assertTrue(message.hasExtension(defaultDoubleExtension));
-    Assert.assertTrue(message.hasExtension(defaultBoolExtension));
-    Assert.assertTrue(message.hasExtension(defaultStringExtension));
-    Assert.assertTrue(message.hasExtension(defaultBytesExtension));
-
-    Assert.assertTrue(message.hasExtension(defaultNestedEnumExtension));
-    Assert.assertTrue(message.hasExtension(defaultForeignEnumExtension));
-    Assert.assertTrue(message.hasExtension(defaultImportEnumExtension));
-
-    Assert.assertTrue(message.hasExtension(defaultStringPieceExtension));
-    Assert.assertTrue(message.hasExtension(defaultCordExtension));
-
-    assertEqualsExactType(401, message.getExtension(defaultInt32Extension));
-    assertEqualsExactType(402L, message.getExtension(defaultInt64Extension));
-    assertEqualsExactType(403, message.getExtension(defaultUint32Extension));
-    assertEqualsExactType(404L, message.getExtension(defaultUint64Extension));
-    assertEqualsExactType(405, message.getExtension(defaultSint32Extension));
-    assertEqualsExactType(406L, message.getExtension(defaultSint64Extension));
-    assertEqualsExactType(407, message.getExtension(defaultFixed32Extension));
-    assertEqualsExactType(408L, message.getExtension(defaultFixed64Extension));
-    assertEqualsExactType(409, message.getExtension(defaultSfixed32Extension));
-    assertEqualsExactType(410L, message.getExtension(defaultSfixed64Extension));
-    assertEqualsExactType(411F, message.getExtension(defaultFloatExtension));
-    assertEqualsExactType(412D, message.getExtension(defaultDoubleExtension));
-    assertEqualsExactType(false, message.getExtension(defaultBoolExtension));
-    assertEqualsExactType("415", message.getExtension(defaultStringExtension));
-    assertEqualsExactType(toBytes("416"), message.getExtension(defaultBytesExtension));
-
-    assertEqualsExactType(
-        TestAllTypes.NestedEnum.FOO, message.getExtension(defaultNestedEnumExtension));
-    assertEqualsExactType(
-        ForeignEnum.FOREIGN_FOO, message.getExtension(defaultForeignEnumExtension));
-    assertEqualsExactType(ImportEnum.IMPORT_FOO, message.getExtension(defaultImportEnumExtension));
-
-    assertEqualsExactType("424", message.getExtension(defaultStringPieceExtension));
-    assertEqualsExactType("425", message.getExtension(defaultCordExtension));
-
-    Assert.assertTrue(message.hasExtension(oneofBytesExtension));
-
-    assertEqualsExactType(toBytes("604"), message.getExtension(oneofBytesExtension));
-  }
-
-  // -------------------------------------------------------------------
-
-  /**
-   * Assert (using {@code junit.framework.Assert}} that all extensions of {@code message} are
-   * cleared, and that getting the extensions returns their default values.
-   */
-  public static void assertExtensionsClear(TestAllExtensionsOrBuilder message) {
-    // hasBlah() should initially be false for all optional fields.
-    Assert.assertFalse(message.hasExtension(optionalInt32Extension));
-    Assert.assertFalse(message.hasExtension(optionalInt64Extension));
-    Assert.assertFalse(message.hasExtension(optionalUint32Extension));
-    Assert.assertFalse(message.hasExtension(optionalUint64Extension));
-    Assert.assertFalse(message.hasExtension(optionalSint32Extension));
-    Assert.assertFalse(message.hasExtension(optionalSint64Extension));
-    Assert.assertFalse(message.hasExtension(optionalFixed32Extension));
-    Assert.assertFalse(message.hasExtension(optionalFixed64Extension));
-    Assert.assertFalse(message.hasExtension(optionalSfixed32Extension));
-    Assert.assertFalse(message.hasExtension(optionalSfixed64Extension));
-    Assert.assertFalse(message.hasExtension(optionalFloatExtension));
-    Assert.assertFalse(message.hasExtension(optionalDoubleExtension));
-    Assert.assertFalse(message.hasExtension(optionalBoolExtension));
-    Assert.assertFalse(message.hasExtension(optionalStringExtension));
-    Assert.assertFalse(message.hasExtension(optionalBytesExtension));
-
-    Assert.assertFalse(message.hasExtension(optionalGroupExtension));
-    Assert.assertFalse(message.hasExtension(optionalNestedMessageExtension));
-    Assert.assertFalse(message.hasExtension(optionalForeignMessageExtension));
-    Assert.assertFalse(message.hasExtension(optionalImportMessageExtension));
-
-    Assert.assertFalse(message.hasExtension(optionalNestedEnumExtension));
-    Assert.assertFalse(message.hasExtension(optionalForeignEnumExtension));
-    Assert.assertFalse(message.hasExtension(optionalImportEnumExtension));
-
-    Assert.assertFalse(message.hasExtension(optionalStringPieceExtension));
-    Assert.assertFalse(message.hasExtension(optionalCordExtension));
-
-    // Optional fields without defaults are set to zero or something like it.
-    assertEqualsExactType(0, message.getExtension(optionalInt32Extension));
-    assertEqualsExactType(0L, message.getExtension(optionalInt64Extension));
-    assertEqualsExactType(0, message.getExtension(optionalUint32Extension));
-    assertEqualsExactType(0L, message.getExtension(optionalUint64Extension));
-    assertEqualsExactType(0, message.getExtension(optionalSint32Extension));
-    assertEqualsExactType(0L, message.getExtension(optionalSint64Extension));
-    assertEqualsExactType(0, message.getExtension(optionalFixed32Extension));
-    assertEqualsExactType(0L, message.getExtension(optionalFixed64Extension));
-    assertEqualsExactType(0, message.getExtension(optionalSfixed32Extension));
-    assertEqualsExactType(0L, message.getExtension(optionalSfixed64Extension));
-    assertEqualsExactType(0F, message.getExtension(optionalFloatExtension));
-    assertEqualsExactType(0D, message.getExtension(optionalDoubleExtension));
-    assertEqualsExactType(false, message.getExtension(optionalBoolExtension));
-    assertEqualsExactType("", message.getExtension(optionalStringExtension));
-    assertEqualsExactType(ByteString.EMPTY, message.getExtension(optionalBytesExtension));
-
-    // Embedded messages should also be clear.
-    Assert.assertFalse(message.getExtension(optionalGroupExtension).hasA());
-    Assert.assertFalse(message.getExtension(optionalNestedMessageExtension).hasBb());
-    Assert.assertFalse(message.getExtension(optionalForeignMessageExtension).hasC());
-    Assert.assertFalse(message.getExtension(optionalImportMessageExtension).hasD());
-
-    assertEqualsExactType(0, message.getExtension(optionalGroupExtension).getA());
-    assertEqualsExactType(0, message.getExtension(optionalNestedMessageExtension).getBb());
-    assertEqualsExactType(0, message.getExtension(optionalForeignMessageExtension).getC());
-    assertEqualsExactType(0, message.getExtension(optionalImportMessageExtension).getD());
-
-    // Enums without defaults are set to the first value in the enum.
-    assertEqualsExactType(
-        TestAllTypes.NestedEnum.FOO, message.getExtension(optionalNestedEnumExtension));
-    assertEqualsExactType(
-        ForeignEnum.FOREIGN_FOO, message.getExtension(optionalForeignEnumExtension));
-    assertEqualsExactType(ImportEnum.IMPORT_FOO, message.getExtension(optionalImportEnumExtension));
-
-    assertEqualsExactType("", message.getExtension(optionalStringPieceExtension));
-    assertEqualsExactType("", message.getExtension(optionalCordExtension));
-
-    // Repeated fields are empty.
-    Assert.assertEquals(0, message.getExtensionCount(repeatedInt32Extension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedInt64Extension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedUint32Extension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedUint64Extension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedSint32Extension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedSint64Extension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedFixed32Extension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedFixed64Extension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed32Extension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed64Extension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedFloatExtension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedDoubleExtension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedBoolExtension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedStringExtension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedBytesExtension));
-
-    Assert.assertEquals(0, message.getExtensionCount(repeatedGroupExtension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedNestedMessageExtension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedForeignMessageExtension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedImportMessageExtension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedLazyMessageExtension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedNestedEnumExtension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedForeignEnumExtension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedImportEnumExtension));
-
-    Assert.assertEquals(0, message.getExtensionCount(repeatedStringPieceExtension));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedCordExtension));
-
-    // Repeated fields are empty via getExtension().size().
-    Assert.assertEquals(0, message.getExtension(repeatedInt32Extension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedInt64Extension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedUint32Extension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedUint64Extension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedSint32Extension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedSint64Extension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedFixed32Extension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedFixed64Extension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedSfixed32Extension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedSfixed64Extension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedFloatExtension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedDoubleExtension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedBoolExtension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedStringExtension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedBytesExtension).size());
-
-    Assert.assertEquals(0, message.getExtension(repeatedGroupExtension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedNestedMessageExtension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedForeignMessageExtension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedImportMessageExtension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedLazyMessageExtension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedNestedEnumExtension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedForeignEnumExtension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedImportEnumExtension).size());
-
-    Assert.assertEquals(0, message.getExtension(repeatedStringPieceExtension).size());
-    Assert.assertEquals(0, message.getExtension(repeatedCordExtension).size());
-
-    // hasBlah() should also be false for all default fields.
-    Assert.assertFalse(message.hasExtension(defaultInt32Extension));
-    Assert.assertFalse(message.hasExtension(defaultInt64Extension));
-    Assert.assertFalse(message.hasExtension(defaultUint32Extension));
-    Assert.assertFalse(message.hasExtension(defaultUint64Extension));
-    Assert.assertFalse(message.hasExtension(defaultSint32Extension));
-    Assert.assertFalse(message.hasExtension(defaultSint64Extension));
-    Assert.assertFalse(message.hasExtension(defaultFixed32Extension));
-    Assert.assertFalse(message.hasExtension(defaultFixed64Extension));
-    Assert.assertFalse(message.hasExtension(defaultSfixed32Extension));
-    Assert.assertFalse(message.hasExtension(defaultSfixed64Extension));
-    Assert.assertFalse(message.hasExtension(defaultFloatExtension));
-    Assert.assertFalse(message.hasExtension(defaultDoubleExtension));
-    Assert.assertFalse(message.hasExtension(defaultBoolExtension));
-    Assert.assertFalse(message.hasExtension(defaultStringExtension));
-    Assert.assertFalse(message.hasExtension(defaultBytesExtension));
-
-    Assert.assertFalse(message.hasExtension(defaultNestedEnumExtension));
-    Assert.assertFalse(message.hasExtension(defaultForeignEnumExtension));
-    Assert.assertFalse(message.hasExtension(defaultImportEnumExtension));
-
-    Assert.assertFalse(message.hasExtension(defaultStringPieceExtension));
-    Assert.assertFalse(message.hasExtension(defaultCordExtension));
-
-    // Fields with defaults have their default values (duh).
-    assertEqualsExactType(41, message.getExtension(defaultInt32Extension));
-    assertEqualsExactType(42L, message.getExtension(defaultInt64Extension));
-    assertEqualsExactType(43, message.getExtension(defaultUint32Extension));
-    assertEqualsExactType(44L, message.getExtension(defaultUint64Extension));
-    assertEqualsExactType(-45, message.getExtension(defaultSint32Extension));
-    assertEqualsExactType(46L, message.getExtension(defaultSint64Extension));
-    assertEqualsExactType(47, message.getExtension(defaultFixed32Extension));
-    assertEqualsExactType(48L, message.getExtension(defaultFixed64Extension));
-    assertEqualsExactType(49, message.getExtension(defaultSfixed32Extension));
-    assertEqualsExactType(-50L, message.getExtension(defaultSfixed64Extension));
-    assertEqualsExactType(51.5F, message.getExtension(defaultFloatExtension));
-    assertEqualsExactType(52e3D, message.getExtension(defaultDoubleExtension));
-    assertEqualsExactType(true, message.getExtension(defaultBoolExtension));
-    assertEqualsExactType("hello", message.getExtension(defaultStringExtension));
-    assertEqualsExactType(toBytes("world"), message.getExtension(defaultBytesExtension));
-
-    assertEqualsExactType(
-        TestAllTypes.NestedEnum.BAR, message.getExtension(defaultNestedEnumExtension));
-    assertEqualsExactType(
-        ForeignEnum.FOREIGN_BAR, message.getExtension(defaultForeignEnumExtension));
-    assertEqualsExactType(ImportEnum.IMPORT_BAR, message.getExtension(defaultImportEnumExtension));
-
-    assertEqualsExactType("abc", message.getExtension(defaultStringPieceExtension));
-    assertEqualsExactType("123", message.getExtension(defaultCordExtension));
-
-    Assert.assertFalse(message.hasExtension(oneofUint32Extension));
-    Assert.assertFalse(message.hasExtension(oneofNestedMessageExtension));
-    Assert.assertFalse(message.hasExtension(oneofStringExtension));
-    Assert.assertFalse(message.hasExtension(oneofBytesExtension));
-  }
-
-  // -------------------------------------------------------------------
-
-  /**
-   * Assert (using {@code junit.framework.Assert}} that all extensions of {@code message} are set to
-   * the values assigned by {@code setAllExtensions} followed by {@code modifyRepeatedExtensions}.
-   */
-  public static void assertRepeatedExtensionsModified(TestAllExtensionsOrBuilder message) {
-    // ModifyRepeatedFields only sets the second repeated element of each
-    // field.  In addition to verifying this, we also verify that the first
-    // element and size were *not* modified.
-    Assert.assertEquals(2, message.getExtensionCount(repeatedInt32Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedInt64Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedUint32Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedUint64Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedSint32Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedSint64Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64Extension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtension));
-
-    Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedLazyMessageExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtension));
-
-    Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtension));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtension));
-
-    assertEqualsExactType(201, message.getExtension(repeatedInt32Extension, 0));
-    assertEqualsExactType(202L, message.getExtension(repeatedInt64Extension, 0));
-    assertEqualsExactType(203, message.getExtension(repeatedUint32Extension, 0));
-    assertEqualsExactType(204L, message.getExtension(repeatedUint64Extension, 0));
-    assertEqualsExactType(205, message.getExtension(repeatedSint32Extension, 0));
-    assertEqualsExactType(206L, message.getExtension(repeatedSint64Extension, 0));
-    assertEqualsExactType(207, message.getExtension(repeatedFixed32Extension, 0));
-    assertEqualsExactType(208L, message.getExtension(repeatedFixed64Extension, 0));
-    assertEqualsExactType(209, message.getExtension(repeatedSfixed32Extension, 0));
-    assertEqualsExactType(210L, message.getExtension(repeatedSfixed64Extension, 0));
-    assertEqualsExactType(211F, message.getExtension(repeatedFloatExtension, 0));
-    assertEqualsExactType(212D, message.getExtension(repeatedDoubleExtension, 0));
-    assertEqualsExactType(true, message.getExtension(repeatedBoolExtension, 0));
-    assertEqualsExactType("215", message.getExtension(repeatedStringExtension, 0));
-    assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtension, 0));
-
-    assertEqualsExactType(217, message.getExtension(repeatedGroupExtension, 0).getA());
-    assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtension, 0).getBb());
-    assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtension, 0).getC());
-    assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtension, 0).getD());
-    assertEqualsExactType(227, message.getExtension(repeatedLazyMessageExtension, 0).getBb());
-
-    assertEqualsExactType(
-        TestAllTypes.NestedEnum.BAR, message.getExtension(repeatedNestedEnumExtension, 0));
-    assertEqualsExactType(
-        ForeignEnum.FOREIGN_BAR, message.getExtension(repeatedForeignEnumExtension, 0));
-    assertEqualsExactType(
-        ImportEnum.IMPORT_BAR, message.getExtension(repeatedImportEnumExtension, 0));
-
-    assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtension, 0));
-    assertEqualsExactType("225", message.getExtension(repeatedCordExtension, 0));
-
-    // Actually verify the second (modified) elements now.
-    assertEqualsExactType(501, message.getExtension(repeatedInt32Extension, 1));
-    assertEqualsExactType(502L, message.getExtension(repeatedInt64Extension, 1));
-    assertEqualsExactType(503, message.getExtension(repeatedUint32Extension, 1));
-    assertEqualsExactType(504L, message.getExtension(repeatedUint64Extension, 1));
-    assertEqualsExactType(505, message.getExtension(repeatedSint32Extension, 1));
-    assertEqualsExactType(506L, message.getExtension(repeatedSint64Extension, 1));
-    assertEqualsExactType(507, message.getExtension(repeatedFixed32Extension, 1));
-    assertEqualsExactType(508L, message.getExtension(repeatedFixed64Extension, 1));
-    assertEqualsExactType(509, message.getExtension(repeatedSfixed32Extension, 1));
-    assertEqualsExactType(510L, message.getExtension(repeatedSfixed64Extension, 1));
-    assertEqualsExactType(511F, message.getExtension(repeatedFloatExtension, 1));
-    assertEqualsExactType(512D, message.getExtension(repeatedDoubleExtension, 1));
-    assertEqualsExactType(true, message.getExtension(repeatedBoolExtension, 1));
-    assertEqualsExactType("515", message.getExtension(repeatedStringExtension, 1));
-    assertEqualsExactType(toBytes("516"), message.getExtension(repeatedBytesExtension, 1));
-
-    assertEqualsExactType(517, message.getExtension(repeatedGroupExtension, 1).getA());
-    assertEqualsExactType(518, message.getExtension(repeatedNestedMessageExtension, 1).getBb());
-    assertEqualsExactType(519, message.getExtension(repeatedForeignMessageExtension, 1).getC());
-    assertEqualsExactType(520, message.getExtension(repeatedImportMessageExtension, 1).getD());
-    assertEqualsExactType(527, message.getExtension(repeatedLazyMessageExtension, 1).getBb());
-
-    assertEqualsExactType(
-        TestAllTypes.NestedEnum.FOO, message.getExtension(repeatedNestedEnumExtension, 1));
-    assertEqualsExactType(
-        ForeignEnum.FOREIGN_FOO, message.getExtension(repeatedForeignEnumExtension, 1));
-    assertEqualsExactType(
-        ImportEnum.IMPORT_FOO, message.getExtension(repeatedImportEnumExtension, 1));
-
-    assertEqualsExactType("524", message.getExtension(repeatedStringPieceExtension, 1));
-    assertEqualsExactType("525", message.getExtension(repeatedCordExtension, 1));
-  }
-
-  public static void setPackedExtensions(TestPackedExtensions.Builder message) {
-    message.addExtension(packedInt32Extension, 601);
-    message.addExtension(packedInt64Extension, 602L);
-    message.addExtension(packedUint32Extension, 603);
-    message.addExtension(packedUint64Extension, 604L);
-    message.addExtension(packedSint32Extension, 605);
-    message.addExtension(packedSint64Extension, 606L);
-    message.addExtension(packedFixed32Extension, 607);
-    message.addExtension(packedFixed64Extension, 608L);
-    message.addExtension(packedSfixed32Extension, 609);
-    message.addExtension(packedSfixed64Extension, 610L);
-    message.addExtension(packedFloatExtension, 611F);
-    message.addExtension(packedDoubleExtension, 612D);
-    message.addExtension(packedBoolExtension, true);
-    message.addExtension(packedEnumExtension, ForeignEnum.FOREIGN_BAR);
-    // Add a second one of each field.
-    message.addExtension(packedInt32Extension, 701);
-    message.addExtension(packedInt64Extension, 702L);
-    message.addExtension(packedUint32Extension, 703);
-    message.addExtension(packedUint64Extension, 704L);
-    message.addExtension(packedSint32Extension, 705);
-    message.addExtension(packedSint64Extension, 706L);
-    message.addExtension(packedFixed32Extension, 707);
-    message.addExtension(packedFixed64Extension, 708L);
-    message.addExtension(packedSfixed32Extension, 709);
-    message.addExtension(packedSfixed64Extension, 710L);
-    message.addExtension(packedFloatExtension, 711F);
-    message.addExtension(packedDoubleExtension, 712D);
-    message.addExtension(packedBoolExtension, false);
-    message.addExtension(packedEnumExtension, ForeignEnum.FOREIGN_BAZ);
-  }
-
-  public static void assertPackedExtensionsSet(TestPackedExtensions message) {
-    Assert.assertEquals(2, message.getExtensionCount(packedInt32Extension));
-    Assert.assertEquals(2, message.getExtensionCount(packedInt64Extension));
-    Assert.assertEquals(2, message.getExtensionCount(packedUint32Extension));
-    Assert.assertEquals(2, message.getExtensionCount(packedUint64Extension));
-    Assert.assertEquals(2, message.getExtensionCount(packedSint32Extension));
-    Assert.assertEquals(2, message.getExtensionCount(packedSint64Extension));
-    Assert.assertEquals(2, message.getExtensionCount(packedFixed32Extension));
-    Assert.assertEquals(2, message.getExtensionCount(packedFixed64Extension));
-    Assert.assertEquals(2, message.getExtensionCount(packedSfixed32Extension));
-    Assert.assertEquals(2, message.getExtensionCount(packedSfixed64Extension));
-    Assert.assertEquals(2, message.getExtensionCount(packedFloatExtension));
-    Assert.assertEquals(2, message.getExtensionCount(packedDoubleExtension));
-    Assert.assertEquals(2, message.getExtensionCount(packedBoolExtension));
-    Assert.assertEquals(2, message.getExtensionCount(packedEnumExtension));
-    assertEqualsExactType(601, message.getExtension(packedInt32Extension, 0));
-    assertEqualsExactType(602L, message.getExtension(packedInt64Extension, 0));
-    assertEqualsExactType(603, message.getExtension(packedUint32Extension, 0));
-    assertEqualsExactType(604L, message.getExtension(packedUint64Extension, 0));
-    assertEqualsExactType(605, message.getExtension(packedSint32Extension, 0));
-    assertEqualsExactType(606L, message.getExtension(packedSint64Extension, 0));
-    assertEqualsExactType(607, message.getExtension(packedFixed32Extension, 0));
-    assertEqualsExactType(608L, message.getExtension(packedFixed64Extension, 0));
-    assertEqualsExactType(609, message.getExtension(packedSfixed32Extension, 0));
-    assertEqualsExactType(610L, message.getExtension(packedSfixed64Extension, 0));
-    assertEqualsExactType(611F, message.getExtension(packedFloatExtension, 0));
-    assertEqualsExactType(612D, message.getExtension(packedDoubleExtension, 0));
-    assertEqualsExactType(true, message.getExtension(packedBoolExtension, 0));
-    assertEqualsExactType(ForeignEnum.FOREIGN_BAR, message.getExtension(packedEnumExtension, 0));
-    assertEqualsExactType(701, message.getExtension(packedInt32Extension, 1));
-    assertEqualsExactType(702L, message.getExtension(packedInt64Extension, 1));
-    assertEqualsExactType(703, message.getExtension(packedUint32Extension, 1));
-    assertEqualsExactType(704L, message.getExtension(packedUint64Extension, 1));
-    assertEqualsExactType(705, message.getExtension(packedSint32Extension, 1));
-    assertEqualsExactType(706L, message.getExtension(packedSint64Extension, 1));
-    assertEqualsExactType(707, message.getExtension(packedFixed32Extension, 1));
-    assertEqualsExactType(708L, message.getExtension(packedFixed64Extension, 1));
-    assertEqualsExactType(709, message.getExtension(packedSfixed32Extension, 1));
-    assertEqualsExactType(710L, message.getExtension(packedSfixed64Extension, 1));
-    assertEqualsExactType(711F, message.getExtension(packedFloatExtension, 1));
-    assertEqualsExactType(712D, message.getExtension(packedDoubleExtension, 1));
-    assertEqualsExactType(false, message.getExtension(packedBoolExtension, 1));
-    assertEqualsExactType(ForeignEnum.FOREIGN_BAZ, message.getExtension(packedEnumExtension, 1));
-  }
-
-  // ===================================================================
-  // Lite extensions
-
-  /**
-   * Assert (using {@code junit.framework.Assert}} that all extensions of {@code message} are set to
-   * the values assigned by {@code setAllExtensions}.
-   */
-  public static void assertAllExtensionsSet(TestAllExtensionsLiteOrBuilder message) {
-    Assert.assertTrue(message.hasExtension(optionalInt32ExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalInt64ExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalUint32ExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalUint64ExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalSint32ExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalSint64ExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalFixed32ExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalFixed64ExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalSfixed32ExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalSfixed64ExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalFloatExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalDoubleExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalBoolExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalStringExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalBytesExtensionLite));
-
-    Assert.assertTrue(message.hasExtension(optionalGroupExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalNestedMessageExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalForeignMessageExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalImportMessageExtensionLite));
-
-    Assert.assertTrue(message.getExtension(optionalGroupExtensionLite).hasA());
-    Assert.assertTrue(message.getExtension(optionalNestedMessageExtensionLite).hasBb());
-    Assert.assertTrue(message.getExtension(optionalForeignMessageExtensionLite).hasC());
-    Assert.assertTrue(message.getExtension(optionalImportMessageExtensionLite).hasD());
-
-    Assert.assertTrue(message.hasExtension(optionalNestedEnumExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalForeignEnumExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalImportEnumExtensionLite));
-
-    Assert.assertTrue(message.hasExtension(optionalStringPieceExtensionLite));
-    Assert.assertTrue(message.hasExtension(optionalCordExtensionLite));
-
-    assertEqualsExactType(101, message.getExtension(optionalInt32ExtensionLite));
-    assertEqualsExactType(102L, message.getExtension(optionalInt64ExtensionLite));
-    assertEqualsExactType(103, message.getExtension(optionalUint32ExtensionLite));
-    assertEqualsExactType(104L, message.getExtension(optionalUint64ExtensionLite));
-    assertEqualsExactType(105, message.getExtension(optionalSint32ExtensionLite));
-    assertEqualsExactType(106L, message.getExtension(optionalSint64ExtensionLite));
-    assertEqualsExactType(107, message.getExtension(optionalFixed32ExtensionLite));
-    assertEqualsExactType(108L, message.getExtension(optionalFixed64ExtensionLite));
-    assertEqualsExactType(109, message.getExtension(optionalSfixed32ExtensionLite));
-    assertEqualsExactType(110L, message.getExtension(optionalSfixed64ExtensionLite));
-    assertEqualsExactType(111F, message.getExtension(optionalFloatExtensionLite));
-    assertEqualsExactType(112D, message.getExtension(optionalDoubleExtensionLite));
-    assertEqualsExactType(true, message.getExtension(optionalBoolExtensionLite));
-    assertEqualsExactType("115", message.getExtension(optionalStringExtensionLite));
-    assertEqualsExactType(toBytes("116"), message.getExtension(optionalBytesExtensionLite));
-
-    assertEqualsExactType(117, message.getExtension(optionalGroupExtensionLite).getA());
-    assertEqualsExactType(118, message.getExtension(optionalNestedMessageExtensionLite).getBb());
-    assertEqualsExactType(119, message.getExtension(optionalForeignMessageExtensionLite).getC());
-    assertEqualsExactType(120, message.getExtension(optionalImportMessageExtensionLite).getD());
-    assertEqualsExactType(
-        126, message.getExtension(optionalPublicImportMessageExtensionLite).getE());
-    assertEqualsExactType(127, message.getExtension(optionalLazyMessageExtensionLite).getBb());
-
-    assertEqualsExactType(
-        TestAllTypesLite.NestedEnum.BAZ, message.getExtension(optionalNestedEnumExtensionLite));
-    assertEqualsExactType(
-        ForeignEnumLite.FOREIGN_LITE_BAZ, message.getExtension(optionalForeignEnumExtensionLite));
-    assertEqualsExactType(
-        ImportEnumLite.IMPORT_LITE_BAZ, message.getExtension(optionalImportEnumExtensionLite));
-
-    assertEqualsExactType("124", message.getExtension(optionalStringPieceExtensionLite));
-    assertEqualsExactType("125", message.getExtension(optionalCordExtensionLite));
-
-    // -----------------------------------------------------------------
-
-    Assert.assertEquals(2, message.getExtensionCount(repeatedInt32ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedInt64ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedUint32ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedUint64ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedSint32ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedSint64ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtensionLite));
-
-    Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedLazyMessageExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtensionLite));
-
-    Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtensionLite));
-
-    assertEqualsExactType(201, message.getExtension(repeatedInt32ExtensionLite, 0));
-    assertEqualsExactType(202L, message.getExtension(repeatedInt64ExtensionLite, 0));
-    assertEqualsExactType(203, message.getExtension(repeatedUint32ExtensionLite, 0));
-    assertEqualsExactType(204L, message.getExtension(repeatedUint64ExtensionLite, 0));
-    assertEqualsExactType(205, message.getExtension(repeatedSint32ExtensionLite, 0));
-    assertEqualsExactType(206L, message.getExtension(repeatedSint64ExtensionLite, 0));
-    assertEqualsExactType(207, message.getExtension(repeatedFixed32ExtensionLite, 0));
-    assertEqualsExactType(208L, message.getExtension(repeatedFixed64ExtensionLite, 0));
-    assertEqualsExactType(209, message.getExtension(repeatedSfixed32ExtensionLite, 0));
-    assertEqualsExactType(210L, message.getExtension(repeatedSfixed64ExtensionLite, 0));
-    assertEqualsExactType(211F, message.getExtension(repeatedFloatExtensionLite, 0));
-    assertEqualsExactType(212D, message.getExtension(repeatedDoubleExtensionLite, 0));
-    assertEqualsExactType(true, message.getExtension(repeatedBoolExtensionLite, 0));
-    assertEqualsExactType("215", message.getExtension(repeatedStringExtensionLite, 0));
-    assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtensionLite, 0));
-
-    assertEqualsExactType(217, message.getExtension(repeatedGroupExtensionLite, 0).getA());
-    assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtensionLite, 0).getBb());
-    assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtensionLite, 0).getC());
-    assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtensionLite, 0).getD());
-    assertEqualsExactType(227, message.getExtension(repeatedLazyMessageExtensionLite, 0).getBb());
-
-    assertEqualsExactType(
-        TestAllTypesLite.NestedEnum.BAR, message.getExtension(repeatedNestedEnumExtensionLite, 0));
-    assertEqualsExactType(
-        ForeignEnumLite.FOREIGN_LITE_BAR,
-        message.getExtension(repeatedForeignEnumExtensionLite, 0));
-    assertEqualsExactType(
-        ImportEnumLite.IMPORT_LITE_BAR, message.getExtension(repeatedImportEnumExtensionLite, 0));
-
-    assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtensionLite, 0));
-    assertEqualsExactType("225", message.getExtension(repeatedCordExtensionLite, 0));
-
-    assertEqualsExactType(301, message.getExtension(repeatedInt32ExtensionLite, 1));
-    assertEqualsExactType(302L, message.getExtension(repeatedInt64ExtensionLite, 1));
-    assertEqualsExactType(303, message.getExtension(repeatedUint32ExtensionLite, 1));
-    assertEqualsExactType(304L, message.getExtension(repeatedUint64ExtensionLite, 1));
-    assertEqualsExactType(305, message.getExtension(repeatedSint32ExtensionLite, 1));
-    assertEqualsExactType(306L, message.getExtension(repeatedSint64ExtensionLite, 1));
-    assertEqualsExactType(307, message.getExtension(repeatedFixed32ExtensionLite, 1));
-    assertEqualsExactType(308L, message.getExtension(repeatedFixed64ExtensionLite, 1));
-    assertEqualsExactType(309, message.getExtension(repeatedSfixed32ExtensionLite, 1));
-    assertEqualsExactType(310L, message.getExtension(repeatedSfixed64ExtensionLite, 1));
-    assertEqualsExactType(311F, message.getExtension(repeatedFloatExtensionLite, 1));
-    assertEqualsExactType(312D, message.getExtension(repeatedDoubleExtensionLite, 1));
-    assertEqualsExactType(false, message.getExtension(repeatedBoolExtensionLite, 1));
-    assertEqualsExactType("315", message.getExtension(repeatedStringExtensionLite, 1));
-    assertEqualsExactType(toBytes("316"), message.getExtension(repeatedBytesExtensionLite, 1));
-
-    assertEqualsExactType(317, message.getExtension(repeatedGroupExtensionLite, 1).getA());
-    assertEqualsExactType(318, message.getExtension(repeatedNestedMessageExtensionLite, 1).getBb());
-    assertEqualsExactType(319, message.getExtension(repeatedForeignMessageExtensionLite, 1).getC());
-    assertEqualsExactType(320, message.getExtension(repeatedImportMessageExtensionLite, 1).getD());
-    assertEqualsExactType(327, message.getExtension(repeatedLazyMessageExtensionLite, 1).getBb());
-
-    assertEqualsExactType(
-        TestAllTypesLite.NestedEnum.BAZ, message.getExtension(repeatedNestedEnumExtensionLite, 1));
-    assertEqualsExactType(
-        ForeignEnumLite.FOREIGN_LITE_BAZ,
-        message.getExtension(repeatedForeignEnumExtensionLite, 1));
-    assertEqualsExactType(
-        ImportEnumLite.IMPORT_LITE_BAZ, message.getExtension(repeatedImportEnumExtensionLite, 1));
-
-    assertEqualsExactType("324", message.getExtension(repeatedStringPieceExtensionLite, 1));
-    assertEqualsExactType("325", message.getExtension(repeatedCordExtensionLite, 1));
-
-    // -----------------------------------------------------------------
-
-    Assert.assertTrue(message.hasExtension(defaultInt32ExtensionLite));
-    Assert.assertTrue(message.hasExtension(defaultInt64ExtensionLite));
-    Assert.assertTrue(message.hasExtension(defaultUint32ExtensionLite));
-    Assert.assertTrue(message.hasExtension(defaultUint64ExtensionLite));
-    Assert.assertTrue(message.hasExtension(defaultSint32ExtensionLite));
-    Assert.assertTrue(message.hasExtension(defaultSint64ExtensionLite));
-    Assert.assertTrue(message.hasExtension(defaultFixed32ExtensionLite));
-    Assert.assertTrue(message.hasExtension(defaultFixed64ExtensionLite));
-    Assert.assertTrue(message.hasExtension(defaultSfixed32ExtensionLite));
-    Assert.assertTrue(message.hasExtension(defaultSfixed64ExtensionLite));
-    Assert.assertTrue(message.hasExtension(defaultFloatExtensionLite));
-    Assert.assertTrue(message.hasExtension(defaultDoubleExtensionLite));
-    Assert.assertTrue(message.hasExtension(defaultBoolExtensionLite));
-    Assert.assertTrue(message.hasExtension(defaultStringExtensionLite));
-    Assert.assertTrue(message.hasExtension(defaultBytesExtensionLite));
-
-    Assert.assertTrue(message.hasExtension(defaultNestedEnumExtensionLite));
-    Assert.assertTrue(message.hasExtension(defaultForeignEnumExtensionLite));
-    Assert.assertTrue(message.hasExtension(defaultImportEnumExtensionLite));
-
-    Assert.assertTrue(message.hasExtension(defaultStringPieceExtensionLite));
-    Assert.assertTrue(message.hasExtension(defaultCordExtensionLite));
-
-    assertEqualsExactType(401, message.getExtension(defaultInt32ExtensionLite));
-    assertEqualsExactType(402L, message.getExtension(defaultInt64ExtensionLite));
-    assertEqualsExactType(403, message.getExtension(defaultUint32ExtensionLite));
-    assertEqualsExactType(404L, message.getExtension(defaultUint64ExtensionLite));
-    assertEqualsExactType(405, message.getExtension(defaultSint32ExtensionLite));
-    assertEqualsExactType(406L, message.getExtension(defaultSint64ExtensionLite));
-    assertEqualsExactType(407, message.getExtension(defaultFixed32ExtensionLite));
-    assertEqualsExactType(408L, message.getExtension(defaultFixed64ExtensionLite));
-    assertEqualsExactType(409, message.getExtension(defaultSfixed32ExtensionLite));
-    assertEqualsExactType(410L, message.getExtension(defaultSfixed64ExtensionLite));
-    assertEqualsExactType(411F, message.getExtension(defaultFloatExtensionLite));
-    assertEqualsExactType(412D, message.getExtension(defaultDoubleExtensionLite));
-    assertEqualsExactType(false, message.getExtension(defaultBoolExtensionLite));
-    assertEqualsExactType("415", message.getExtension(defaultStringExtensionLite));
-    assertEqualsExactType(toBytes("416"), message.getExtension(defaultBytesExtensionLite));
-
-    assertEqualsExactType(
-        TestAllTypesLite.NestedEnum.FOO, message.getExtension(defaultNestedEnumExtensionLite));
-    assertEqualsExactType(
-        ForeignEnumLite.FOREIGN_LITE_FOO, message.getExtension(defaultForeignEnumExtensionLite));
-    assertEqualsExactType(
-        ImportEnumLite.IMPORT_LITE_FOO, message.getExtension(defaultImportEnumExtensionLite));
-
-    assertEqualsExactType("424", message.getExtension(defaultStringPieceExtensionLite));
-    assertEqualsExactType("425", message.getExtension(defaultCordExtensionLite));
-
-    Assert.assertTrue(message.hasExtension(oneofBytesExtensionLite));
-
-    assertEqualsExactType(toBytes("604"), message.getExtension(oneofBytesExtensionLite));
-  }
-
-  // -------------------------------------------------------------------
-
-  /**
-   * Assert (using {@code junit.framework.Assert}} that all extensions of {@code message} are
-   * cleared, and that getting the extensions returns their default values.
-   */
-  public static void assertExtensionsClear(TestAllExtensionsLiteOrBuilder message) {
-    // hasBlah() should initially be false for all optional fields.
-    Assert.assertFalse(message.hasExtension(optionalInt32ExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalInt64ExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalUint32ExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalUint64ExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalSint32ExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalSint64ExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalFixed32ExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalFixed64ExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalSfixed32ExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalSfixed64ExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalFloatExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalDoubleExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalBoolExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalStringExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalBytesExtensionLite));
-
-    Assert.assertFalse(message.hasExtension(optionalGroupExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalNestedMessageExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalForeignMessageExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalImportMessageExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalPublicImportMessageExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalLazyMessageExtensionLite));
-
-    Assert.assertFalse(message.hasExtension(optionalNestedEnumExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalForeignEnumExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalImportEnumExtensionLite));
-
-    Assert.assertFalse(message.hasExtension(optionalStringPieceExtensionLite));
-    Assert.assertFalse(message.hasExtension(optionalCordExtensionLite));
-
-    // Optional fields without defaults are set to zero or something like it.
-    assertEqualsExactType(0, message.getExtension(optionalInt32ExtensionLite));
-    assertEqualsExactType(0L, message.getExtension(optionalInt64ExtensionLite));
-    assertEqualsExactType(0, message.getExtension(optionalUint32ExtensionLite));
-    assertEqualsExactType(0L, message.getExtension(optionalUint64ExtensionLite));
-    assertEqualsExactType(0, message.getExtension(optionalSint32ExtensionLite));
-    assertEqualsExactType(0L, message.getExtension(optionalSint64ExtensionLite));
-    assertEqualsExactType(0, message.getExtension(optionalFixed32ExtensionLite));
-    assertEqualsExactType(0L, message.getExtension(optionalFixed64ExtensionLite));
-    assertEqualsExactType(0, message.getExtension(optionalSfixed32ExtensionLite));
-    assertEqualsExactType(0L, message.getExtension(optionalSfixed64ExtensionLite));
-    assertEqualsExactType(0F, message.getExtension(optionalFloatExtensionLite));
-    assertEqualsExactType(0D, message.getExtension(optionalDoubleExtensionLite));
-    assertEqualsExactType(false, message.getExtension(optionalBoolExtensionLite));
-    assertEqualsExactType("", message.getExtension(optionalStringExtensionLite));
-    assertEqualsExactType(ByteString.EMPTY, message.getExtension(optionalBytesExtensionLite));
-
-    // Embedded messages should also be clear.
-    Assert.assertFalse(message.getExtension(optionalGroupExtensionLite).hasA());
-    Assert.assertFalse(message.getExtension(optionalNestedMessageExtensionLite).hasBb());
-    Assert.assertFalse(message.getExtension(optionalForeignMessageExtensionLite).hasC());
-    Assert.assertFalse(message.getExtension(optionalImportMessageExtensionLite).hasD());
-    Assert.assertFalse(message.getExtension(optionalPublicImportMessageExtensionLite).hasE());
-    Assert.assertFalse(message.getExtension(optionalLazyMessageExtensionLite).hasBb());
-
-    assertEqualsExactType(0, message.getExtension(optionalGroupExtensionLite).getA());
-    assertEqualsExactType(0, message.getExtension(optionalNestedMessageExtensionLite).getBb());
-    assertEqualsExactType(0, message.getExtension(optionalForeignMessageExtensionLite).getC());
-    assertEqualsExactType(0, message.getExtension(optionalImportMessageExtensionLite).getD());
-    assertEqualsExactType(0, message.getExtension(optionalPublicImportMessageExtensionLite).getE());
-    assertEqualsExactType(0, message.getExtension(optionalLazyMessageExtensionLite).getBb());
-
-    // Enums without defaults are set to the first value in the enum.
-    assertEqualsExactType(
-        TestAllTypesLite.NestedEnum.FOO, message.getExtension(optionalNestedEnumExtensionLite));
-    assertEqualsExactType(
-        ForeignEnumLite.FOREIGN_LITE_FOO, message.getExtension(optionalForeignEnumExtensionLite));
-    assertEqualsExactType(
-        ImportEnumLite.IMPORT_LITE_FOO, message.getExtension(optionalImportEnumExtensionLite));
-
-    assertEqualsExactType("", message.getExtension(optionalStringPieceExtensionLite));
-    assertEqualsExactType("", message.getExtension(optionalCordExtensionLite));
-
-    // Repeated fields are empty.
-    Assert.assertEquals(0, message.getExtensionCount(repeatedInt32ExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedInt64ExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedUint32ExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedUint64ExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedSint32ExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedSint64ExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedFixed32ExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedFixed64ExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed32ExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed64ExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedFloatExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedDoubleExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedBoolExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedStringExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedBytesExtensionLite));
-
-    Assert.assertEquals(0, message.getExtensionCount(repeatedGroupExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedNestedMessageExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedForeignMessageExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedImportMessageExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedLazyMessageExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedNestedEnumExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedForeignEnumExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedImportEnumExtensionLite));
-
-    Assert.assertEquals(0, message.getExtensionCount(repeatedStringPieceExtensionLite));
-    Assert.assertEquals(0, message.getExtensionCount(repeatedCordExtensionLite));
-
-    // hasBlah() should also be false for all default fields.
-    Assert.assertFalse(message.hasExtension(defaultInt32ExtensionLite));
-    Assert.assertFalse(message.hasExtension(defaultInt64ExtensionLite));
-    Assert.assertFalse(message.hasExtension(defaultUint32ExtensionLite));
-    Assert.assertFalse(message.hasExtension(defaultUint64ExtensionLite));
-    Assert.assertFalse(message.hasExtension(defaultSint32ExtensionLite));
-    Assert.assertFalse(message.hasExtension(defaultSint64ExtensionLite));
-    Assert.assertFalse(message.hasExtension(defaultFixed32ExtensionLite));
-    Assert.assertFalse(message.hasExtension(defaultFixed64ExtensionLite));
-    Assert.assertFalse(message.hasExtension(defaultSfixed32ExtensionLite));
-    Assert.assertFalse(message.hasExtension(defaultSfixed64ExtensionLite));
-    Assert.assertFalse(message.hasExtension(defaultFloatExtensionLite));
-    Assert.assertFalse(message.hasExtension(defaultDoubleExtensionLite));
-    Assert.assertFalse(message.hasExtension(defaultBoolExtensionLite));
-    Assert.assertFalse(message.hasExtension(defaultStringExtensionLite));
-    Assert.assertFalse(message.hasExtension(defaultBytesExtensionLite));
-
-    Assert.assertFalse(message.hasExtension(defaultNestedEnumExtensionLite));
-    Assert.assertFalse(message.hasExtension(defaultForeignEnumExtensionLite));
-    Assert.assertFalse(message.hasExtension(defaultImportEnumExtensionLite));
-
-    Assert.assertFalse(message.hasExtension(defaultStringPieceExtensionLite));
-    Assert.assertFalse(message.hasExtension(defaultCordExtensionLite));
-
-    // Fields with defaults have their default values (duh).
-    assertEqualsExactType(41, message.getExtension(defaultInt32ExtensionLite));
-    assertEqualsExactType(42L, message.getExtension(defaultInt64ExtensionLite));
-    assertEqualsExactType(43, message.getExtension(defaultUint32ExtensionLite));
-    assertEqualsExactType(44L, message.getExtension(defaultUint64ExtensionLite));
-    assertEqualsExactType(-45, message.getExtension(defaultSint32ExtensionLite));
-    assertEqualsExactType(46L, message.getExtension(defaultSint64ExtensionLite));
-    assertEqualsExactType(47, message.getExtension(defaultFixed32ExtensionLite));
-    assertEqualsExactType(48L, message.getExtension(defaultFixed64ExtensionLite));
-    assertEqualsExactType(49, message.getExtension(defaultSfixed32ExtensionLite));
-    assertEqualsExactType(-50L, message.getExtension(defaultSfixed64ExtensionLite));
-    assertEqualsExactType(51.5F, message.getExtension(defaultFloatExtensionLite));
-    assertEqualsExactType(52e3D, message.getExtension(defaultDoubleExtensionLite));
-    assertEqualsExactType(true, message.getExtension(defaultBoolExtensionLite));
-    assertEqualsExactType("hello", message.getExtension(defaultStringExtensionLite));
-    assertEqualsExactType(toBytes("world"), message.getExtension(defaultBytesExtensionLite));
-
-    assertEqualsExactType(
-        TestAllTypesLite.NestedEnum.BAR, message.getExtension(defaultNestedEnumExtensionLite));
-    assertEqualsExactType(
-        ForeignEnumLite.FOREIGN_LITE_BAR, message.getExtension(defaultForeignEnumExtensionLite));
-    assertEqualsExactType(
-        ImportEnumLite.IMPORT_LITE_BAR, message.getExtension(defaultImportEnumExtensionLite));
-
-    assertEqualsExactType("abc", message.getExtension(defaultStringPieceExtensionLite));
-    assertEqualsExactType("123", message.getExtension(defaultCordExtensionLite));
-
-    Assert.assertFalse(message.hasExtension(oneofUint32ExtensionLite));
-    Assert.assertFalse(message.hasExtension(oneofNestedMessageExtensionLite));
-    Assert.assertFalse(message.hasExtension(oneofStringExtensionLite));
-    Assert.assertFalse(message.hasExtension(oneofBytesExtensionLite));
-  }
-
-  // -------------------------------------------------------------------
-
-  /**
-   * Assert (using {@code junit.framework.Assert}} that all extensions of {@code message} are set to
-   * the values assigned by {@code setAllExtensions} followed by {@code modifyRepeatedExtensions}.
-   */
-  public static void assertRepeatedExtensionsModified(TestAllExtensionsLiteOrBuilder message) {
-    // ModifyRepeatedFields only sets the second repeated element of each
-    // field.  In addition to verifying this, we also verify that the first
-    // element and size were *not* modified.
-    Assert.assertEquals(2, message.getExtensionCount(repeatedInt32ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedInt64ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedUint32ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedUint64ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedSint32ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedSint64ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtensionLite));
-
-    Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedLazyMessageExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtensionLite));
-
-    Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtensionLite));
-
-    assertEqualsExactType(201, message.getExtension(repeatedInt32ExtensionLite, 0));
-    assertEqualsExactType(202L, message.getExtension(repeatedInt64ExtensionLite, 0));
-    assertEqualsExactType(203, message.getExtension(repeatedUint32ExtensionLite, 0));
-    assertEqualsExactType(204L, message.getExtension(repeatedUint64ExtensionLite, 0));
-    assertEqualsExactType(205, message.getExtension(repeatedSint32ExtensionLite, 0));
-    assertEqualsExactType(206L, message.getExtension(repeatedSint64ExtensionLite, 0));
-    assertEqualsExactType(207, message.getExtension(repeatedFixed32ExtensionLite, 0));
-    assertEqualsExactType(208L, message.getExtension(repeatedFixed64ExtensionLite, 0));
-    assertEqualsExactType(209, message.getExtension(repeatedSfixed32ExtensionLite, 0));
-    assertEqualsExactType(210L, message.getExtension(repeatedSfixed64ExtensionLite, 0));
-    assertEqualsExactType(211F, message.getExtension(repeatedFloatExtensionLite, 0));
-    assertEqualsExactType(212D, message.getExtension(repeatedDoubleExtensionLite, 0));
-    assertEqualsExactType(true, message.getExtension(repeatedBoolExtensionLite, 0));
-    assertEqualsExactType("215", message.getExtension(repeatedStringExtensionLite, 0));
-    assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtensionLite, 0));
-
-    assertEqualsExactType(217, message.getExtension(repeatedGroupExtensionLite, 0).getA());
-    assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtensionLite, 0).getBb());
-    assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtensionLite, 0).getC());
-    assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtensionLite, 0).getD());
-    assertEqualsExactType(227, message.getExtension(repeatedLazyMessageExtensionLite, 0).getBb());
-
-    assertEqualsExactType(
-        TestAllTypesLite.NestedEnum.BAR, message.getExtension(repeatedNestedEnumExtensionLite, 0));
-    assertEqualsExactType(
-        ForeignEnumLite.FOREIGN_LITE_BAR,
-        message.getExtension(repeatedForeignEnumExtensionLite, 0));
-    assertEqualsExactType(
-        ImportEnumLite.IMPORT_LITE_BAR, message.getExtension(repeatedImportEnumExtensionLite, 0));
-
-    assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtensionLite, 0));
-    assertEqualsExactType("225", message.getExtension(repeatedCordExtensionLite, 0));
-
-    // Actually verify the second (modified) elements now.
-    assertEqualsExactType(501, message.getExtension(repeatedInt32ExtensionLite, 1));
-    assertEqualsExactType(502L, message.getExtension(repeatedInt64ExtensionLite, 1));
-    assertEqualsExactType(503, message.getExtension(repeatedUint32ExtensionLite, 1));
-    assertEqualsExactType(504L, message.getExtension(repeatedUint64ExtensionLite, 1));
-    assertEqualsExactType(505, message.getExtension(repeatedSint32ExtensionLite, 1));
-    assertEqualsExactType(506L, message.getExtension(repeatedSint64ExtensionLite, 1));
-    assertEqualsExactType(507, message.getExtension(repeatedFixed32ExtensionLite, 1));
-    assertEqualsExactType(508L, message.getExtension(repeatedFixed64ExtensionLite, 1));
-    assertEqualsExactType(509, message.getExtension(repeatedSfixed32ExtensionLite, 1));
-    assertEqualsExactType(510L, message.getExtension(repeatedSfixed64ExtensionLite, 1));
-    assertEqualsExactType(511F, message.getExtension(repeatedFloatExtensionLite, 1));
-    assertEqualsExactType(512D, message.getExtension(repeatedDoubleExtensionLite, 1));
-    assertEqualsExactType(true, message.getExtension(repeatedBoolExtensionLite, 1));
-    assertEqualsExactType("515", message.getExtension(repeatedStringExtensionLite, 1));
-    assertEqualsExactType(toBytes("516"), message.getExtension(repeatedBytesExtensionLite, 1));
-
-    assertEqualsExactType(517, message.getExtension(repeatedGroupExtensionLite, 1).getA());
-    assertEqualsExactType(518, message.getExtension(repeatedNestedMessageExtensionLite, 1).getBb());
-    assertEqualsExactType(519, message.getExtension(repeatedForeignMessageExtensionLite, 1).getC());
-    assertEqualsExactType(520, message.getExtension(repeatedImportMessageExtensionLite, 1).getD());
-    assertEqualsExactType(527, message.getExtension(repeatedLazyMessageExtensionLite, 1).getBb());
-
-    assertEqualsExactType(
-        TestAllTypesLite.NestedEnum.FOO, message.getExtension(repeatedNestedEnumExtensionLite, 1));
-    assertEqualsExactType(
-        ForeignEnumLite.FOREIGN_LITE_FOO,
-        message.getExtension(repeatedForeignEnumExtensionLite, 1));
-    assertEqualsExactType(
-        ImportEnumLite.IMPORT_LITE_FOO, message.getExtension(repeatedImportEnumExtensionLite, 1));
-
-    assertEqualsExactType("524", message.getExtension(repeatedStringPieceExtensionLite, 1));
-    assertEqualsExactType("525", message.getExtension(repeatedCordExtensionLite, 1));
-  }
-
-  public static void assertPackedExtensionsSet(TestPackedExtensionsLite message) {
-    Assert.assertEquals(2, message.getExtensionCount(packedInt32ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(packedInt64ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(packedUint32ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(packedUint64ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(packedSint32ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(packedSint64ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(packedFixed32ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(packedFixed64ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(packedSfixed32ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(packedSfixed64ExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(packedFloatExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(packedDoubleExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(packedBoolExtensionLite));
-    Assert.assertEquals(2, message.getExtensionCount(packedEnumExtensionLite));
-    assertEqualsExactType(601, message.getExtension(packedInt32ExtensionLite, 0));
-    assertEqualsExactType(602L, message.getExtension(packedInt64ExtensionLite, 0));
-    assertEqualsExactType(603, message.getExtension(packedUint32ExtensionLite, 0));
-    assertEqualsExactType(604L, message.getExtension(packedUint64ExtensionLite, 0));
-    assertEqualsExactType(605, message.getExtension(packedSint32ExtensionLite, 0));
-    assertEqualsExactType(606L, message.getExtension(packedSint64ExtensionLite, 0));
-    assertEqualsExactType(607, message.getExtension(packedFixed32ExtensionLite, 0));
-    assertEqualsExactType(608L, message.getExtension(packedFixed64ExtensionLite, 0));
-    assertEqualsExactType(609, message.getExtension(packedSfixed32ExtensionLite, 0));
-    assertEqualsExactType(610L, message.getExtension(packedSfixed64ExtensionLite, 0));
-    assertEqualsExactType(611F, message.getExtension(packedFloatExtensionLite, 0));
-    assertEqualsExactType(612D, message.getExtension(packedDoubleExtensionLite, 0));
-    assertEqualsExactType(true, message.getExtension(packedBoolExtensionLite, 0));
-    assertEqualsExactType(
-        ForeignEnumLite.FOREIGN_LITE_BAR, message.getExtension(packedEnumExtensionLite, 0));
-    assertEqualsExactType(701, message.getExtension(packedInt32ExtensionLite, 1));
-    assertEqualsExactType(702L, message.getExtension(packedInt64ExtensionLite, 1));
-    assertEqualsExactType(703, message.getExtension(packedUint32ExtensionLite, 1));
-    assertEqualsExactType(704L, message.getExtension(packedUint64ExtensionLite, 1));
-    assertEqualsExactType(705, message.getExtension(packedSint32ExtensionLite, 1));
-    assertEqualsExactType(706L, message.getExtension(packedSint64ExtensionLite, 1));
-    assertEqualsExactType(707, message.getExtension(packedFixed32ExtensionLite, 1));
-    assertEqualsExactType(708L, message.getExtension(packedFixed64ExtensionLite, 1));
-    assertEqualsExactType(709, message.getExtension(packedSfixed32ExtensionLite, 1));
-    assertEqualsExactType(710L, message.getExtension(packedSfixed64ExtensionLite, 1));
-    assertEqualsExactType(711F, message.getExtension(packedFloatExtensionLite, 1));
-    assertEqualsExactType(712D, message.getExtension(packedDoubleExtensionLite, 1));
-    assertEqualsExactType(false, message.getExtension(packedBoolExtensionLite, 1));
-    assertEqualsExactType(
-        ForeignEnumLite.FOREIGN_LITE_BAZ, message.getExtension(packedEnumExtensionLite, 1));
-  }
-
-  // ===================================================================
-  // oneof
-  public static void setOneof(TestOneof2.Builder message) {
-    message.setFooLazyMessage(TestOneof2.NestedMessage.newBuilder().setQuxInt(100).build());
-    message.setBarString("101");
-    message.setBazInt(102);
-    message.setBazString("103");
-  }
-
-  public static void assertOneofSet(TestOneof2 message) {
-    Assert.assertTrue(message.hasFooLazyMessage());
-    Assert.assertTrue(message.getFooLazyMessage().hasQuxInt());
-
-    Assert.assertTrue(message.hasBarString());
-    Assert.assertTrue(message.hasBazInt());
-    Assert.assertTrue(message.hasBazString());
-
-    Assert.assertEquals(100, message.getFooLazyMessage().getQuxInt());
-    Assert.assertEquals("101", message.getBarString());
-    Assert.assertEquals(102, message.getBazInt());
-    Assert.assertEquals("103", message.getBazString());
-  }
-
-  public static void assertAtMostOneFieldSetOneof(TestOneof2 message) {
-    int count = 0;
-    if (message.hasFooInt()) {
-      ++count;
-    }
-    if (message.hasFooString()) {
-      ++count;
-    }
-    if (message.hasFooCord()) {
-      ++count;
-    }
-    if (message.hasFooStringPiece()) {
-      ++count;
-    }
-    if (message.hasFooBytes()) {
-      ++count;
-    }
-    if (message.hasFooEnum()) {
-      ++count;
-    }
-    if (message.hasFooMessage()) {
-      ++count;
-    }
-    if (message.hasFooGroup()) {
-      ++count;
-    }
-    if (message.hasFooLazyMessage()) {
-      ++count;
-    }
-    Assert.assertTrue(count <= 1);
-
-    count = 0;
-    if (message.hasBarInt()) {
-      ++count;
-    }
-    if (message.hasBarString()) {
-      ++count;
-    }
-    if (message.hasBarCord()) {
-      ++count;
-    }
-    if (message.hasBarStringPiece()) {
-      ++count;
-    }
-    if (message.hasBarBytes()) {
-      ++count;
-    }
-    if (message.hasBarEnum()) {
-      ++count;
-    }
-    Assert.assertTrue(count <= 1);
-
-    switch (message.getFooCase()) {
-      case FOO_INT:
-        Assert.assertTrue(message.hasFooInt());
-        break;
-      case FOO_STRING:
-        Assert.assertTrue(message.hasFooString());
-        break;
-      case FOO_CORD:
-        Assert.assertTrue(message.hasFooCord());
-        break;
-      case FOO_STRING_PIECE:
-        Assert.assertTrue(message.hasFooStringPiece());
-        break;
-      case FOO_BYTES:
-        Assert.assertTrue(message.hasFooBytes());
-        break;
-      case FOO_ENUM:
-        Assert.assertTrue(message.hasFooEnum());
-        break;
-      case FOO_MESSAGE:
-        Assert.assertTrue(message.hasFooMessage());
-        break;
-      case FOOGROUP:
-        Assert.assertTrue(message.hasFooGroup());
-        break;
-      case FOO_LAZY_MESSAGE:
-        Assert.assertTrue(message.hasFooLazyMessage());
-        break;
-      case FOO_NOT_SET:
-        break;
-        // TODO(b/18683919): go/enum-switch-lsc
-    }
-  }
-
-  // =================================================================
-
-  private static ByteString readBytesFromResource(String name) {
-    try {
-      return ByteString.copyFrom(
-          com.google.common.io.ByteStreams.toByteArray(TestUtil.class.getResourceAsStream(name)));
-    } catch (IOException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  /**
-   * Get the bytes of the "golden message". This is a serialized TestAllTypes with all fields set as
-   * they would be by {@link #setAllFields(TestAllTypes.Builder)}, but it is loaded from a file on
-   * disk rather than generated dynamically. The file is actually generated by C++ code, so testing
-   * against it verifies compatibility with C++.
-   */
-  public static ByteString getGoldenMessage() {
-    if (goldenMessage == null) {
-      goldenMessage =
-          readBytesFromResource("/google/protobuf/testdata/golden_message_oneof_implemented");
-    }
-    return goldenMessage;
-  }
-
-  private static ByteString goldenMessage = null;
-
-  /**
-   * Get the bytes of the "golden packed fields message". This is a serialized TestPackedTypes with
-   * all fields set as they would be by {@link #setPackedFields(TestPackedTypes.Builder)}, but it is
-   * loaded from a file on disk rather than generated dynamically. The file is actually generated by
-   * C++ code, so testing against it verifies compatibility with C++.
-   */
-  public static ByteString getGoldenPackedFieldsMessage() {
-    if (goldenPackedFieldsMessage == null) {
-      goldenPackedFieldsMessage =
-          readBytesFromResource("/google/protobuf/testdata/golden_packed_fields_message");
-    }
-    return goldenPackedFieldsMessage;
-  }
-
-  private static ByteString goldenPackedFieldsMessage = null;
-
-
-  /** Helper class to test logged messages */
-  public static class TestLogHandler extends Handler {
-    /** We will keep a private list of all logged records */
-    private final List<LogRecord> list = new ArrayList<>();
-
-    /** Adds the most recently logged record to our list. */
-    @Override
-    public synchronized void publish(LogRecord record) {
-      list.add(record);
-    }
-
-    @Override
-    public void flush() {}
-
-    @Override
-    public void close() {}
-
-    /** Returns a snapshot of the logged records. */
-    public synchronized List<LogRecord> getStoredLogRecords() {
-      List<LogRecord> result = new ArrayList<>(list);
-      return Collections.unmodifiableList(result);
-    }
-  }
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestUtilLite.java b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestUtilLite.java
deleted file mode 100644
index 993dd9d..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestUtilLite.java
+++ /dev/null
@@ -1,551 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf;
-
-import static com.google.protobuf.UnittestLite.defaultBoolExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultBytesExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultCordExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultDoubleExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultFixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultFixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultFloatExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultForeignEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultImportEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultInt32ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultInt64ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultNestedEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultSfixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultSfixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultSint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultSint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultStringExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultStringPieceExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultUint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultUint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.oneofBytesExtensionLite;
-import static com.google.protobuf.UnittestLite.oneofNestedMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.oneofStringExtensionLite;
-import static com.google.protobuf.UnittestLite.oneofUint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalBoolExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalBytesExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalCordExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalDoubleExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalFixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalFixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalFloatExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalForeignEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalForeignMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalGroupExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalImportEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalImportMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalInt32ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalInt64ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalLazyMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalNestedEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalNestedMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalPublicImportMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalSfixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalSfixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalSint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalSint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalStringExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalStringPieceExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalUint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalUint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedBoolExtensionLite;
-import static com.google.protobuf.UnittestLite.packedDoubleExtensionLite;
-import static com.google.protobuf.UnittestLite.packedEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.packedFixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedFixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedFloatExtensionLite;
-import static com.google.protobuf.UnittestLite.packedInt32ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedInt64ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedSfixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedSfixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedSint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedSint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedUint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedUint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedBoolExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedBytesExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedCordExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedDoubleExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedFixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedFixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedFloatExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedForeignEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedForeignMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedGroupExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedImportEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedImportMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedInt32ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedInt64ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedLazyMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedNestedEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedNestedMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedSfixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedSfixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedSint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedSint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedStringExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedStringPieceExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedUint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedUint64ExtensionLite;
-
-import com.google.protobuf.UnittestImportLite.ImportEnumLite;
-import com.google.protobuf.UnittestImportLite.ImportMessageLite;
-import com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite;
-import com.google.protobuf.UnittestLite.ForeignEnumLite;
-import com.google.protobuf.UnittestLite.ForeignMessageLite;
-import com.google.protobuf.UnittestLite.OptionalGroup_extension_lite;
-import com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite;
-import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
-import com.google.protobuf.UnittestLite.TestAllTypesLite;
-import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
-
-/**
- * Contains methods for setting fields of {@code TestAllTypesLite}, {@code TestAllExtensionsLite},
- * and {@code TestPackedExtensionsLite}. This is analogous to the functionality in TestUtil.java but
- * does not depend on the presence of any non-lite protos.
- *
- * <p>This code is not to be used outside of {@code com.google.protobuf} and subpackages.
- */
-public final class TestUtilLite {
-  private TestUtilLite() {}
-
-  /** Helper to convert a String to ByteString. */
-  public static ByteString toBytes(String str) {
-    return ByteString.copyFromUtf8(str);
-  }
-
-  /**
-   * Get a {@code TestAllTypesLite.Builder} with all fields set as they would be by {@link
-   * #setAllFields(TestAllTypesLite.Builder)}.
-   */
-  public static TestAllTypesLite.Builder getAllLiteSetBuilder() {
-    TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder();
-    setAllFields(builder);
-    return builder;
-  }
-
-  /**
-   * Get a {@code TestAllExtensionsLite} with all fields set as they would be by {@link
-   * #setAllExtensions(TestAllExtensionsLite.Builder)}.
-   */
-  public static TestAllExtensionsLite getAllLiteExtensionsSet() {
-    TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
-    setAllExtensions(builder);
-    return builder.build();
-  }
-
-  public static TestPackedExtensionsLite getLitePackedExtensionsSet() {
-    TestPackedExtensionsLite.Builder builder = TestPackedExtensionsLite.newBuilder();
-    setPackedExtensions(builder);
-    return builder.build();
-  }
-
-  /** Set every field of {@code builder} to the values expected by {@code assertAllFieldsSet()}. */
-  public static void setAllFields(TestAllTypesLite.Builder builder) {
-    builder.setOptionalInt32(101);
-    builder.setOptionalInt64(102);
-    builder.setOptionalUint32(103);
-    builder.setOptionalUint64(104);
-    builder.setOptionalSint32(105);
-    builder.setOptionalSint64(106);
-    builder.setOptionalFixed32(107);
-    builder.setOptionalFixed64(108);
-    builder.setOptionalSfixed32(109);
-    builder.setOptionalSfixed64(110);
-    builder.setOptionalFloat(111);
-    builder.setOptionalDouble(112);
-    builder.setOptionalBool(true);
-    builder.setOptionalString("115");
-    builder.setOptionalBytes(toBytes("116"));
-
-    builder.setOptionalGroup(TestAllTypesLite.OptionalGroup.newBuilder().setA(117).build());
-    builder.setOptionalNestedMessage(
-        TestAllTypesLite.NestedMessage.newBuilder().setBb(118).build());
-    builder.setOptionalForeignMessage(ForeignMessageLite.newBuilder().setC(119).build());
-    builder.setOptionalImportMessage(ImportMessageLite.newBuilder().setD(120).build());
-    builder.setOptionalPublicImportMessage(PublicImportMessageLite.newBuilder().setE(126).build());
-    builder.setOptionalLazyMessage(TestAllTypesLite.NestedMessage.newBuilder().setBb(127).build());
-
-    builder.setOptionalNestedEnum(TestAllTypesLite.NestedEnum.BAZ);
-    builder.setOptionalForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAZ);
-    builder.setOptionalImportEnum(ImportEnumLite.IMPORT_LITE_BAZ);
-
-    builder.setOptionalStringPiece("124");
-    builder.setOptionalCord("125");
-
-    // -----------------------------------------------------------------
-
-    builder.addRepeatedInt32(201);
-    builder.addRepeatedInt64(202);
-    builder.addRepeatedUint32(203);
-    builder.addRepeatedUint64(204);
-    builder.addRepeatedSint32(205);
-    builder.addRepeatedSint64(206);
-    builder.addRepeatedFixed32(207);
-    builder.addRepeatedFixed64(208);
-    builder.addRepeatedSfixed32(209);
-    builder.addRepeatedSfixed64(210);
-    builder.addRepeatedFloat(211);
-    builder.addRepeatedDouble(212);
-    builder.addRepeatedBool(true);
-    builder.addRepeatedString("215");
-    builder.addRepeatedBytes(toBytes("216"));
-
-    builder.addRepeatedGroup(TestAllTypesLite.RepeatedGroup.newBuilder().setA(217).build());
-    builder.addRepeatedNestedMessage(
-        TestAllTypesLite.NestedMessage.newBuilder().setBb(218).build());
-    builder.addRepeatedForeignMessage(ForeignMessageLite.newBuilder().setC(219).build());
-    builder.addRepeatedImportMessage(ImportMessageLite.newBuilder().setD(220).build());
-    builder.addRepeatedLazyMessage(TestAllTypesLite.NestedMessage.newBuilder().setBb(227).build());
-
-    builder.addRepeatedNestedEnum(TestAllTypesLite.NestedEnum.BAR);
-    builder.addRepeatedForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR);
-    builder.addRepeatedImportEnum(ImportEnumLite.IMPORT_LITE_BAR);
-
-    builder.addRepeatedStringPiece("224");
-    builder.addRepeatedCord("225");
-
-    // Add a second one of each field.
-    builder.addRepeatedInt32(301);
-    builder.addRepeatedInt64(302);
-    builder.addRepeatedUint32(303);
-    builder.addRepeatedUint64(304);
-    builder.addRepeatedSint32(305);
-    builder.addRepeatedSint64(306);
-    builder.addRepeatedFixed32(307);
-    builder.addRepeatedFixed64(308);
-    builder.addRepeatedSfixed32(309);
-    builder.addRepeatedSfixed64(310);
-    builder.addRepeatedFloat(311);
-    builder.addRepeatedDouble(312);
-    builder.addRepeatedBool(false);
-    builder.addRepeatedString("315");
-    builder.addRepeatedBytes(toBytes("316"));
-
-    builder.addRepeatedGroup(TestAllTypesLite.RepeatedGroup.newBuilder().setA(317).build());
-    builder.addRepeatedNestedMessage(
-        TestAllTypesLite.NestedMessage.newBuilder().setBb(318).build());
-    builder.addRepeatedForeignMessage(ForeignMessageLite.newBuilder().setC(319).build());
-    builder.addRepeatedImportMessage(ImportMessageLite.newBuilder().setD(320).build());
-    builder.addRepeatedLazyMessage(TestAllTypesLite.NestedMessage.newBuilder().setBb(327).build());
-
-    builder.addRepeatedNestedEnum(TestAllTypesLite.NestedEnum.BAZ);
-    builder.addRepeatedForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAZ);
-    builder.addRepeatedImportEnum(ImportEnumLite.IMPORT_LITE_BAZ);
-
-    builder.addRepeatedStringPiece("324");
-    builder.addRepeatedCord("325");
-
-    // -----------------------------------------------------------------
-
-    builder.setDefaultInt32(401);
-    builder.setDefaultInt64(402);
-    builder.setDefaultUint32(403);
-    builder.setDefaultUint64(404);
-    builder.setDefaultSint32(405);
-    builder.setDefaultSint64(406);
-    builder.setDefaultFixed32(407);
-    builder.setDefaultFixed64(408);
-    builder.setDefaultSfixed32(409);
-    builder.setDefaultSfixed64(410);
-    builder.setDefaultFloat(411);
-    builder.setDefaultDouble(412);
-    builder.setDefaultBool(false);
-    builder.setDefaultString("415");
-    builder.setDefaultBytes(toBytes("416"));
-
-    builder.setDefaultNestedEnum(TestAllTypesLite.NestedEnum.FOO);
-    builder.setDefaultForeignEnum(ForeignEnumLite.FOREIGN_LITE_FOO);
-    builder.setDefaultImportEnum(ImportEnumLite.IMPORT_LITE_FOO);
-
-    builder.setDefaultStringPiece("424");
-    builder.setDefaultCord("425");
-
-    builder.setOneofUint32(601);
-    builder.setOneofNestedMessage(TestAllTypesLite.NestedMessage.newBuilder().setBb(602).build());
-    builder.setOneofString("603");
-    builder.setOneofBytes(toBytes("604"));
-  }
-
-  /**
-   * Get an unmodifiable {@link ExtensionRegistryLite} containing all the extensions of {@code
-   * TestAllExtensionsLite}.
-   */
-  public static ExtensionRegistryLite getExtensionRegistryLite() {
-    ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance();
-    registerAllExtensionsLite(registry);
-    return registry.getUnmodifiable();
-  }
-
-  /**
-   * Register all of {@code TestAllExtensionsLite}'s extensions with the given {@link
-   * ExtensionRegistryLite}.
-   */
-  public static void registerAllExtensionsLite(ExtensionRegistryLite registry) {
-    UnittestLite.registerAllExtensions(registry);
-  }
-
-  // ===================================================================
-  // Lite extensions
-
-  /**
-   * Set every field of {@code message} to the values expected by {@code assertAllExtensionsSet()}.
-   */
-  public static void setAllExtensions(TestAllExtensionsLite.Builder message) {
-    message.setExtension(optionalInt32ExtensionLite, 101);
-    message.setExtension(optionalInt64ExtensionLite, 102L);
-    message.setExtension(optionalUint32ExtensionLite, 103);
-    message.setExtension(optionalUint64ExtensionLite, 104L);
-    message.setExtension(optionalSint32ExtensionLite, 105);
-    message.setExtension(optionalSint64ExtensionLite, 106L);
-    message.setExtension(optionalFixed32ExtensionLite, 107);
-    message.setExtension(optionalFixed64ExtensionLite, 108L);
-    message.setExtension(optionalSfixed32ExtensionLite, 109);
-    message.setExtension(optionalSfixed64ExtensionLite, 110L);
-    message.setExtension(optionalFloatExtensionLite, 111F);
-    message.setExtension(optionalDoubleExtensionLite, 112D);
-    message.setExtension(optionalBoolExtensionLite, true);
-    message.setExtension(optionalStringExtensionLite, "115");
-    message.setExtension(optionalBytesExtensionLite, toBytes("116"));
-
-    message.setExtension(
-        optionalGroupExtensionLite, OptionalGroup_extension_lite.newBuilder().setA(117).build());
-    message.setExtension(
-        optionalNestedMessageExtensionLite,
-        TestAllTypesLite.NestedMessage.newBuilder().setBb(118).build());
-    message.setExtension(
-        optionalForeignMessageExtensionLite, ForeignMessageLite.newBuilder().setC(119).build());
-    message.setExtension(
-        optionalImportMessageExtensionLite, ImportMessageLite.newBuilder().setD(120).build());
-    message.setExtension(
-        optionalPublicImportMessageExtensionLite,
-        PublicImportMessageLite.newBuilder().setE(126).build());
-    message.setExtension(
-        optionalLazyMessageExtensionLite,
-        TestAllTypesLite.NestedMessage.newBuilder().setBb(127).build());
-
-    message.setExtension(optionalNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAZ);
-    message.setExtension(optionalForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
-    message.setExtension(optionalImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ);
-
-    message.setExtension(optionalStringPieceExtensionLite, "124");
-    message.setExtension(optionalCordExtensionLite, "125");
-
-    // -----------------------------------------------------------------
-
-    message.addExtension(repeatedInt32ExtensionLite, 201);
-    message.addExtension(repeatedInt64ExtensionLite, 202L);
-    message.addExtension(repeatedUint32ExtensionLite, 203);
-    message.addExtension(repeatedUint64ExtensionLite, 204L);
-    message.addExtension(repeatedSint32ExtensionLite, 205);
-    message.addExtension(repeatedSint64ExtensionLite, 206L);
-    message.addExtension(repeatedFixed32ExtensionLite, 207);
-    message.addExtension(repeatedFixed64ExtensionLite, 208L);
-    message.addExtension(repeatedSfixed32ExtensionLite, 209);
-    message.addExtension(repeatedSfixed64ExtensionLite, 210L);
-    message.addExtension(repeatedFloatExtensionLite, 211F);
-    message.addExtension(repeatedDoubleExtensionLite, 212D);
-    message.addExtension(repeatedBoolExtensionLite, true);
-    message.addExtension(repeatedStringExtensionLite, "215");
-    message.addExtension(repeatedBytesExtensionLite, toBytes("216"));
-
-    message.addExtension(
-        repeatedGroupExtensionLite, RepeatedGroup_extension_lite.newBuilder().setA(217).build());
-    message.addExtension(
-        repeatedNestedMessageExtensionLite,
-        TestAllTypesLite.NestedMessage.newBuilder().setBb(218).build());
-    message.addExtension(
-        repeatedForeignMessageExtensionLite, ForeignMessageLite.newBuilder().setC(219).build());
-    message.addExtension(
-        repeatedImportMessageExtensionLite, ImportMessageLite.newBuilder().setD(220).build());
-    message.addExtension(
-        repeatedLazyMessageExtensionLite,
-        TestAllTypesLite.NestedMessage.newBuilder().setBb(227).build());
-
-    message.addExtension(repeatedNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAR);
-    message.addExtension(repeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAR);
-    message.addExtension(repeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAR);
-
-    message.addExtension(repeatedStringPieceExtensionLite, "224");
-    message.addExtension(repeatedCordExtensionLite, "225");
-
-    // Add a second one of each field.
-    message.addExtension(repeatedInt32ExtensionLite, 301);
-    message.addExtension(repeatedInt64ExtensionLite, 302L);
-    message.addExtension(repeatedUint32ExtensionLite, 303);
-    message.addExtension(repeatedUint64ExtensionLite, 304L);
-    message.addExtension(repeatedSint32ExtensionLite, 305);
-    message.addExtension(repeatedSint64ExtensionLite, 306L);
-    message.addExtension(repeatedFixed32ExtensionLite, 307);
-    message.addExtension(repeatedFixed64ExtensionLite, 308L);
-    message.addExtension(repeatedSfixed32ExtensionLite, 309);
-    message.addExtension(repeatedSfixed64ExtensionLite, 310L);
-    message.addExtension(repeatedFloatExtensionLite, 311F);
-    message.addExtension(repeatedDoubleExtensionLite, 312D);
-    message.addExtension(repeatedBoolExtensionLite, false);
-    message.addExtension(repeatedStringExtensionLite, "315");
-    message.addExtension(repeatedBytesExtensionLite, toBytes("316"));
-
-    message.addExtension(
-        repeatedGroupExtensionLite, RepeatedGroup_extension_lite.newBuilder().setA(317).build());
-    message.addExtension(
-        repeatedNestedMessageExtensionLite,
-        TestAllTypesLite.NestedMessage.newBuilder().setBb(318).build());
-    message.addExtension(
-        repeatedForeignMessageExtensionLite, ForeignMessageLite.newBuilder().setC(319).build());
-    message.addExtension(
-        repeatedImportMessageExtensionLite, ImportMessageLite.newBuilder().setD(320).build());
-    message.addExtension(
-        repeatedLazyMessageExtensionLite,
-        TestAllTypesLite.NestedMessage.newBuilder().setBb(327).build());
-
-    message.addExtension(repeatedNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAZ);
-    message.addExtension(repeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
-    message.addExtension(repeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ);
-
-    message.addExtension(repeatedStringPieceExtensionLite, "324");
-    message.addExtension(repeatedCordExtensionLite, "325");
-
-    // -----------------------------------------------------------------
-
-    message.setExtension(defaultInt32ExtensionLite, 401);
-    message.setExtension(defaultInt64ExtensionLite, 402L);
-    message.setExtension(defaultUint32ExtensionLite, 403);
-    message.setExtension(defaultUint64ExtensionLite, 404L);
-    message.setExtension(defaultSint32ExtensionLite, 405);
-    message.setExtension(defaultSint64ExtensionLite, 406L);
-    message.setExtension(defaultFixed32ExtensionLite, 407);
-    message.setExtension(defaultFixed64ExtensionLite, 408L);
-    message.setExtension(defaultSfixed32ExtensionLite, 409);
-    message.setExtension(defaultSfixed64ExtensionLite, 410L);
-    message.setExtension(defaultFloatExtensionLite, 411F);
-    message.setExtension(defaultDoubleExtensionLite, 412D);
-    message.setExtension(defaultBoolExtensionLite, false);
-    message.setExtension(defaultStringExtensionLite, "415");
-    message.setExtension(defaultBytesExtensionLite, toBytes("416"));
-
-    message.setExtension(defaultNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.FOO);
-    message.setExtension(defaultForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_FOO);
-    message.setExtension(defaultImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_FOO);
-
-    message.setExtension(defaultStringPieceExtensionLite, "424");
-    message.setExtension(defaultCordExtensionLite, "425");
-
-    message.setExtension(oneofUint32ExtensionLite, 601);
-    message.setExtension(
-        oneofNestedMessageExtensionLite,
-        TestAllTypesLite.NestedMessage.newBuilder().setBb(602).build());
-    message.setExtension(oneofStringExtensionLite, "603");
-    message.setExtension(oneofBytesExtensionLite, toBytes("604"));
-  }
-
-  // -------------------------------------------------------------------
-
-  /**
-   * Modify the repeated extensions of {@code message} to contain the values expected by {@code
-   * assertRepeatedExtensionsModified()}.
-   */
-  public static void modifyRepeatedExtensions(TestAllExtensionsLite.Builder message) {
-    message.setExtension(repeatedInt32ExtensionLite, 1, 501);
-    message.setExtension(repeatedInt64ExtensionLite, 1, 502L);
-    message.setExtension(repeatedUint32ExtensionLite, 1, 503);
-    message.setExtension(repeatedUint64ExtensionLite, 1, 504L);
-    message.setExtension(repeatedSint32ExtensionLite, 1, 505);
-    message.setExtension(repeatedSint64ExtensionLite, 1, 506L);
-    message.setExtension(repeatedFixed32ExtensionLite, 1, 507);
-    message.setExtension(repeatedFixed64ExtensionLite, 1, 508L);
-    message.setExtension(repeatedSfixed32ExtensionLite, 1, 509);
-    message.setExtension(repeatedSfixed64ExtensionLite, 1, 510L);
-    message.setExtension(repeatedFloatExtensionLite, 1, 511F);
-    message.setExtension(repeatedDoubleExtensionLite, 1, 512D);
-    message.setExtension(repeatedBoolExtensionLite, 1, true);
-    message.setExtension(repeatedStringExtensionLite, 1, "515");
-    message.setExtension(repeatedBytesExtensionLite, 1, toBytes("516"));
-
-    message.setExtension(
-        repeatedGroupExtensionLite, 1, RepeatedGroup_extension_lite.newBuilder().setA(517).build());
-    message.setExtension(
-        repeatedNestedMessageExtensionLite,
-        1,
-        TestAllTypesLite.NestedMessage.newBuilder().setBb(518).build());
-    message.setExtension(
-        repeatedForeignMessageExtensionLite, 1, ForeignMessageLite.newBuilder().setC(519).build());
-    message.setExtension(
-        repeatedImportMessageExtensionLite, 1, ImportMessageLite.newBuilder().setD(520).build());
-    message.setExtension(
-        repeatedLazyMessageExtensionLite,
-        1,
-        TestAllTypesLite.NestedMessage.newBuilder().setBb(527).build());
-
-    message.setExtension(repeatedNestedEnumExtensionLite, 1, TestAllTypesLite.NestedEnum.FOO);
-    message.setExtension(repeatedForeignEnumExtensionLite, 1, ForeignEnumLite.FOREIGN_LITE_FOO);
-    message.setExtension(repeatedImportEnumExtensionLite, 1, ImportEnumLite.IMPORT_LITE_FOO);
-
-    message.setExtension(repeatedStringPieceExtensionLite, 1, "524");
-    message.setExtension(repeatedCordExtensionLite, 1, "525");
-  }
-
-  public static void setPackedExtensions(TestPackedExtensionsLite.Builder message) {
-    message.addExtension(packedInt32ExtensionLite, 601);
-    message.addExtension(packedInt64ExtensionLite, 602L);
-    message.addExtension(packedUint32ExtensionLite, 603);
-    message.addExtension(packedUint64ExtensionLite, 604L);
-    message.addExtension(packedSint32ExtensionLite, 605);
-    message.addExtension(packedSint64ExtensionLite, 606L);
-    message.addExtension(packedFixed32ExtensionLite, 607);
-    message.addExtension(packedFixed64ExtensionLite, 608L);
-    message.addExtension(packedSfixed32ExtensionLite, 609);
-    message.addExtension(packedSfixed64ExtensionLite, 610L);
-    message.addExtension(packedFloatExtensionLite, 611F);
-    message.addExtension(packedDoubleExtensionLite, 612D);
-    message.addExtension(packedBoolExtensionLite, true);
-    message.addExtension(packedEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAR);
-    // Add a second one of each field.
-    message.addExtension(packedInt32ExtensionLite, 701);
-    message.addExtension(packedInt64ExtensionLite, 702L);
-    message.addExtension(packedUint32ExtensionLite, 703);
-    message.addExtension(packedUint64ExtensionLite, 704L);
-    message.addExtension(packedSint32ExtensionLite, 705);
-    message.addExtension(packedSint64ExtensionLite, 706L);
-    message.addExtension(packedFixed32ExtensionLite, 707);
-    message.addExtension(packedFixed64ExtensionLite, 708L);
-    message.addExtension(packedSfixed32ExtensionLite, 709);
-    message.addExtension(packedSfixed64ExtensionLite, 710L);
-    message.addExtension(packedFloatExtensionLite, 711F);
-    message.addExtension(packedDoubleExtensionLite, 712D);
-    message.addExtension(packedBoolExtensionLite, false);
-    message.addExtension(packedEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
-  }
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/UnittestImportLite.java b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/UnittestImportLite.java
deleted file mode 100644
index 0811896..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/UnittestImportLite.java
+++ /dev/null
@@ -1,375 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/unittest_import_lite.proto
-
-package com.google.protobuf;
-
-public final class UnittestImportLite {
-  private UnittestImportLite() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-  /**
-   * Protobuf enum {@code protobuf_unittest_import.ImportEnumLite}
-   */
-  public enum ImportEnumLite
-      implements com.google.protobuf.Internal.EnumLite {
-    /**
-     * <code>IMPORT_LITE_FOO = 7;</code>
-     */
-    IMPORT_LITE_FOO(7),
-    /**
-     * <code>IMPORT_LITE_BAR = 8;</code>
-     */
-    IMPORT_LITE_BAR(8),
-    /**
-     * <code>IMPORT_LITE_BAZ = 9;</code>
-     */
-    IMPORT_LITE_BAZ(9),
-    ;
-
-    /**
-     * <code>IMPORT_LITE_FOO = 7;</code>
-     */
-    public static final int IMPORT_LITE_FOO_VALUE = 7;
-    /**
-     * <code>IMPORT_LITE_BAR = 8;</code>
-     */
-    public static final int IMPORT_LITE_BAR_VALUE = 8;
-    /**
-     * <code>IMPORT_LITE_BAZ = 9;</code>
-     */
-    public static final int IMPORT_LITE_BAZ_VALUE = 9;
-
-
-    @java.lang.Override
-    public final int getNumber() {
-      return value;
-    }
-
-    /**
-     * @param value The number of the enum to look for.
-     * @return The enum associated with the given number.
-     * @deprecated Use {@link #forNumber(int)} instead.
-     */
-    @java.lang.Deprecated
-    public static ImportEnumLite valueOf(int value) {
-      return forNumber(value);
-    }
-
-    public static ImportEnumLite forNumber(int value) {
-      switch (value) {
-        case 7: return IMPORT_LITE_FOO;
-        case 8: return IMPORT_LITE_BAR;
-        case 9: return IMPORT_LITE_BAZ;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<ImportEnumLite>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        ImportEnumLite> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<ImportEnumLite>() {
-            @java.lang.Override
-            public ImportEnumLite findValueByNumber(int number) {
-              return ImportEnumLite.forNumber(number);
-            }
-          };
-
-    public static com.google.protobuf.Internal.EnumVerifier 
-        internalGetVerifier() {
-      return ImportEnumLiteVerifier.INSTANCE;
-    }
-
-    private static final class ImportEnumLiteVerifier implements 
-         com.google.protobuf.Internal.EnumVerifier { 
-            static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new ImportEnumLiteVerifier();
-            @java.lang.Override
-            public boolean isInRange(int number) {
-              return ImportEnumLite.forNumber(number) != null;
-            }
-          };
-
-    private final int value;
-
-    private ImportEnumLite(int value) {
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:protobuf_unittest_import.ImportEnumLite)
-  }
-
-  public interface ImportMessageLiteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest_import.ImportMessageLite)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional int32 d = 1;</code>
-     * @return Whether the d field is set.
-     */
-    boolean hasD();
-    /**
-     * <code>optional int32 d = 1;</code>
-     * @return The d.
-     */
-    int getD();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest_import.ImportMessageLite}
-   */
-  public  static final class ImportMessageLite extends
-      com.google.protobuf.GeneratedMessageLite<
-          ImportMessageLite, ImportMessageLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest_import.ImportMessageLite)
-      ImportMessageLiteOrBuilder {
-    private ImportMessageLite() {
-    }
-    private int bitField0_;
-    public static final int D_FIELD_NUMBER = 1;
-    private int d_;
-    /**
-     * <code>optional int32 d = 1;</code>
-     * @return Whether the d field is set.
-     */
-    @java.lang.Override
-    public boolean hasD() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 d = 1;</code>
-     * @return The d.
-     */
-    @java.lang.Override
-    public int getD() {
-      return d_;
-    }
-    /**
-     * <code>optional int32 d = 1;</code>
-     * @param value The d to set.
-     */
-    private void setD(int value) {
-      bitField0_ |= 0x00000001;
-      d_ = value;
-    }
-    /**
-     * <code>optional int32 d = 1;</code>
-     */
-    private void clearD() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      d_ = 0;
-    }
-
-    public static com.google.protobuf.UnittestImportLite.ImportMessageLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestImportLite.ImportMessageLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestImportLite.ImportMessageLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestImportLite.ImportMessageLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestImportLite.ImportMessageLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestImportLite.ImportMessageLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestImportLite.ImportMessageLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestImportLite.ImportMessageLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestImportLite.ImportMessageLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestImportLite.ImportMessageLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestImportLite.ImportMessageLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestImportLite.ImportMessageLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestImportLite.ImportMessageLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest_import.ImportMessageLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.UnittestImportLite.ImportMessageLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest_import.ImportMessageLite)
-        com.google.protobuf.UnittestImportLite.ImportMessageLiteOrBuilder {
-      // Construct using com.google.protobuf.UnittestImportLite.ImportMessageLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int32 d = 1;</code>
-       * @return Whether the d field is set.
-       */
-      @java.lang.Override
-      public boolean hasD() {
-        return instance.hasD();
-      }
-      /**
-       * <code>optional int32 d = 1;</code>
-       * @return The d.
-       */
-      @java.lang.Override
-      public int getD() {
-        return instance.getD();
-      }
-      /**
-       * <code>optional int32 d = 1;</code>
-       * @param value The d to set.
-       * @return This builder for chaining.
-       */
-      public Builder setD(int value) {
-        copyOnWrite();
-        instance.setD(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 d = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearD() {
-        copyOnWrite();
-        instance.clearD();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest_import.ImportMessageLite)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestImportLite.ImportMessageLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "d_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1004\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestImportLite.ImportMessageLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestImportLite.ImportMessageLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestImportLite.ImportMessageLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest_import.ImportMessageLite)
-    private static final com.google.protobuf.UnittestImportLite.ImportMessageLite DEFAULT_INSTANCE;
-    static {
-      ImportMessageLite defaultInstance = new ImportMessageLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        ImportMessageLite.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestImportLite.ImportMessageLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<ImportMessageLite> PARSER;
-
-    public static com.google.protobuf.Parser<ImportMessageLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/UnittestImportPublicLite.java b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/UnittestImportPublicLite.java
deleted file mode 100644
index 1b1f745..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/UnittestImportPublicLite.java
+++ /dev/null
@@ -1,282 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/unittest_import_public_lite.proto
-
-package com.google.protobuf;
-
-public final class UnittestImportPublicLite {
-  private UnittestImportPublicLite() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-  public interface PublicImportMessageLiteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest_import.PublicImportMessageLite)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional int32 e = 1;</code>
-     * @return Whether the e field is set.
-     */
-    boolean hasE();
-    /**
-     * <code>optional int32 e = 1;</code>
-     * @return The e.
-     */
-    int getE();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest_import.PublicImportMessageLite}
-   */
-  public  static final class PublicImportMessageLite extends
-      com.google.protobuf.GeneratedMessageLite<
-          PublicImportMessageLite, PublicImportMessageLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest_import.PublicImportMessageLite)
-      PublicImportMessageLiteOrBuilder {
-    private PublicImportMessageLite() {
-    }
-    private int bitField0_;
-    public static final int E_FIELD_NUMBER = 1;
-    private int e_;
-    /**
-     * <code>optional int32 e = 1;</code>
-     * @return Whether the e field is set.
-     */
-    @java.lang.Override
-    public boolean hasE() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 e = 1;</code>
-     * @return The e.
-     */
-    @java.lang.Override
-    public int getE() {
-      return e_;
-    }
-    /**
-     * <code>optional int32 e = 1;</code>
-     * @param value The e to set.
-     */
-    private void setE(int value) {
-      bitField0_ |= 0x00000001;
-      e_ = value;
-    }
-    /**
-     * <code>optional int32 e = 1;</code>
-     */
-    private void clearE() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      e_ = 0;
-    }
-
-    public static com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest_import.PublicImportMessageLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest_import.PublicImportMessageLite)
-        com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLiteOrBuilder {
-      // Construct using com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int32 e = 1;</code>
-       * @return Whether the e field is set.
-       */
-      @java.lang.Override
-      public boolean hasE() {
-        return instance.hasE();
-      }
-      /**
-       * <code>optional int32 e = 1;</code>
-       * @return The e.
-       */
-      @java.lang.Override
-      public int getE() {
-        return instance.getE();
-      }
-      /**
-       * <code>optional int32 e = 1;</code>
-       * @param value The e to set.
-       * @return This builder for chaining.
-       */
-      public Builder setE(int value) {
-        copyOnWrite();
-        instance.setE(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 e = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearE() {
-        copyOnWrite();
-        instance.clearE();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest_import.PublicImportMessageLite)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "e_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1004\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest_import.PublicImportMessageLite)
-    private static final com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite DEFAULT_INSTANCE;
-    static {
-      PublicImportMessageLite defaultInstance = new PublicImportMessageLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        PublicImportMessageLite.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<PublicImportMessageLite> PARSER;
-
-    public static com.google.protobuf.Parser<PublicImportMessageLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/UnittestLite.java b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/UnittestLite.java
deleted file mode 100644
index 48f4b24..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/UnittestLite.java
+++ /dev/null
@@ -1,27627 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-public final class UnittestLite {
-  private UnittestLite() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-    registry.add(com.google.protobuf.UnittestLite.optionalInt32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalInt64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalUint32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalUint64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalSint32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalSint64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalFixed32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalFixed64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalSfixed32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalSfixed64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalFloatExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalDoubleExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalBoolExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalStringExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalBytesExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalGroupExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalNestedMessageExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalForeignMessageExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalImportMessageExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalNestedEnumExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalForeignEnumExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalImportEnumExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalStringPieceExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalCordExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalPublicImportMessageExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.optionalLazyMessageExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedInt32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedInt64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedUint32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedUint64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedSint32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedSint64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedFixed32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedFixed64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedSfixed32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedSfixed64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedFloatExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedDoubleExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedBoolExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedStringExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedBytesExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedGroupExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedNestedMessageExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedForeignMessageExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedImportMessageExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedNestedEnumExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedForeignEnumExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedImportEnumExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedStringPieceExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedCordExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.repeatedLazyMessageExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultInt32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultInt64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultUint32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultUint64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultSint32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultSint64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultFixed32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultFixed64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultSfixed32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultSfixed64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultFloatExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultDoubleExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultBoolExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultStringExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultBytesExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultNestedEnumExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultForeignEnumExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultImportEnumExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultStringPieceExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.defaultCordExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.oneofUint32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.oneofNestedMessageExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.oneofStringExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.oneofBytesExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.packedInt32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.packedInt64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.packedUint32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.packedUint64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.packedSint32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.packedSint64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.packedFixed32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.packedFixed64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.packedSfixed32ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.packedSfixed64ExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.packedFloatExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.packedDoubleExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.packedBoolExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.packedEnumExtensionLite);
-    registry.add(com.google.protobuf.UnittestLite.testAllTypesLite);
-    registry.add(com.google.protobuf.UnittestLite.TestNestedExtensionLite.nestedExtension);
-    registry.add(com.google.protobuf.UnittestLite.TestParsingMergeLite.optionalExt);
-    registry.add(com.google.protobuf.UnittestLite.TestParsingMergeLite.repeatedExt);
-  }
-  /**
-   * Protobuf enum {@code protobuf_unittest.ForeignEnumLite}
-   */
-  public enum ForeignEnumLite
-      implements com.google.protobuf.Internal.EnumLite {
-    /**
-     * <code>FOREIGN_LITE_FOO = 4;</code>
-     */
-    FOREIGN_LITE_FOO(4),
-    /**
-     * <code>FOREIGN_LITE_BAZ = 6;</code>
-     */
-    FOREIGN_LITE_BAZ(6),
-    /**
-     * <code>FOREIGN_LITE_BAR = 5;</code>
-     */
-    FOREIGN_LITE_BAR(5),
-    ;
-
-    /**
-     * <code>FOREIGN_LITE_FOO = 4;</code>
-     */
-    public static final int FOREIGN_LITE_FOO_VALUE = 4;
-    /**
-     * <code>FOREIGN_LITE_BAZ = 6;</code>
-     */
-    public static final int FOREIGN_LITE_BAZ_VALUE = 6;
-    /**
-     * <code>FOREIGN_LITE_BAR = 5;</code>
-     */
-    public static final int FOREIGN_LITE_BAR_VALUE = 5;
-
-
-    @java.lang.Override
-    public final int getNumber() {
-      return value;
-    }
-
-    /**
-     * @param value The number of the enum to look for.
-     * @return The enum associated with the given number.
-     * @deprecated Use {@link #forNumber(int)} instead.
-     */
-    @java.lang.Deprecated
-    public static ForeignEnumLite valueOf(int value) {
-      return forNumber(value);
-    }
-
-    public static ForeignEnumLite forNumber(int value) {
-      switch (value) {
-        case 4: return FOREIGN_LITE_FOO;
-        case 6: return FOREIGN_LITE_BAZ;
-        case 5: return FOREIGN_LITE_BAR;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<ForeignEnumLite>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        ForeignEnumLite> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<ForeignEnumLite>() {
-            @java.lang.Override
-            public ForeignEnumLite findValueByNumber(int number) {
-              return ForeignEnumLite.forNumber(number);
-            }
-          };
-
-    public static com.google.protobuf.Internal.EnumVerifier 
-        internalGetVerifier() {
-      return ForeignEnumLiteVerifier.INSTANCE;
-    }
-
-    private static final class ForeignEnumLiteVerifier implements 
-         com.google.protobuf.Internal.EnumVerifier { 
-            static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new ForeignEnumLiteVerifier();
-            @java.lang.Override
-            public boolean isInRange(int number) {
-              return ForeignEnumLite.forNumber(number) != null;
-            }
-          };
-
-    private final int value;
-
-    private ForeignEnumLite(int value) {
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:protobuf_unittest.ForeignEnumLite)
-  }
-
-  /**
-   * Protobuf enum {@code protobuf_unittest.V1EnumLite}
-   */
-  public enum V1EnumLite
-      implements com.google.protobuf.Internal.EnumLite {
-    /**
-     * <code>V1_FIRST = 1;</code>
-     */
-    V1_FIRST(1),
-    ;
-
-    /**
-     * <code>V1_FIRST = 1;</code>
-     */
-    public static final int V1_FIRST_VALUE = 1;
-
-
-    @java.lang.Override
-    public final int getNumber() {
-      return value;
-    }
-
-    /**
-     * @param value The number of the enum to look for.
-     * @return The enum associated with the given number.
-     * @deprecated Use {@link #forNumber(int)} instead.
-     */
-    @java.lang.Deprecated
-    public static V1EnumLite valueOf(int value) {
-      return forNumber(value);
-    }
-
-    public static V1EnumLite forNumber(int value) {
-      switch (value) {
-        case 1: return V1_FIRST;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<V1EnumLite>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        V1EnumLite> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<V1EnumLite>() {
-            @java.lang.Override
-            public V1EnumLite findValueByNumber(int number) {
-              return V1EnumLite.forNumber(number);
-            }
-          };
-
-    public static com.google.protobuf.Internal.EnumVerifier 
-        internalGetVerifier() {
-      return V1EnumLiteVerifier.INSTANCE;
-    }
-
-    private static final class V1EnumLiteVerifier implements 
-         com.google.protobuf.Internal.EnumVerifier { 
-            static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new V1EnumLiteVerifier();
-            @java.lang.Override
-            public boolean isInRange(int number) {
-              return V1EnumLite.forNumber(number) != null;
-            }
-          };
-
-    private final int value;
-
-    private V1EnumLite(int value) {
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:protobuf_unittest.V1EnumLite)
-  }
-
-  /**
-   * Protobuf enum {@code protobuf_unittest.V2EnumLite}
-   */
-  public enum V2EnumLite
-      implements com.google.protobuf.Internal.EnumLite {
-    /**
-     * <code>V2_FIRST = 1;</code>
-     */
-    V2_FIRST(1),
-    /**
-     * <code>V2_SECOND = 2;</code>
-     */
-    V2_SECOND(2),
-    ;
-
-    /**
-     * <code>V2_FIRST = 1;</code>
-     */
-    public static final int V2_FIRST_VALUE = 1;
-    /**
-     * <code>V2_SECOND = 2;</code>
-     */
-    public static final int V2_SECOND_VALUE = 2;
-
-
-    @java.lang.Override
-    public final int getNumber() {
-      return value;
-    }
-
-    /**
-     * @param value The number of the enum to look for.
-     * @return The enum associated with the given number.
-     * @deprecated Use {@link #forNumber(int)} instead.
-     */
-    @java.lang.Deprecated
-    public static V2EnumLite valueOf(int value) {
-      return forNumber(value);
-    }
-
-    public static V2EnumLite forNumber(int value) {
-      switch (value) {
-        case 1: return V2_FIRST;
-        case 2: return V2_SECOND;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<V2EnumLite>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        V2EnumLite> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<V2EnumLite>() {
-            @java.lang.Override
-            public V2EnumLite findValueByNumber(int number) {
-              return V2EnumLite.forNumber(number);
-            }
-          };
-
-    public static com.google.protobuf.Internal.EnumVerifier 
-        internalGetVerifier() {
-      return V2EnumLiteVerifier.INSTANCE;
-    }
-
-    private static final class V2EnumLiteVerifier implements 
-         com.google.protobuf.Internal.EnumVerifier { 
-            static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new V2EnumLiteVerifier();
-            @java.lang.Override
-            public boolean isInRange(int number) {
-              return V2EnumLite.forNumber(number) != null;
-            }
-          };
-
-    private final int value;
-
-    private V2EnumLite(int value) {
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:protobuf_unittest.V2EnumLite)
-  }
-
-  public interface TestAllTypesLiteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestAllTypesLite)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>optional int32 optional_int32 = 1;</code>
-     * @return Whether the optionalInt32 field is set.
-     */
-    boolean hasOptionalInt32();
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>optional int32 optional_int32 = 1;</code>
-     * @return The optionalInt32.
-     */
-    int getOptionalInt32();
-
-    /**
-     * <code>optional int64 optional_int64 = 2;</code>
-     * @return Whether the optionalInt64 field is set.
-     */
-    boolean hasOptionalInt64();
-    /**
-     * <code>optional int64 optional_int64 = 2;</code>
-     * @return The optionalInt64.
-     */
-    long getOptionalInt64();
-
-    /**
-     * <code>optional uint32 optional_uint32 = 3;</code>
-     * @return Whether the optionalUint32 field is set.
-     */
-    boolean hasOptionalUint32();
-    /**
-     * <code>optional uint32 optional_uint32 = 3;</code>
-     * @return The optionalUint32.
-     */
-    int getOptionalUint32();
-
-    /**
-     * <code>optional uint64 optional_uint64 = 4;</code>
-     * @return Whether the optionalUint64 field is set.
-     */
-    boolean hasOptionalUint64();
-    /**
-     * <code>optional uint64 optional_uint64 = 4;</code>
-     * @return The optionalUint64.
-     */
-    long getOptionalUint64();
-
-    /**
-     * <code>optional sint32 optional_sint32 = 5;</code>
-     * @return Whether the optionalSint32 field is set.
-     */
-    boolean hasOptionalSint32();
-    /**
-     * <code>optional sint32 optional_sint32 = 5;</code>
-     * @return The optionalSint32.
-     */
-    int getOptionalSint32();
-
-    /**
-     * <code>optional sint64 optional_sint64 = 6;</code>
-     * @return Whether the optionalSint64 field is set.
-     */
-    boolean hasOptionalSint64();
-    /**
-     * <code>optional sint64 optional_sint64 = 6;</code>
-     * @return The optionalSint64.
-     */
-    long getOptionalSint64();
-
-    /**
-     * <code>optional fixed32 optional_fixed32 = 7;</code>
-     * @return Whether the optionalFixed32 field is set.
-     */
-    boolean hasOptionalFixed32();
-    /**
-     * <code>optional fixed32 optional_fixed32 = 7;</code>
-     * @return The optionalFixed32.
-     */
-    int getOptionalFixed32();
-
-    /**
-     * <code>optional fixed64 optional_fixed64 = 8;</code>
-     * @return Whether the optionalFixed64 field is set.
-     */
-    boolean hasOptionalFixed64();
-    /**
-     * <code>optional fixed64 optional_fixed64 = 8;</code>
-     * @return The optionalFixed64.
-     */
-    long getOptionalFixed64();
-
-    /**
-     * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-     * @return Whether the optionalSfixed32 field is set.
-     */
-    boolean hasOptionalSfixed32();
-    /**
-     * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-     * @return The optionalSfixed32.
-     */
-    int getOptionalSfixed32();
-
-    /**
-     * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-     * @return Whether the optionalSfixed64 field is set.
-     */
-    boolean hasOptionalSfixed64();
-    /**
-     * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-     * @return The optionalSfixed64.
-     */
-    long getOptionalSfixed64();
-
-    /**
-     * <code>optional float optional_float = 11;</code>
-     * @return Whether the optionalFloat field is set.
-     */
-    boolean hasOptionalFloat();
-    /**
-     * <code>optional float optional_float = 11;</code>
-     * @return The optionalFloat.
-     */
-    float getOptionalFloat();
-
-    /**
-     * <code>optional double optional_double = 12;</code>
-     * @return Whether the optionalDouble field is set.
-     */
-    boolean hasOptionalDouble();
-    /**
-     * <code>optional double optional_double = 12;</code>
-     * @return The optionalDouble.
-     */
-    double getOptionalDouble();
-
-    /**
-     * <code>optional bool optional_bool = 13;</code>
-     * @return Whether the optionalBool field is set.
-     */
-    boolean hasOptionalBool();
-    /**
-     * <code>optional bool optional_bool = 13;</code>
-     * @return The optionalBool.
-     */
-    boolean getOptionalBool();
-
-    /**
-     * <code>optional string optional_string = 14;</code>
-     * @return Whether the optionalString field is set.
-     */
-    boolean hasOptionalString();
-    /**
-     * <code>optional string optional_string = 14;</code>
-     * @return The optionalString.
-     */
-    java.lang.String getOptionalString();
-    /**
-     * <code>optional string optional_string = 14;</code>
-     * @return The bytes for optionalString.
-     */
-    com.google.protobuf.ByteString
-        getOptionalStringBytes();
-
-    /**
-     * <code>optional bytes optional_bytes = 15;</code>
-     * @return Whether the optionalBytes field is set.
-     */
-    boolean hasOptionalBytes();
-    /**
-     * <code>optional bytes optional_bytes = 15;</code>
-     * @return The optionalBytes.
-     */
-    com.google.protobuf.ByteString getOptionalBytes();
-
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     * @return Whether the optionalgroup field is set.
-     */
-    boolean hasOptionalGroup();
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     * @return The optionalgroup.
-     */
-    com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup getOptionalGroup();
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_nested_message = 18;</code>
-     * @return Whether the optionalNestedMessage field is set.
-     */
-    boolean hasOptionalNestedMessage();
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_nested_message = 18;</code>
-     * @return The optionalNestedMessage.
-     */
-    com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage getOptionalNestedMessage();
-
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_foreign_message = 19;</code>
-     * @return Whether the optionalForeignMessage field is set.
-     */
-    boolean hasOptionalForeignMessage();
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_foreign_message = 19;</code>
-     * @return The optionalForeignMessage.
-     */
-    com.google.protobuf.UnittestLite.ForeignMessageLite getOptionalForeignMessage();
-
-    /**
-     * <code>optional .protobuf_unittest_import.ImportMessageLite optional_import_message = 20;</code>
-     * @return Whether the optionalImportMessage field is set.
-     */
-    boolean hasOptionalImportMessage();
-    /**
-     * <code>optional .protobuf_unittest_import.ImportMessageLite optional_import_message = 20;</code>
-     * @return The optionalImportMessage.
-     */
-    com.google.protobuf.UnittestImportLite.ImportMessageLite getOptionalImportMessage();
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum optional_nested_enum = 21;</code>
-     * @return Whether the optionalNestedEnum field is set.
-     */
-    boolean hasOptionalNestedEnum();
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum optional_nested_enum = 21;</code>
-     * @return The optionalNestedEnum.
-     */
-    com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum getOptionalNestedEnum();
-
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite optional_foreign_enum = 22;</code>
-     * @return Whether the optionalForeignEnum field is set.
-     */
-    boolean hasOptionalForeignEnum();
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite optional_foreign_enum = 22;</code>
-     * @return The optionalForeignEnum.
-     */
-    com.google.protobuf.UnittestLite.ForeignEnumLite getOptionalForeignEnum();
-
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnumLite optional_import_enum = 23;</code>
-     * @return Whether the optionalImportEnum field is set.
-     */
-    boolean hasOptionalImportEnum();
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnumLite optional_import_enum = 23;</code>
-     * @return The optionalImportEnum.
-     */
-    com.google.protobuf.UnittestImportLite.ImportEnumLite getOptionalImportEnum();
-
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @return Whether the optionalStringPiece field is set.
-     */
-    boolean hasOptionalStringPiece();
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @return The optionalStringPiece.
-     */
-    java.lang.String getOptionalStringPiece();
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @return The bytes for optionalStringPiece.
-     */
-    com.google.protobuf.ByteString
-        getOptionalStringPieceBytes();
-
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     * @return Whether the optionalCord field is set.
-     */
-    boolean hasOptionalCord();
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     * @return The optionalCord.
-     */
-    java.lang.String getOptionalCord();
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     * @return The bytes for optionalCord.
-     */
-    com.google.protobuf.ByteString
-        getOptionalCordBytes();
-
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>optional .protobuf_unittest_import.PublicImportMessageLite optional_public_import_message = 26;</code>
-     * @return Whether the optionalPublicImportMessage field is set.
-     */
-    boolean hasOptionalPublicImportMessage();
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>optional .protobuf_unittest_import.PublicImportMessageLite optional_public_import_message = 26;</code>
-     * @return The optionalPublicImportMessage.
-     */
-    com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite getOptionalPublicImportMessage();
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     * @return Whether the optionalLazyMessage field is set.
-     */
-    boolean hasOptionalLazyMessage();
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     * @return The optionalLazyMessage.
-     */
-    com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage getOptionalLazyMessage();
-
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @return A list containing the repeatedInt32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedInt32List();
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @return The count of repeatedInt32.
-     */
-    int getRepeatedInt32Count();
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt32 at the given index.
-     */
-    int getRepeatedInt32(int index);
-
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @return A list containing the repeatedInt64.
-     */
-    java.util.List<java.lang.Long> getRepeatedInt64List();
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @return The count of repeatedInt64.
-     */
-    int getRepeatedInt64Count();
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt64 at the given index.
-     */
-    long getRepeatedInt64(int index);
-
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @return A list containing the repeatedUint32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedUint32List();
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @return The count of repeatedUint32.
-     */
-    int getRepeatedUint32Count();
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedUint32 at the given index.
-     */
-    int getRepeatedUint32(int index);
-
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @return A list containing the repeatedUint64.
-     */
-    java.util.List<java.lang.Long> getRepeatedUint64List();
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @return The count of repeatedUint64.
-     */
-    int getRepeatedUint64Count();
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedUint64 at the given index.
-     */
-    long getRepeatedUint64(int index);
-
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @return A list containing the repeatedSint32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedSint32List();
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @return The count of repeatedSint32.
-     */
-    int getRepeatedSint32Count();
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSint32 at the given index.
-     */
-    int getRepeatedSint32(int index);
-
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @return A list containing the repeatedSint64.
-     */
-    java.util.List<java.lang.Long> getRepeatedSint64List();
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @return The count of repeatedSint64.
-     */
-    int getRepeatedSint64Count();
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSint64 at the given index.
-     */
-    long getRepeatedSint64(int index);
-
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @return A list containing the repeatedFixed32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedFixed32List();
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @return The count of repeatedFixed32.
-     */
-    int getRepeatedFixed32Count();
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed32 at the given index.
-     */
-    int getRepeatedFixed32(int index);
-
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @return A list containing the repeatedFixed64.
-     */
-    java.util.List<java.lang.Long> getRepeatedFixed64List();
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @return The count of repeatedFixed64.
-     */
-    int getRepeatedFixed64Count();
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed64 at the given index.
-     */
-    long getRepeatedFixed64(int index);
-
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @return A list containing the repeatedSfixed32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedSfixed32List();
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @return The count of repeatedSfixed32.
-     */
-    int getRepeatedSfixed32Count();
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSfixed32 at the given index.
-     */
-    int getRepeatedSfixed32(int index);
-
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @return A list containing the repeatedSfixed64.
-     */
-    java.util.List<java.lang.Long> getRepeatedSfixed64List();
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @return The count of repeatedSfixed64.
-     */
-    int getRepeatedSfixed64Count();
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSfixed64 at the given index.
-     */
-    long getRepeatedSfixed64(int index);
-
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @return A list containing the repeatedFloat.
-     */
-    java.util.List<java.lang.Float> getRepeatedFloatList();
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @return The count of repeatedFloat.
-     */
-    int getRepeatedFloatCount();
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFloat at the given index.
-     */
-    float getRepeatedFloat(int index);
-
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @return A list containing the repeatedDouble.
-     */
-    java.util.List<java.lang.Double> getRepeatedDoubleList();
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @return The count of repeatedDouble.
-     */
-    int getRepeatedDoubleCount();
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedDouble at the given index.
-     */
-    double getRepeatedDouble(int index);
-
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @return A list containing the repeatedBool.
-     */
-    java.util.List<java.lang.Boolean> getRepeatedBoolList();
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @return The count of repeatedBool.
-     */
-    int getRepeatedBoolCount();
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedBool at the given index.
-     */
-    boolean getRepeatedBool(int index);
-
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @return A list containing the repeatedString.
-     */
-    java.util.List<java.lang.String>
-        getRepeatedStringList();
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @return The count of repeatedString.
-     */
-    int getRepeatedStringCount();
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedString at the given index.
-     */
-    java.lang.String getRepeatedString(int index);
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedString at the given index.
-     */
-    com.google.protobuf.ByteString
-        getRepeatedStringBytes(int index);
-
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @return A list containing the repeatedBytes.
-     */
-    java.util.List<com.google.protobuf.ByteString> getRepeatedBytesList();
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @return The count of repeatedBytes.
-     */
-    int getRepeatedBytesCount();
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedBytes at the given index.
-     */
-    com.google.protobuf.ByteString getRepeatedBytes(int index);
-
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup> 
-        getRepeatedGroupList();
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup getRepeatedGroup(int index);
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    int getRepeatedGroupCount();
-
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     */
-    java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage> 
-        getRepeatedNestedMessageList();
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     */
-    com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage getRepeatedNestedMessage(int index);
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     */
-    int getRepeatedNestedMessageCount();
-
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     */
-    java.util.List<com.google.protobuf.UnittestLite.ForeignMessageLite> 
-        getRepeatedForeignMessageList();
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     */
-    com.google.protobuf.UnittestLite.ForeignMessageLite getRepeatedForeignMessage(int index);
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     */
-    int getRepeatedForeignMessageCount();
-
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     */
-    java.util.List<com.google.protobuf.UnittestImportLite.ImportMessageLite> 
-        getRepeatedImportMessageList();
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     */
-    com.google.protobuf.UnittestImportLite.ImportMessageLite getRepeatedImportMessage(int index);
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     */
-    int getRepeatedImportMessageCount();
-
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-     * @return A list containing the repeatedNestedEnum.
-     */
-    java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum> getRepeatedNestedEnumList();
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-     * @return The count of repeatedNestedEnum.
-     */
-    int getRepeatedNestedEnumCount();
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedNestedEnum at the given index.
-     */
-    com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum getRepeatedNestedEnum(int index);
-
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-     * @return A list containing the repeatedForeignEnum.
-     */
-    java.util.List<com.google.protobuf.UnittestLite.ForeignEnumLite> getRepeatedForeignEnumList();
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-     * @return The count of repeatedForeignEnum.
-     */
-    int getRepeatedForeignEnumCount();
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedForeignEnum at the given index.
-     */
-    com.google.protobuf.UnittestLite.ForeignEnumLite getRepeatedForeignEnum(int index);
-
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-     * @return A list containing the repeatedImportEnum.
-     */
-    java.util.List<com.google.protobuf.UnittestImportLite.ImportEnumLite> getRepeatedImportEnumList();
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-     * @return The count of repeatedImportEnum.
-     */
-    int getRepeatedImportEnumCount();
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedImportEnum at the given index.
-     */
-    com.google.protobuf.UnittestImportLite.ImportEnumLite getRepeatedImportEnum(int index);
-
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @return A list containing the repeatedStringPiece.
-     */
-    java.util.List<java.lang.String>
-        getRepeatedStringPieceList();
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @return The count of repeatedStringPiece.
-     */
-    int getRepeatedStringPieceCount();
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedStringPiece at the given index.
-     */
-    java.lang.String getRepeatedStringPiece(int index);
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedStringPiece at the given index.
-     */
-    com.google.protobuf.ByteString
-        getRepeatedStringPieceBytes(int index);
-
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @return A list containing the repeatedCord.
-     */
-    java.util.List<java.lang.String>
-        getRepeatedCordList();
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @return The count of repeatedCord.
-     */
-    int getRepeatedCordCount();
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedCord at the given index.
-     */
-    java.lang.String getRepeatedCord(int index);
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedCord at the given index.
-     */
-    com.google.protobuf.ByteString
-        getRepeatedCordBytes(int index);
-
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage> 
-        getRepeatedLazyMessageList();
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage getRepeatedLazyMessage(int index);
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    int getRepeatedLazyMessageCount();
-
-    /**
-     * <pre>
-     * Singular with defaults
-     * </pre>
-     *
-     * <code>optional int32 default_int32 = 61 [default = 41];</code>
-     * @return Whether the defaultInt32 field is set.
-     */
-    boolean hasDefaultInt32();
-    /**
-     * <pre>
-     * Singular with defaults
-     * </pre>
-     *
-     * <code>optional int32 default_int32 = 61 [default = 41];</code>
-     * @return The defaultInt32.
-     */
-    int getDefaultInt32();
-
-    /**
-     * <code>optional int64 default_int64 = 62 [default = 42];</code>
-     * @return Whether the defaultInt64 field is set.
-     */
-    boolean hasDefaultInt64();
-    /**
-     * <code>optional int64 default_int64 = 62 [default = 42];</code>
-     * @return The defaultInt64.
-     */
-    long getDefaultInt64();
-
-    /**
-     * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-     * @return Whether the defaultUint32 field is set.
-     */
-    boolean hasDefaultUint32();
-    /**
-     * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-     * @return The defaultUint32.
-     */
-    int getDefaultUint32();
-
-    /**
-     * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-     * @return Whether the defaultUint64 field is set.
-     */
-    boolean hasDefaultUint64();
-    /**
-     * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-     * @return The defaultUint64.
-     */
-    long getDefaultUint64();
-
-    /**
-     * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-     * @return Whether the defaultSint32 field is set.
-     */
-    boolean hasDefaultSint32();
-    /**
-     * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-     * @return The defaultSint32.
-     */
-    int getDefaultSint32();
-
-    /**
-     * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-     * @return Whether the defaultSint64 field is set.
-     */
-    boolean hasDefaultSint64();
-    /**
-     * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-     * @return The defaultSint64.
-     */
-    long getDefaultSint64();
-
-    /**
-     * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-     * @return Whether the defaultFixed32 field is set.
-     */
-    boolean hasDefaultFixed32();
-    /**
-     * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-     * @return The defaultFixed32.
-     */
-    int getDefaultFixed32();
-
-    /**
-     * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-     * @return Whether the defaultFixed64 field is set.
-     */
-    boolean hasDefaultFixed64();
-    /**
-     * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-     * @return The defaultFixed64.
-     */
-    long getDefaultFixed64();
-
-    /**
-     * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-     * @return Whether the defaultSfixed32 field is set.
-     */
-    boolean hasDefaultSfixed32();
-    /**
-     * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-     * @return The defaultSfixed32.
-     */
-    int getDefaultSfixed32();
-
-    /**
-     * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-     * @return Whether the defaultSfixed64 field is set.
-     */
-    boolean hasDefaultSfixed64();
-    /**
-     * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-     * @return The defaultSfixed64.
-     */
-    long getDefaultSfixed64();
-
-    /**
-     * <code>optional float default_float = 71 [default = 51.5];</code>
-     * @return Whether the defaultFloat field is set.
-     */
-    boolean hasDefaultFloat();
-    /**
-     * <code>optional float default_float = 71 [default = 51.5];</code>
-     * @return The defaultFloat.
-     */
-    float getDefaultFloat();
-
-    /**
-     * <code>optional double default_double = 72 [default = 52000];</code>
-     * @return Whether the defaultDouble field is set.
-     */
-    boolean hasDefaultDouble();
-    /**
-     * <code>optional double default_double = 72 [default = 52000];</code>
-     * @return The defaultDouble.
-     */
-    double getDefaultDouble();
-
-    /**
-     * <code>optional bool default_bool = 73 [default = true];</code>
-     * @return Whether the defaultBool field is set.
-     */
-    boolean hasDefaultBool();
-    /**
-     * <code>optional bool default_bool = 73 [default = true];</code>
-     * @return The defaultBool.
-     */
-    boolean getDefaultBool();
-
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     * @return Whether the defaultString field is set.
-     */
-    boolean hasDefaultString();
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     * @return The defaultString.
-     */
-    java.lang.String getDefaultString();
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     * @return The bytes for defaultString.
-     */
-    com.google.protobuf.ByteString
-        getDefaultStringBytes();
-
-    /**
-     * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-     * @return Whether the defaultBytes field is set.
-     */
-    boolean hasDefaultBytes();
-    /**
-     * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-     * @return The defaultBytes.
-     */
-    com.google.protobuf.ByteString getDefaultBytes();
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-     * @return Whether the defaultNestedEnum field is set.
-     */
-    boolean hasDefaultNestedEnum();
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-     * @return The defaultNestedEnum.
-     */
-    com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum getDefaultNestedEnum();
-
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite default_foreign_enum = 82 [default = FOREIGN_LITE_BAR];</code>
-     * @return Whether the defaultForeignEnum field is set.
-     */
-    boolean hasDefaultForeignEnum();
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite default_foreign_enum = 82 [default = FOREIGN_LITE_BAR];</code>
-     * @return The defaultForeignEnum.
-     */
-    com.google.protobuf.UnittestLite.ForeignEnumLite getDefaultForeignEnum();
-
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnumLite default_import_enum = 83 [default = IMPORT_LITE_BAR];</code>
-     * @return Whether the defaultImportEnum field is set.
-     */
-    boolean hasDefaultImportEnum();
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnumLite default_import_enum = 83 [default = IMPORT_LITE_BAR];</code>
-     * @return The defaultImportEnum.
-     */
-    com.google.protobuf.UnittestImportLite.ImportEnumLite getDefaultImportEnum();
-
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     * @return Whether the defaultStringPiece field is set.
-     */
-    boolean hasDefaultStringPiece();
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     * @return The defaultStringPiece.
-     */
-    java.lang.String getDefaultStringPiece();
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     * @return The bytes for defaultStringPiece.
-     */
-    com.google.protobuf.ByteString
-        getDefaultStringPieceBytes();
-
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     * @return Whether the defaultCord field is set.
-     */
-    boolean hasDefaultCord();
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     * @return The defaultCord.
-     */
-    java.lang.String getDefaultCord();
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     * @return The bytes for defaultCord.
-     */
-    com.google.protobuf.ByteString
-        getDefaultCordBytes();
-
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     * @return Whether the oneofUint32 field is set.
-     */
-    boolean hasOneofUint32();
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     * @return The oneofUint32.
-     */
-    int getOneofUint32();
-
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_nested_message = 112;</code>
-     * @return Whether the oneofNestedMessage field is set.
-     */
-    boolean hasOneofNestedMessage();
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_nested_message = 112;</code>
-     * @return The oneofNestedMessage.
-     */
-    com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage getOneofNestedMessage();
-
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return Whether the oneofString field is set.
-     */
-    boolean hasOneofString();
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return The oneofString.
-     */
-    java.lang.String getOneofString();
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return The bytes for oneofString.
-     */
-    com.google.protobuf.ByteString
-        getOneofStringBytes();
-
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     * @return Whether the oneofBytes field is set.
-     */
-    boolean hasOneofBytes();
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     * @return The oneofBytes.
-     */
-    com.google.protobuf.ByteString getOneofBytes();
-
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_lazy_nested_message = 115 [lazy = true];</code>
-     * @return Whether the oneofLazyNestedMessage field is set.
-     */
-    boolean hasOneofLazyNestedMessage();
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_lazy_nested_message = 115 [lazy = true];</code>
-     * @return The oneofLazyNestedMessage.
-     */
-    com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage getOneofLazyNestedMessage();
-
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage2 oneof_nested_message2 = 117;</code>
-     * @return Whether the oneofNestedMessage2 field is set.
-     */
-    boolean hasOneofNestedMessage2();
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage2 oneof_nested_message2 = 117;</code>
-     * @return The oneofNestedMessage2.
-     */
-    com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 getOneofNestedMessage2();
-
-    /**
-     * <pre>
-     * Tests toString for non-repeated fields with a list suffix
-     * </pre>
-     *
-     * <code>optional int32 deceptively_named_list = 116;</code>
-     * @return Whether the deceptivelyNamedList field is set.
-     */
-    boolean hasDeceptivelyNamedList();
-    /**
-     * <pre>
-     * Tests toString for non-repeated fields with a list suffix
-     * </pre>
-     *
-     * <code>optional int32 deceptively_named_list = 116;</code>
-     * @return The deceptivelyNamedList.
-     */
-    int getDeceptivelyNamedList();
-
-    public com.google.protobuf.UnittestLite.TestAllTypesLite.OneofFieldCase getOneofFieldCase();
-  }
-  /**
-   * <pre>
-   * Same as TestAllTypes but with the lite runtime.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestAllTypesLite}
-   */
-  public  static final class TestAllTypesLite extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestAllTypesLite, TestAllTypesLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestAllTypesLite)
-      TestAllTypesLiteOrBuilder {
-    private TestAllTypesLite() {
-      optionalString_ = "";
-      optionalBytes_ = com.google.protobuf.ByteString.EMPTY;
-      optionalNestedEnum_ = 1;
-      optionalForeignEnum_ = 4;
-      optionalImportEnum_ = 7;
-      optionalStringPiece_ = "";
-      optionalCord_ = "";
-      repeatedInt32_ = emptyIntList();
-      repeatedInt64_ = emptyLongList();
-      repeatedUint32_ = emptyIntList();
-      repeatedUint64_ = emptyLongList();
-      repeatedSint32_ = emptyIntList();
-      repeatedSint64_ = emptyLongList();
-      repeatedFixed32_ = emptyIntList();
-      repeatedFixed64_ = emptyLongList();
-      repeatedSfixed32_ = emptyIntList();
-      repeatedSfixed64_ = emptyLongList();
-      repeatedFloat_ = emptyFloatList();
-      repeatedDouble_ = emptyDoubleList();
-      repeatedBool_ = emptyBooleanList();
-      repeatedString_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      repeatedBytes_ = emptyProtobufList();
-      repeatedGroup_ = emptyProtobufList();
-      repeatedNestedMessage_ = emptyProtobufList();
-      repeatedForeignMessage_ = emptyProtobufList();
-      repeatedImportMessage_ = emptyProtobufList();
-      repeatedNestedEnum_ = emptyIntList();
-      repeatedForeignEnum_ = emptyIntList();
-      repeatedImportEnum_ = emptyIntList();
-      repeatedStringPiece_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      repeatedCord_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      repeatedLazyMessage_ = emptyProtobufList();
-      defaultInt32_ = 41;
-      defaultInt64_ = 42L;
-      defaultUint32_ = 43;
-      defaultUint64_ = 44L;
-      defaultSint32_ = -45;
-      defaultSint64_ = 46L;
-      defaultFixed32_ = 47;
-      defaultFixed64_ = 48L;
-      defaultSfixed32_ = 49;
-      defaultSfixed64_ = -50L;
-      defaultFloat_ = 51.5F;
-      defaultDouble_ = 52000D;
-      defaultBool_ = true;
-      defaultString_ = "hello";
-      defaultBytes_ = DEFAULTBYTES_DEFAULT_VALUE;
-      defaultNestedEnum_ = 2;
-      defaultForeignEnum_ = 5;
-      defaultImportEnum_ = 8;
-      defaultStringPiece_ = "abc";
-      defaultCord_ = "123";
-    }
-    /**
-     * Protobuf enum {@code protobuf_unittest.TestAllTypesLite.NestedEnum}
-     */
-    public enum NestedEnum
-        implements com.google.protobuf.Internal.EnumLite {
-      /**
-       * <code>FOO = 1;</code>
-       */
-      FOO(1),
-      /**
-       * <code>BAR = 2;</code>
-       */
-      BAR(2),
-      /**
-       * <code>BAZ = 3;</code>
-       */
-      BAZ(3),
-      ;
-
-      /**
-       * <code>FOO = 1;</code>
-       */
-      public static final int FOO_VALUE = 1;
-      /**
-       * <code>BAR = 2;</code>
-       */
-      public static final int BAR_VALUE = 2;
-      /**
-       * <code>BAZ = 3;</code>
-       */
-      public static final int BAZ_VALUE = 3;
-
-
-      @java.lang.Override
-      public final int getNumber() {
-        return value;
-      }
-
-      /**
-       * @param value The number of the enum to look for.
-       * @return The enum associated with the given number.
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static NestedEnum valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static NestedEnum forNumber(int value) {
-        switch (value) {
-          case 1: return FOO;
-          case 2: return BAR;
-          case 3: return BAZ;
-          default: return null;
-        }
-      }
-
-      public static com.google.protobuf.Internal.EnumLiteMap<NestedEnum>
-          internalGetValueMap() {
-        return internalValueMap;
-      }
-      private static final com.google.protobuf.Internal.EnumLiteMap<
-          NestedEnum> internalValueMap =
-            new com.google.protobuf.Internal.EnumLiteMap<NestedEnum>() {
-              @java.lang.Override
-              public NestedEnum findValueByNumber(int number) {
-                return NestedEnum.forNumber(number);
-              }
-            };
-
-      public static com.google.protobuf.Internal.EnumVerifier 
-          internalGetVerifier() {
-        return NestedEnumVerifier.INSTANCE;
-      }
-
-      private static final class NestedEnumVerifier implements 
-           com.google.protobuf.Internal.EnumVerifier { 
-              static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new NestedEnumVerifier();
-              @java.lang.Override
-              public boolean isInRange(int number) {
-                return NestedEnum.forNumber(number) != null;
-              }
-            };
-
-      private final int value;
-
-      private NestedEnum(int value) {
-        this.value = value;
-      }
-
-      // @@protoc_insertion_point(enum_scope:protobuf_unittest.TestAllTypesLite.NestedEnum)
-    }
-
-    public interface NestedMessageOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestAllTypesLite.NestedMessage)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int32 bb = 1;</code>
-       * @return Whether the bb field is set.
-       */
-      boolean hasBb();
-      /**
-       * <code>optional int32 bb = 1;</code>
-       * @return The bb.
-       */
-      int getBb();
-
-      /**
-       * <code>optional int64 cc = 2;</code>
-       * @return Whether the cc field is set.
-       */
-      boolean hasCc();
-      /**
-       * <code>optional int64 cc = 2;</code>
-       * @return The cc.
-       */
-      long getCc();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestAllTypesLite.NestedMessage}
-     */
-    public  static final class NestedMessage extends
-        com.google.protobuf.GeneratedMessageLite<
-            NestedMessage, NestedMessage.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestAllTypesLite.NestedMessage)
-        NestedMessageOrBuilder {
-      private NestedMessage() {
-      }
-      private int bitField0_;
-      public static final int BB_FIELD_NUMBER = 1;
-      private int bb_;
-      /**
-       * <code>optional int32 bb = 1;</code>
-       * @return Whether the bb field is set.
-       */
-      @java.lang.Override
-      public boolean hasBb() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int32 bb = 1;</code>
-       * @return The bb.
-       */
-      @java.lang.Override
-      public int getBb() {
-        return bb_;
-      }
-      /**
-       * <code>optional int32 bb = 1;</code>
-       * @param value The bb to set.
-       */
-      private void setBb(int value) {
-        bitField0_ |= 0x00000001;
-        bb_ = value;
-      }
-      /**
-       * <code>optional int32 bb = 1;</code>
-       */
-      private void clearBb() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        bb_ = 0;
-      }
-
-      public static final int CC_FIELD_NUMBER = 2;
-      private long cc_;
-      /**
-       * <code>optional int64 cc = 2;</code>
-       * @return Whether the cc field is set.
-       */
-      @java.lang.Override
-      public boolean hasCc() {
-        return ((bitField0_ & 0x00000002) != 0);
-      }
-      /**
-       * <code>optional int64 cc = 2;</code>
-       * @return The cc.
-       */
-      @java.lang.Override
-      public long getCc() {
-        return cc_;
-      }
-      /**
-       * <code>optional int64 cc = 2;</code>
-       * @param value The cc to set.
-       */
-      private void setCc(long value) {
-        bitField0_ |= 0x00000002;
-        cc_ = value;
-      }
-      /**
-       * <code>optional int64 cc = 2;</code>
-       */
-      private void clearCc() {
-        bitField0_ = (bitField0_ & ~0x00000002);
-        cc_ = 0L;
-      }
-
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestAllTypesLite.NestedMessage}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestAllTypesLite.NestedMessage)
-          com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessageOrBuilder {
-        // Construct using com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int32 bb = 1;</code>
-         * @return Whether the bb field is set.
-         */
-        @java.lang.Override
-        public boolean hasBb() {
-          return instance.hasBb();
-        }
-        /**
-         * <code>optional int32 bb = 1;</code>
-         * @return The bb.
-         */
-        @java.lang.Override
-        public int getBb() {
-          return instance.getBb();
-        }
-        /**
-         * <code>optional int32 bb = 1;</code>
-         * @param value The bb to set.
-         * @return This builder for chaining.
-         */
-        public Builder setBb(int value) {
-          copyOnWrite();
-          instance.setBb(value);
-          return this;
-        }
-        /**
-         * <code>optional int32 bb = 1;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearBb() {
-          copyOnWrite();
-          instance.clearBb();
-          return this;
-        }
-
-        /**
-         * <code>optional int64 cc = 2;</code>
-         * @return Whether the cc field is set.
-         */
-        @java.lang.Override
-        public boolean hasCc() {
-          return instance.hasCc();
-        }
-        /**
-         * <code>optional int64 cc = 2;</code>
-         * @return The cc.
-         */
-        @java.lang.Override
-        public long getCc() {
-          return instance.getCc();
-        }
-        /**
-         * <code>optional int64 cc = 2;</code>
-         * @param value The cc to set.
-         * @return This builder for chaining.
-         */
-        public Builder setCc(long value) {
-          copyOnWrite();
-          instance.setCc(value);
-          return this;
-        }
-        /**
-         * <code>optional int64 cc = 2;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearCc() {
-          copyOnWrite();
-          instance.clearCc();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestAllTypesLite.NestedMessage)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "bb_",
-                "cc_",
-              };
-              java.lang.String info =
-                  "\u0001\u0002\u0000\u0001\u0001\u0002\u0002\u0000\u0000\u0000\u0001\u1004\u0000\u0002" +
-                  "\u1002\u0001";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage> parser = PARSER;
-            if (parser == null) {
-              synchronized (com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestAllTypesLite.NestedMessage)
-      private static final com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage DEFAULT_INSTANCE;
-      static {
-        NestedMessage defaultInstance = new NestedMessage();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          NestedMessage.class, defaultInstance);
-      }
-
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<NestedMessage> PARSER;
-
-      public static com.google.protobuf.Parser<NestedMessage> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    public interface NestedMessage2OrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestAllTypesLite.NestedMessage2)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int32 dd = 1;</code>
-       * @return Whether the dd field is set.
-       */
-      boolean hasDd();
-      /**
-       * <code>optional int32 dd = 1;</code>
-       * @return The dd.
-       */
-      int getDd();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestAllTypesLite.NestedMessage2}
-     */
-    public  static final class NestedMessage2 extends
-        com.google.protobuf.GeneratedMessageLite<
-            NestedMessage2, NestedMessage2.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestAllTypesLite.NestedMessage2)
-        NestedMessage2OrBuilder {
-      private NestedMessage2() {
-      }
-      private int bitField0_;
-      public static final int DD_FIELD_NUMBER = 1;
-      private int dd_;
-      /**
-       * <code>optional int32 dd = 1;</code>
-       * @return Whether the dd field is set.
-       */
-      @java.lang.Override
-      public boolean hasDd() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int32 dd = 1;</code>
-       * @return The dd.
-       */
-      @java.lang.Override
-      public int getDd() {
-        return dd_;
-      }
-      /**
-       * <code>optional int32 dd = 1;</code>
-       * @param value The dd to set.
-       */
-      private void setDd(int value) {
-        bitField0_ |= 0x00000001;
-        dd_ = value;
-      }
-      /**
-       * <code>optional int32 dd = 1;</code>
-       */
-      private void clearDd() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        dd_ = 0;
-      }
-
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestAllTypesLite.NestedMessage2}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestAllTypesLite.NestedMessage2)
-          com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2OrBuilder {
-        // Construct using com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int32 dd = 1;</code>
-         * @return Whether the dd field is set.
-         */
-        @java.lang.Override
-        public boolean hasDd() {
-          return instance.hasDd();
-        }
-        /**
-         * <code>optional int32 dd = 1;</code>
-         * @return The dd.
-         */
-        @java.lang.Override
-        public int getDd() {
-          return instance.getDd();
-        }
-        /**
-         * <code>optional int32 dd = 1;</code>
-         * @param value The dd to set.
-         * @return This builder for chaining.
-         */
-        public Builder setDd(int value) {
-          copyOnWrite();
-          instance.setDd(value);
-          return this;
-        }
-        /**
-         * <code>optional int32 dd = 1;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearDd() {
-          copyOnWrite();
-          instance.clearDd();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestAllTypesLite.NestedMessage2)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "dd_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1004\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2> parser = PARSER;
-            if (parser == null) {
-              synchronized (com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestAllTypesLite.NestedMessage2)
-      private static final com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 DEFAULT_INSTANCE;
-      static {
-        NestedMessage2 defaultInstance = new NestedMessage2();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          NestedMessage2.class, defaultInstance);
-      }
-
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<NestedMessage2> PARSER;
-
-      public static com.google.protobuf.Parser<NestedMessage2> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    public interface OptionalGroupOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestAllTypesLite.OptionalGroup)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return Whether the a field is set.
-       */
-      boolean hasA();
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return The a.
-       */
-      int getA();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestAllTypesLite.OptionalGroup}
-     */
-    public  static final class OptionalGroup extends
-        com.google.protobuf.GeneratedMessageLite<
-            OptionalGroup, OptionalGroup.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestAllTypesLite.OptionalGroup)
-        OptionalGroupOrBuilder {
-      private OptionalGroup() {
-      }
-      private int bitField0_;
-      public static final int A_FIELD_NUMBER = 17;
-      private int a_;
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public int getA() {
-        return a_;
-      }
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @param value The a to set.
-       */
-      private void setA(int value) {
-        bitField0_ |= 0x00000001;
-        a_ = value;
-      }
-      /**
-       * <code>optional int32 a = 17;</code>
-       */
-      private void clearA() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        a_ = 0;
-      }
-
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestAllTypesLite.OptionalGroup}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestAllTypesLite.OptionalGroup)
-          com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroupOrBuilder {
-        // Construct using com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int32 a = 17;</code>
-         * @return Whether the a field is set.
-         */
-        @java.lang.Override
-        public boolean hasA() {
-          return instance.hasA();
-        }
-        /**
-         * <code>optional int32 a = 17;</code>
-         * @return The a.
-         */
-        @java.lang.Override
-        public int getA() {
-          return instance.getA();
-        }
-        /**
-         * <code>optional int32 a = 17;</code>
-         * @param value The a to set.
-         * @return This builder for chaining.
-         */
-        public Builder setA(int value) {
-          copyOnWrite();
-          instance.setA(value);
-          return this;
-        }
-        /**
-         * <code>optional int32 a = 17;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearA() {
-          copyOnWrite();
-          instance.clearA();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestAllTypesLite.OptionalGroup)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "a_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\u0011\u0011\u0001\u0000\u0000\u0000\u0011\u1004\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup> parser = PARSER;
-            if (parser == null) {
-              synchronized (com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestAllTypesLite.OptionalGroup)
-      private static final com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup DEFAULT_INSTANCE;
-      static {
-        OptionalGroup defaultInstance = new OptionalGroup();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          OptionalGroup.class, defaultInstance);
-      }
-
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<OptionalGroup> PARSER;
-
-      public static com.google.protobuf.Parser<OptionalGroup> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    public interface RepeatedGroupOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestAllTypesLite.RepeatedGroup)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int32 a = 47;</code>
-       * @return Whether the a field is set.
-       */
-      boolean hasA();
-      /**
-       * <code>optional int32 a = 47;</code>
-       * @return The a.
-       */
-      int getA();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestAllTypesLite.RepeatedGroup}
-     */
-    public  static final class RepeatedGroup extends
-        com.google.protobuf.GeneratedMessageLite<
-            RepeatedGroup, RepeatedGroup.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestAllTypesLite.RepeatedGroup)
-        RepeatedGroupOrBuilder {
-      private RepeatedGroup() {
-      }
-      private int bitField0_;
-      public static final int A_FIELD_NUMBER = 47;
-      private int a_;
-      /**
-       * <code>optional int32 a = 47;</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int32 a = 47;</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public int getA() {
-        return a_;
-      }
-      /**
-       * <code>optional int32 a = 47;</code>
-       * @param value The a to set.
-       */
-      private void setA(int value) {
-        bitField0_ |= 0x00000001;
-        a_ = value;
-      }
-      /**
-       * <code>optional int32 a = 47;</code>
-       */
-      private void clearA() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        a_ = 0;
-      }
-
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestAllTypesLite.RepeatedGroup}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestAllTypesLite.RepeatedGroup)
-          com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroupOrBuilder {
-        // Construct using com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int32 a = 47;</code>
-         * @return Whether the a field is set.
-         */
-        @java.lang.Override
-        public boolean hasA() {
-          return instance.hasA();
-        }
-        /**
-         * <code>optional int32 a = 47;</code>
-         * @return The a.
-         */
-        @java.lang.Override
-        public int getA() {
-          return instance.getA();
-        }
-        /**
-         * <code>optional int32 a = 47;</code>
-         * @param value The a to set.
-         * @return This builder for chaining.
-         */
-        public Builder setA(int value) {
-          copyOnWrite();
-          instance.setA(value);
-          return this;
-        }
-        /**
-         * <code>optional int32 a = 47;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearA() {
-          copyOnWrite();
-          instance.clearA();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestAllTypesLite.RepeatedGroup)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "a_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001//\u0001\u0000\u0000\u0000/\u1004\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup> parser = PARSER;
-            if (parser == null) {
-              synchronized (com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestAllTypesLite.RepeatedGroup)
-      private static final com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup DEFAULT_INSTANCE;
-      static {
-        RepeatedGroup defaultInstance = new RepeatedGroup();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          RepeatedGroup.class, defaultInstance);
-      }
-
-      public static com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<RepeatedGroup> PARSER;
-
-      public static com.google.protobuf.Parser<RepeatedGroup> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int bitField0_;
-    private int bitField1_;
-    private int oneofFieldCase_ = 0;
-    private java.lang.Object oneofField_;
-    public enum OneofFieldCase {
-      ONEOF_UINT32(111),
-      ONEOF_NESTED_MESSAGE(112),
-      ONEOF_STRING(113),
-      ONEOF_BYTES(114),
-      ONEOF_LAZY_NESTED_MESSAGE(115),
-      ONEOF_NESTED_MESSAGE2(117),
-      ONEOFFIELD_NOT_SET(0);
-      private final int value;
-      private OneofFieldCase(int value) {
-        this.value = value;
-      }
-      /**
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static OneofFieldCase valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static OneofFieldCase forNumber(int value) {
-        switch (value) {
-          case 111: return ONEOF_UINT32;
-          case 112: return ONEOF_NESTED_MESSAGE;
-          case 113: return ONEOF_STRING;
-          case 114: return ONEOF_BYTES;
-          case 115: return ONEOF_LAZY_NESTED_MESSAGE;
-          case 117: return ONEOF_NESTED_MESSAGE2;
-          case 0: return ONEOFFIELD_NOT_SET;
-          default: return null;
-        }
-      }
-      public int getNumber() {
-        return this.value;
-      }
-    };
-
-    @java.lang.Override
-    public OneofFieldCase
-    getOneofFieldCase() {
-      return OneofFieldCase.forNumber(
-          oneofFieldCase_);
-    }
-
-    private void clearOneofField() {
-      oneofFieldCase_ = 0;
-      oneofField_ = null;
-    }
-
-    public static final int OPTIONAL_INT32_FIELD_NUMBER = 1;
-    private int optionalInt32_;
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>optional int32 optional_int32 = 1;</code>
-     * @return Whether the optionalInt32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalInt32() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>optional int32 optional_int32 = 1;</code>
-     * @return The optionalInt32.
-     */
-    @java.lang.Override
-    public int getOptionalInt32() {
-      return optionalInt32_;
-    }
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>optional int32 optional_int32 = 1;</code>
-     * @param value The optionalInt32 to set.
-     */
-    private void setOptionalInt32(int value) {
-      bitField0_ |= 0x00000001;
-      optionalInt32_ = value;
-    }
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>optional int32 optional_int32 = 1;</code>
-     */
-    private void clearOptionalInt32() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      optionalInt32_ = 0;
-    }
-
-    public static final int OPTIONAL_INT64_FIELD_NUMBER = 2;
-    private long optionalInt64_;
-    /**
-     * <code>optional int64 optional_int64 = 2;</code>
-     * @return Whether the optionalInt64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalInt64() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional int64 optional_int64 = 2;</code>
-     * @return The optionalInt64.
-     */
-    @java.lang.Override
-    public long getOptionalInt64() {
-      return optionalInt64_;
-    }
-    /**
-     * <code>optional int64 optional_int64 = 2;</code>
-     * @param value The optionalInt64 to set.
-     */
-    private void setOptionalInt64(long value) {
-      bitField0_ |= 0x00000002;
-      optionalInt64_ = value;
-    }
-    /**
-     * <code>optional int64 optional_int64 = 2;</code>
-     */
-    private void clearOptionalInt64() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      optionalInt64_ = 0L;
-    }
-
-    public static final int OPTIONAL_UINT32_FIELD_NUMBER = 3;
-    private int optionalUint32_;
-    /**
-     * <code>optional uint32 optional_uint32 = 3;</code>
-     * @return Whether the optionalUint32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalUint32() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional uint32 optional_uint32 = 3;</code>
-     * @return The optionalUint32.
-     */
-    @java.lang.Override
-    public int getOptionalUint32() {
-      return optionalUint32_;
-    }
-    /**
-     * <code>optional uint32 optional_uint32 = 3;</code>
-     * @param value The optionalUint32 to set.
-     */
-    private void setOptionalUint32(int value) {
-      bitField0_ |= 0x00000004;
-      optionalUint32_ = value;
-    }
-    /**
-     * <code>optional uint32 optional_uint32 = 3;</code>
-     */
-    private void clearOptionalUint32() {
-      bitField0_ = (bitField0_ & ~0x00000004);
-      optionalUint32_ = 0;
-    }
-
-    public static final int OPTIONAL_UINT64_FIELD_NUMBER = 4;
-    private long optionalUint64_;
-    /**
-     * <code>optional uint64 optional_uint64 = 4;</code>
-     * @return Whether the optionalUint64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalUint64() {
-      return ((bitField0_ & 0x00000008) != 0);
-    }
-    /**
-     * <code>optional uint64 optional_uint64 = 4;</code>
-     * @return The optionalUint64.
-     */
-    @java.lang.Override
-    public long getOptionalUint64() {
-      return optionalUint64_;
-    }
-    /**
-     * <code>optional uint64 optional_uint64 = 4;</code>
-     * @param value The optionalUint64 to set.
-     */
-    private void setOptionalUint64(long value) {
-      bitField0_ |= 0x00000008;
-      optionalUint64_ = value;
-    }
-    /**
-     * <code>optional uint64 optional_uint64 = 4;</code>
-     */
-    private void clearOptionalUint64() {
-      bitField0_ = (bitField0_ & ~0x00000008);
-      optionalUint64_ = 0L;
-    }
-
-    public static final int OPTIONAL_SINT32_FIELD_NUMBER = 5;
-    private int optionalSint32_;
-    /**
-     * <code>optional sint32 optional_sint32 = 5;</code>
-     * @return Whether the optionalSint32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalSint32() {
-      return ((bitField0_ & 0x00000010) != 0);
-    }
-    /**
-     * <code>optional sint32 optional_sint32 = 5;</code>
-     * @return The optionalSint32.
-     */
-    @java.lang.Override
-    public int getOptionalSint32() {
-      return optionalSint32_;
-    }
-    /**
-     * <code>optional sint32 optional_sint32 = 5;</code>
-     * @param value The optionalSint32 to set.
-     */
-    private void setOptionalSint32(int value) {
-      bitField0_ |= 0x00000010;
-      optionalSint32_ = value;
-    }
-    /**
-     * <code>optional sint32 optional_sint32 = 5;</code>
-     */
-    private void clearOptionalSint32() {
-      bitField0_ = (bitField0_ & ~0x00000010);
-      optionalSint32_ = 0;
-    }
-
-    public static final int OPTIONAL_SINT64_FIELD_NUMBER = 6;
-    private long optionalSint64_;
-    /**
-     * <code>optional sint64 optional_sint64 = 6;</code>
-     * @return Whether the optionalSint64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalSint64() {
-      return ((bitField0_ & 0x00000020) != 0);
-    }
-    /**
-     * <code>optional sint64 optional_sint64 = 6;</code>
-     * @return The optionalSint64.
-     */
-    @java.lang.Override
-    public long getOptionalSint64() {
-      return optionalSint64_;
-    }
-    /**
-     * <code>optional sint64 optional_sint64 = 6;</code>
-     * @param value The optionalSint64 to set.
-     */
-    private void setOptionalSint64(long value) {
-      bitField0_ |= 0x00000020;
-      optionalSint64_ = value;
-    }
-    /**
-     * <code>optional sint64 optional_sint64 = 6;</code>
-     */
-    private void clearOptionalSint64() {
-      bitField0_ = (bitField0_ & ~0x00000020);
-      optionalSint64_ = 0L;
-    }
-
-    public static final int OPTIONAL_FIXED32_FIELD_NUMBER = 7;
-    private int optionalFixed32_;
-    /**
-     * <code>optional fixed32 optional_fixed32 = 7;</code>
-     * @return Whether the optionalFixed32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalFixed32() {
-      return ((bitField0_ & 0x00000040) != 0);
-    }
-    /**
-     * <code>optional fixed32 optional_fixed32 = 7;</code>
-     * @return The optionalFixed32.
-     */
-    @java.lang.Override
-    public int getOptionalFixed32() {
-      return optionalFixed32_;
-    }
-    /**
-     * <code>optional fixed32 optional_fixed32 = 7;</code>
-     * @param value The optionalFixed32 to set.
-     */
-    private void setOptionalFixed32(int value) {
-      bitField0_ |= 0x00000040;
-      optionalFixed32_ = value;
-    }
-    /**
-     * <code>optional fixed32 optional_fixed32 = 7;</code>
-     */
-    private void clearOptionalFixed32() {
-      bitField0_ = (bitField0_ & ~0x00000040);
-      optionalFixed32_ = 0;
-    }
-
-    public static final int OPTIONAL_FIXED64_FIELD_NUMBER = 8;
-    private long optionalFixed64_;
-    /**
-     * <code>optional fixed64 optional_fixed64 = 8;</code>
-     * @return Whether the optionalFixed64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalFixed64() {
-      return ((bitField0_ & 0x00000080) != 0);
-    }
-    /**
-     * <code>optional fixed64 optional_fixed64 = 8;</code>
-     * @return The optionalFixed64.
-     */
-    @java.lang.Override
-    public long getOptionalFixed64() {
-      return optionalFixed64_;
-    }
-    /**
-     * <code>optional fixed64 optional_fixed64 = 8;</code>
-     * @param value The optionalFixed64 to set.
-     */
-    private void setOptionalFixed64(long value) {
-      bitField0_ |= 0x00000080;
-      optionalFixed64_ = value;
-    }
-    /**
-     * <code>optional fixed64 optional_fixed64 = 8;</code>
-     */
-    private void clearOptionalFixed64() {
-      bitField0_ = (bitField0_ & ~0x00000080);
-      optionalFixed64_ = 0L;
-    }
-
-    public static final int OPTIONAL_SFIXED32_FIELD_NUMBER = 9;
-    private int optionalSfixed32_;
-    /**
-     * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-     * @return Whether the optionalSfixed32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalSfixed32() {
-      return ((bitField0_ & 0x00000100) != 0);
-    }
-    /**
-     * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-     * @return The optionalSfixed32.
-     */
-    @java.lang.Override
-    public int getOptionalSfixed32() {
-      return optionalSfixed32_;
-    }
-    /**
-     * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-     * @param value The optionalSfixed32 to set.
-     */
-    private void setOptionalSfixed32(int value) {
-      bitField0_ |= 0x00000100;
-      optionalSfixed32_ = value;
-    }
-    /**
-     * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-     */
-    private void clearOptionalSfixed32() {
-      bitField0_ = (bitField0_ & ~0x00000100);
-      optionalSfixed32_ = 0;
-    }
-
-    public static final int OPTIONAL_SFIXED64_FIELD_NUMBER = 10;
-    private long optionalSfixed64_;
-    /**
-     * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-     * @return Whether the optionalSfixed64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalSfixed64() {
-      return ((bitField0_ & 0x00000200) != 0);
-    }
-    /**
-     * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-     * @return The optionalSfixed64.
-     */
-    @java.lang.Override
-    public long getOptionalSfixed64() {
-      return optionalSfixed64_;
-    }
-    /**
-     * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-     * @param value The optionalSfixed64 to set.
-     */
-    private void setOptionalSfixed64(long value) {
-      bitField0_ |= 0x00000200;
-      optionalSfixed64_ = value;
-    }
-    /**
-     * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-     */
-    private void clearOptionalSfixed64() {
-      bitField0_ = (bitField0_ & ~0x00000200);
-      optionalSfixed64_ = 0L;
-    }
-
-    public static final int OPTIONAL_FLOAT_FIELD_NUMBER = 11;
-    private float optionalFloat_;
-    /**
-     * <code>optional float optional_float = 11;</code>
-     * @return Whether the optionalFloat field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalFloat() {
-      return ((bitField0_ & 0x00000400) != 0);
-    }
-    /**
-     * <code>optional float optional_float = 11;</code>
-     * @return The optionalFloat.
-     */
-    @java.lang.Override
-    public float getOptionalFloat() {
-      return optionalFloat_;
-    }
-    /**
-     * <code>optional float optional_float = 11;</code>
-     * @param value The optionalFloat to set.
-     */
-    private void setOptionalFloat(float value) {
-      bitField0_ |= 0x00000400;
-      optionalFloat_ = value;
-    }
-    /**
-     * <code>optional float optional_float = 11;</code>
-     */
-    private void clearOptionalFloat() {
-      bitField0_ = (bitField0_ & ~0x00000400);
-      optionalFloat_ = 0F;
-    }
-
-    public static final int OPTIONAL_DOUBLE_FIELD_NUMBER = 12;
-    private double optionalDouble_;
-    /**
-     * <code>optional double optional_double = 12;</code>
-     * @return Whether the optionalDouble field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalDouble() {
-      return ((bitField0_ & 0x00000800) != 0);
-    }
-    /**
-     * <code>optional double optional_double = 12;</code>
-     * @return The optionalDouble.
-     */
-    @java.lang.Override
-    public double getOptionalDouble() {
-      return optionalDouble_;
-    }
-    /**
-     * <code>optional double optional_double = 12;</code>
-     * @param value The optionalDouble to set.
-     */
-    private void setOptionalDouble(double value) {
-      bitField0_ |= 0x00000800;
-      optionalDouble_ = value;
-    }
-    /**
-     * <code>optional double optional_double = 12;</code>
-     */
-    private void clearOptionalDouble() {
-      bitField0_ = (bitField0_ & ~0x00000800);
-      optionalDouble_ = 0D;
-    }
-
-    public static final int OPTIONAL_BOOL_FIELD_NUMBER = 13;
-    private boolean optionalBool_;
-    /**
-     * <code>optional bool optional_bool = 13;</code>
-     * @return Whether the optionalBool field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalBool() {
-      return ((bitField0_ & 0x00001000) != 0);
-    }
-    /**
-     * <code>optional bool optional_bool = 13;</code>
-     * @return The optionalBool.
-     */
-    @java.lang.Override
-    public boolean getOptionalBool() {
-      return optionalBool_;
-    }
-    /**
-     * <code>optional bool optional_bool = 13;</code>
-     * @param value The optionalBool to set.
-     */
-    private void setOptionalBool(boolean value) {
-      bitField0_ |= 0x00001000;
-      optionalBool_ = value;
-    }
-    /**
-     * <code>optional bool optional_bool = 13;</code>
-     */
-    private void clearOptionalBool() {
-      bitField0_ = (bitField0_ & ~0x00001000);
-      optionalBool_ = false;
-    }
-
-    public static final int OPTIONAL_STRING_FIELD_NUMBER = 14;
-    private java.lang.String optionalString_;
-    /**
-     * <code>optional string optional_string = 14;</code>
-     * @return Whether the optionalString field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalString() {
-      return ((bitField0_ & 0x00002000) != 0);
-    }
-    /**
-     * <code>optional string optional_string = 14;</code>
-     * @return The optionalString.
-     */
-    @java.lang.Override
-    public java.lang.String getOptionalString() {
-      return optionalString_;
-    }
-    /**
-     * <code>optional string optional_string = 14;</code>
-     * @return The bytes for optionalString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOptionalStringBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(optionalString_);
-    }
-    /**
-     * <code>optional string optional_string = 14;</code>
-     * @param value The optionalString to set.
-     */
-    private void setOptionalString(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00002000;
-      optionalString_ = value;
-    }
-    /**
-     * <code>optional string optional_string = 14;</code>
-     */
-    private void clearOptionalString() {
-      bitField0_ = (bitField0_ & ~0x00002000);
-      optionalString_ = getDefaultInstance().getOptionalString();
-    }
-    /**
-     * <code>optional string optional_string = 14;</code>
-     * @param value The bytes for optionalString to set.
-     */
-    private void setOptionalStringBytes(
-        com.google.protobuf.ByteString value) {
-      optionalString_ = value.toStringUtf8();
-      bitField0_ |= 0x00002000;
-    }
-
-    public static final int OPTIONAL_BYTES_FIELD_NUMBER = 15;
-    private com.google.protobuf.ByteString optionalBytes_;
-    /**
-     * <code>optional bytes optional_bytes = 15;</code>
-     * @return Whether the optionalBytes field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalBytes() {
-      return ((bitField0_ & 0x00004000) != 0);
-    }
-    /**
-     * <code>optional bytes optional_bytes = 15;</code>
-     * @return The optionalBytes.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getOptionalBytes() {
-      return optionalBytes_;
-    }
-    /**
-     * <code>optional bytes optional_bytes = 15;</code>
-     * @param value The optionalBytes to set.
-     */
-    private void setOptionalBytes(com.google.protobuf.ByteString value) {
-      value.getClass();
-  bitField0_ |= 0x00004000;
-      optionalBytes_ = value;
-    }
-    /**
-     * <code>optional bytes optional_bytes = 15;</code>
-     */
-    private void clearOptionalBytes() {
-      bitField0_ = (bitField0_ & ~0x00004000);
-      optionalBytes_ = getDefaultInstance().getOptionalBytes();
-    }
-
-    public static final int OPTIONALGROUP_FIELD_NUMBER = 16;
-    private com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup optionalGroup_;
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalGroup() {
-      return ((bitField0_ & 0x00008000) != 0);
-    }
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup getOptionalGroup() {
-      return optionalGroup_ == null ? com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup.getDefaultInstance() : optionalGroup_;
-    }
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     */
-    private void setOptionalGroup(com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup value) {
-      value.getClass();
-  optionalGroup_ = value;
-      bitField0_ |= 0x00008000;
-      }
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalGroup(com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup value) {
-      value.getClass();
-  if (optionalGroup_ != null &&
-          optionalGroup_ != com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup.getDefaultInstance()) {
-        optionalGroup_ =
-          com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup.newBuilder(optionalGroup_).mergeFrom(value).buildPartial();
-      } else {
-        optionalGroup_ = value;
-      }
-      bitField0_ |= 0x00008000;
-    }
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     */
-    private void clearOptionalGroup() {  optionalGroup_ = null;
-      bitField0_ = (bitField0_ & ~0x00008000);
-    }
-
-    public static final int OPTIONAL_NESTED_MESSAGE_FIELD_NUMBER = 18;
-    private com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage optionalNestedMessage_;
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_nested_message = 18;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalNestedMessage() {
-      return ((bitField0_ & 0x00010000) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_nested_message = 18;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage getOptionalNestedMessage() {
-      return optionalNestedMessage_ == null ? com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.getDefaultInstance() : optionalNestedMessage_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_nested_message = 18;</code>
-     */
-    private void setOptionalNestedMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-      value.getClass();
-  optionalNestedMessage_ = value;
-      bitField0_ |= 0x00010000;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_nested_message = 18;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalNestedMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-      value.getClass();
-  if (optionalNestedMessage_ != null &&
-          optionalNestedMessage_ != com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.getDefaultInstance()) {
-        optionalNestedMessage_ =
-          com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.newBuilder(optionalNestedMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalNestedMessage_ = value;
-      }
-      bitField0_ |= 0x00010000;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_nested_message = 18;</code>
-     */
-    private void clearOptionalNestedMessage() {  optionalNestedMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x00010000);
-    }
-
-    public static final int OPTIONAL_FOREIGN_MESSAGE_FIELD_NUMBER = 19;
-    private com.google.protobuf.UnittestLite.ForeignMessageLite optionalForeignMessage_;
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_foreign_message = 19;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalForeignMessage() {
-      return ((bitField0_ & 0x00020000) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_foreign_message = 19;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.ForeignMessageLite getOptionalForeignMessage() {
-      return optionalForeignMessage_ == null ? com.google.protobuf.UnittestLite.ForeignMessageLite.getDefaultInstance() : optionalForeignMessage_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_foreign_message = 19;</code>
-     */
-    private void setOptionalForeignMessage(com.google.protobuf.UnittestLite.ForeignMessageLite value) {
-      value.getClass();
-  optionalForeignMessage_ = value;
-      bitField0_ |= 0x00020000;
-      }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_foreign_message = 19;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalForeignMessage(com.google.protobuf.UnittestLite.ForeignMessageLite value) {
-      value.getClass();
-  if (optionalForeignMessage_ != null &&
-          optionalForeignMessage_ != com.google.protobuf.UnittestLite.ForeignMessageLite.getDefaultInstance()) {
-        optionalForeignMessage_ =
-          com.google.protobuf.UnittestLite.ForeignMessageLite.newBuilder(optionalForeignMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalForeignMessage_ = value;
-      }
-      bitField0_ |= 0x00020000;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_foreign_message = 19;</code>
-     */
-    private void clearOptionalForeignMessage() {  optionalForeignMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x00020000);
-    }
-
-    public static final int OPTIONAL_IMPORT_MESSAGE_FIELD_NUMBER = 20;
-    private com.google.protobuf.UnittestImportLite.ImportMessageLite optionalImportMessage_;
-    /**
-     * <code>optional .protobuf_unittest_import.ImportMessageLite optional_import_message = 20;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalImportMessage() {
-      return ((bitField0_ & 0x00040000) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportMessageLite optional_import_message = 20;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestImportLite.ImportMessageLite getOptionalImportMessage() {
-      return optionalImportMessage_ == null ? com.google.protobuf.UnittestImportLite.ImportMessageLite.getDefaultInstance() : optionalImportMessage_;
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportMessageLite optional_import_message = 20;</code>
-     */
-    private void setOptionalImportMessage(com.google.protobuf.UnittestImportLite.ImportMessageLite value) {
-      value.getClass();
-  optionalImportMessage_ = value;
-      bitField0_ |= 0x00040000;
-      }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportMessageLite optional_import_message = 20;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalImportMessage(com.google.protobuf.UnittestImportLite.ImportMessageLite value) {
-      value.getClass();
-  if (optionalImportMessage_ != null &&
-          optionalImportMessage_ != com.google.protobuf.UnittestImportLite.ImportMessageLite.getDefaultInstance()) {
-        optionalImportMessage_ =
-          com.google.protobuf.UnittestImportLite.ImportMessageLite.newBuilder(optionalImportMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalImportMessage_ = value;
-      }
-      bitField0_ |= 0x00040000;
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportMessageLite optional_import_message = 20;</code>
-     */
-    private void clearOptionalImportMessage() {  optionalImportMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x00040000);
-    }
-
-    public static final int OPTIONAL_NESTED_ENUM_FIELD_NUMBER = 21;
-    private int optionalNestedEnum_;
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum optional_nested_enum = 21;</code>
-     * @return Whether the optionalNestedEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalNestedEnum() {
-      return ((bitField0_ & 0x00080000) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum optional_nested_enum = 21;</code>
-     * @return The optionalNestedEnum.
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum getOptionalNestedEnum() {
-      com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum result = com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum.forNumber(optionalNestedEnum_);
-      return result == null ? com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum.FOO : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum optional_nested_enum = 21;</code>
-     * @param value The optionalNestedEnum to set.
-     */
-    private void setOptionalNestedEnum(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum value) {
-      optionalNestedEnum_ = value.getNumber();
-      bitField0_ |= 0x00080000;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum optional_nested_enum = 21;</code>
-     */
-    private void clearOptionalNestedEnum() {
-      bitField0_ = (bitField0_ & ~0x00080000);
-      optionalNestedEnum_ = 1;
-    }
-
-    public static final int OPTIONAL_FOREIGN_ENUM_FIELD_NUMBER = 22;
-    private int optionalForeignEnum_;
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite optional_foreign_enum = 22;</code>
-     * @return Whether the optionalForeignEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalForeignEnum() {
-      return ((bitField0_ & 0x00100000) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite optional_foreign_enum = 22;</code>
-     * @return The optionalForeignEnum.
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.ForeignEnumLite getOptionalForeignEnum() {
-      com.google.protobuf.UnittestLite.ForeignEnumLite result = com.google.protobuf.UnittestLite.ForeignEnumLite.forNumber(optionalForeignEnum_);
-      return result == null ? com.google.protobuf.UnittestLite.ForeignEnumLite.FOREIGN_LITE_FOO : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite optional_foreign_enum = 22;</code>
-     * @param value The optionalForeignEnum to set.
-     */
-    private void setOptionalForeignEnum(com.google.protobuf.UnittestLite.ForeignEnumLite value) {
-      optionalForeignEnum_ = value.getNumber();
-      bitField0_ |= 0x00100000;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite optional_foreign_enum = 22;</code>
-     */
-    private void clearOptionalForeignEnum() {
-      bitField0_ = (bitField0_ & ~0x00100000);
-      optionalForeignEnum_ = 4;
-    }
-
-    public static final int OPTIONAL_IMPORT_ENUM_FIELD_NUMBER = 23;
-    private int optionalImportEnum_;
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnumLite optional_import_enum = 23;</code>
-     * @return Whether the optionalImportEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalImportEnum() {
-      return ((bitField0_ & 0x00200000) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnumLite optional_import_enum = 23;</code>
-     * @return The optionalImportEnum.
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestImportLite.ImportEnumLite getOptionalImportEnum() {
-      com.google.protobuf.UnittestImportLite.ImportEnumLite result = com.google.protobuf.UnittestImportLite.ImportEnumLite.forNumber(optionalImportEnum_);
-      return result == null ? com.google.protobuf.UnittestImportLite.ImportEnumLite.IMPORT_LITE_FOO : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnumLite optional_import_enum = 23;</code>
-     * @param value The optionalImportEnum to set.
-     */
-    private void setOptionalImportEnum(com.google.protobuf.UnittestImportLite.ImportEnumLite value) {
-      optionalImportEnum_ = value.getNumber();
-      bitField0_ |= 0x00200000;
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnumLite optional_import_enum = 23;</code>
-     */
-    private void clearOptionalImportEnum() {
-      bitField0_ = (bitField0_ & ~0x00200000);
-      optionalImportEnum_ = 7;
-    }
-
-    public static final int OPTIONAL_STRING_PIECE_FIELD_NUMBER = 24;
-    private java.lang.String optionalStringPiece_;
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @return Whether the optionalStringPiece field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalStringPiece() {
-      return ((bitField0_ & 0x00400000) != 0);
-    }
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @return The optionalStringPiece.
-     */
-    @java.lang.Override
-    public java.lang.String getOptionalStringPiece() {
-      return optionalStringPiece_;
-    }
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @return The bytes for optionalStringPiece.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOptionalStringPieceBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(optionalStringPiece_);
-    }
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @param value The optionalStringPiece to set.
-     */
-    private void setOptionalStringPiece(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00400000;
-      optionalStringPiece_ = value;
-    }
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     */
-    private void clearOptionalStringPiece() {
-      bitField0_ = (bitField0_ & ~0x00400000);
-      optionalStringPiece_ = getDefaultInstance().getOptionalStringPiece();
-    }
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @param value The bytes for optionalStringPiece to set.
-     */
-    private void setOptionalStringPieceBytes(
-        com.google.protobuf.ByteString value) {
-      optionalStringPiece_ = value.toStringUtf8();
-      bitField0_ |= 0x00400000;
-    }
-
-    public static final int OPTIONAL_CORD_FIELD_NUMBER = 25;
-    private java.lang.String optionalCord_;
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     * @return Whether the optionalCord field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalCord() {
-      return ((bitField0_ & 0x00800000) != 0);
-    }
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     * @return The optionalCord.
-     */
-    @java.lang.Override
-    public java.lang.String getOptionalCord() {
-      return optionalCord_;
-    }
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     * @return The bytes for optionalCord.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOptionalCordBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(optionalCord_);
-    }
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     * @param value The optionalCord to set.
-     */
-    private void setOptionalCord(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00800000;
-      optionalCord_ = value;
-    }
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     */
-    private void clearOptionalCord() {
-      bitField0_ = (bitField0_ & ~0x00800000);
-      optionalCord_ = getDefaultInstance().getOptionalCord();
-    }
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     * @param value The bytes for optionalCord to set.
-     */
-    private void setOptionalCordBytes(
-        com.google.protobuf.ByteString value) {
-      optionalCord_ = value.toStringUtf8();
-      bitField0_ |= 0x00800000;
-    }
-
-    public static final int OPTIONAL_PUBLIC_IMPORT_MESSAGE_FIELD_NUMBER = 26;
-    private com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite optionalPublicImportMessage_;
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>optional .protobuf_unittest_import.PublicImportMessageLite optional_public_import_message = 26;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalPublicImportMessage() {
-      return ((bitField0_ & 0x01000000) != 0);
-    }
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>optional .protobuf_unittest_import.PublicImportMessageLite optional_public_import_message = 26;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite getOptionalPublicImportMessage() {
-      return optionalPublicImportMessage_ == null ? com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite.getDefaultInstance() : optionalPublicImportMessage_;
-    }
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>optional .protobuf_unittest_import.PublicImportMessageLite optional_public_import_message = 26;</code>
-     */
-    private void setOptionalPublicImportMessage(com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite value) {
-      value.getClass();
-  optionalPublicImportMessage_ = value;
-      bitField0_ |= 0x01000000;
-      }
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>optional .protobuf_unittest_import.PublicImportMessageLite optional_public_import_message = 26;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalPublicImportMessage(com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite value) {
-      value.getClass();
-  if (optionalPublicImportMessage_ != null &&
-          optionalPublicImportMessage_ != com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite.getDefaultInstance()) {
-        optionalPublicImportMessage_ =
-          com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite.newBuilder(optionalPublicImportMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalPublicImportMessage_ = value;
-      }
-      bitField0_ |= 0x01000000;
-    }
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>optional .protobuf_unittest_import.PublicImportMessageLite optional_public_import_message = 26;</code>
-     */
-    private void clearOptionalPublicImportMessage() {  optionalPublicImportMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x01000000);
-    }
-
-    public static final int OPTIONAL_LAZY_MESSAGE_FIELD_NUMBER = 27;
-    private com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage optionalLazyMessage_;
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalLazyMessage() {
-      return ((bitField0_ & 0x02000000) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage getOptionalLazyMessage() {
-      return optionalLazyMessage_ == null ? com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.getDefaultInstance() : optionalLazyMessage_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     */
-    private void setOptionalLazyMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-      value.getClass();
-  optionalLazyMessage_ = value;
-      bitField0_ |= 0x02000000;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalLazyMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-      value.getClass();
-  if (optionalLazyMessage_ != null &&
-          optionalLazyMessage_ != com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.getDefaultInstance()) {
-        optionalLazyMessage_ =
-          com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.newBuilder(optionalLazyMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalLazyMessage_ = value;
-      }
-      bitField0_ |= 0x02000000;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     */
-    private void clearOptionalLazyMessage() {  optionalLazyMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x02000000);
-    }
-
-    public static final int REPEATED_INT32_FIELD_NUMBER = 31;
-    private com.google.protobuf.Internal.IntList repeatedInt32_;
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @return A list containing the repeatedInt32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedInt32List() {
-      return repeatedInt32_;
-    }
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @return The count of repeatedInt32.
-     */
-    @java.lang.Override
-    public int getRepeatedInt32Count() {
-      return repeatedInt32_.size();
-    }
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedInt32(int index) {
-      return repeatedInt32_.getInt(index);
-    }
-    private void ensureRepeatedInt32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedInt32_;
-      if (!tmp.isModifiable()) {
-        repeatedInt32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt32 to set.
-     */
-    private void setRepeatedInt32(
-        int index, int value) {
-      ensureRepeatedInt32IsMutable();
-      repeatedInt32_.setInt(index, value);
-    }
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param value The repeatedInt32 to add.
-     */
-    private void addRepeatedInt32(int value) {
-      ensureRepeatedInt32IsMutable();
-      repeatedInt32_.addInt(value);
-    }
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param values The repeatedInt32 to add.
-     */
-    private void addAllRepeatedInt32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedInt32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedInt32_);
-    }
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     */
-    private void clearRepeatedInt32() {
-      repeatedInt32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_INT64_FIELD_NUMBER = 32;
-    private com.google.protobuf.Internal.LongList repeatedInt64_;
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @return A list containing the repeatedInt64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedInt64List() {
-      return repeatedInt64_;
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @return The count of repeatedInt64.
-     */
-    @java.lang.Override
-    public int getRepeatedInt64Count() {
-      return repeatedInt64_.size();
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedInt64(int index) {
-      return repeatedInt64_.getLong(index);
-    }
-    private void ensureRepeatedInt64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedInt64_;
-      if (!tmp.isModifiable()) {
-        repeatedInt64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt64 to set.
-     */
-    private void setRepeatedInt64(
-        int index, long value) {
-      ensureRepeatedInt64IsMutable();
-      repeatedInt64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param value The repeatedInt64 to add.
-     */
-    private void addRepeatedInt64(long value) {
-      ensureRepeatedInt64IsMutable();
-      repeatedInt64_.addLong(value);
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param values The repeatedInt64 to add.
-     */
-    private void addAllRepeatedInt64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedInt64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedInt64_);
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     */
-    private void clearRepeatedInt64() {
-      repeatedInt64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_UINT32_FIELD_NUMBER = 33;
-    private com.google.protobuf.Internal.IntList repeatedUint32_;
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @return A list containing the repeatedUint32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedUint32List() {
-      return repeatedUint32_;
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @return The count of repeatedUint32.
-     */
-    @java.lang.Override
-    public int getRepeatedUint32Count() {
-      return repeatedUint32_.size();
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedUint32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedUint32(int index) {
-      return repeatedUint32_.getInt(index);
-    }
-    private void ensureRepeatedUint32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedUint32_;
-      if (!tmp.isModifiable()) {
-        repeatedUint32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedUint32 to set.
-     */
-    private void setRepeatedUint32(
-        int index, int value) {
-      ensureRepeatedUint32IsMutable();
-      repeatedUint32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param value The repeatedUint32 to add.
-     */
-    private void addRepeatedUint32(int value) {
-      ensureRepeatedUint32IsMutable();
-      repeatedUint32_.addInt(value);
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param values The repeatedUint32 to add.
-     */
-    private void addAllRepeatedUint32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedUint32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedUint32_);
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     */
-    private void clearRepeatedUint32() {
-      repeatedUint32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_UINT64_FIELD_NUMBER = 34;
-    private com.google.protobuf.Internal.LongList repeatedUint64_;
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @return A list containing the repeatedUint64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedUint64List() {
-      return repeatedUint64_;
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @return The count of repeatedUint64.
-     */
-    @java.lang.Override
-    public int getRepeatedUint64Count() {
-      return repeatedUint64_.size();
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedUint64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedUint64(int index) {
-      return repeatedUint64_.getLong(index);
-    }
-    private void ensureRepeatedUint64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedUint64_;
-      if (!tmp.isModifiable()) {
-        repeatedUint64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedUint64 to set.
-     */
-    private void setRepeatedUint64(
-        int index, long value) {
-      ensureRepeatedUint64IsMutable();
-      repeatedUint64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param value The repeatedUint64 to add.
-     */
-    private void addRepeatedUint64(long value) {
-      ensureRepeatedUint64IsMutable();
-      repeatedUint64_.addLong(value);
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param values The repeatedUint64 to add.
-     */
-    private void addAllRepeatedUint64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedUint64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedUint64_);
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     */
-    private void clearRepeatedUint64() {
-      repeatedUint64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_SINT32_FIELD_NUMBER = 35;
-    private com.google.protobuf.Internal.IntList repeatedSint32_;
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @return A list containing the repeatedSint32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedSint32List() {
-      return repeatedSint32_;
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @return The count of repeatedSint32.
-     */
-    @java.lang.Override
-    public int getRepeatedSint32Count() {
-      return repeatedSint32_.size();
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSint32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedSint32(int index) {
-      return repeatedSint32_.getInt(index);
-    }
-    private void ensureRepeatedSint32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedSint32_;
-      if (!tmp.isModifiable()) {
-        repeatedSint32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSint32 to set.
-     */
-    private void setRepeatedSint32(
-        int index, int value) {
-      ensureRepeatedSint32IsMutable();
-      repeatedSint32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param value The repeatedSint32 to add.
-     */
-    private void addRepeatedSint32(int value) {
-      ensureRepeatedSint32IsMutable();
-      repeatedSint32_.addInt(value);
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param values The repeatedSint32 to add.
-     */
-    private void addAllRepeatedSint32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedSint32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedSint32_);
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     */
-    private void clearRepeatedSint32() {
-      repeatedSint32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_SINT64_FIELD_NUMBER = 36;
-    private com.google.protobuf.Internal.LongList repeatedSint64_;
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @return A list containing the repeatedSint64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedSint64List() {
-      return repeatedSint64_;
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @return The count of repeatedSint64.
-     */
-    @java.lang.Override
-    public int getRepeatedSint64Count() {
-      return repeatedSint64_.size();
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSint64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedSint64(int index) {
-      return repeatedSint64_.getLong(index);
-    }
-    private void ensureRepeatedSint64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedSint64_;
-      if (!tmp.isModifiable()) {
-        repeatedSint64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSint64 to set.
-     */
-    private void setRepeatedSint64(
-        int index, long value) {
-      ensureRepeatedSint64IsMutable();
-      repeatedSint64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param value The repeatedSint64 to add.
-     */
-    private void addRepeatedSint64(long value) {
-      ensureRepeatedSint64IsMutable();
-      repeatedSint64_.addLong(value);
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param values The repeatedSint64 to add.
-     */
-    private void addAllRepeatedSint64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedSint64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedSint64_);
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     */
-    private void clearRepeatedSint64() {
-      repeatedSint64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_FIXED32_FIELD_NUMBER = 37;
-    private com.google.protobuf.Internal.IntList repeatedFixed32_;
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @return A list containing the repeatedFixed32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedFixed32List() {
-      return repeatedFixed32_;
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @return The count of repeatedFixed32.
-     */
-    @java.lang.Override
-    public int getRepeatedFixed32Count() {
-      return repeatedFixed32_.size();
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedFixed32(int index) {
-      return repeatedFixed32_.getInt(index);
-    }
-    private void ensureRepeatedFixed32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedFixed32_;
-      if (!tmp.isModifiable()) {
-        repeatedFixed32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed32 to set.
-     */
-    private void setRepeatedFixed32(
-        int index, int value) {
-      ensureRepeatedFixed32IsMutable();
-      repeatedFixed32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param value The repeatedFixed32 to add.
-     */
-    private void addRepeatedFixed32(int value) {
-      ensureRepeatedFixed32IsMutable();
-      repeatedFixed32_.addInt(value);
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param values The repeatedFixed32 to add.
-     */
-    private void addAllRepeatedFixed32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedFixed32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedFixed32_);
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     */
-    private void clearRepeatedFixed32() {
-      repeatedFixed32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_FIXED64_FIELD_NUMBER = 38;
-    private com.google.protobuf.Internal.LongList repeatedFixed64_;
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @return A list containing the repeatedFixed64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedFixed64List() {
-      return repeatedFixed64_;
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @return The count of repeatedFixed64.
-     */
-    @java.lang.Override
-    public int getRepeatedFixed64Count() {
-      return repeatedFixed64_.size();
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedFixed64(int index) {
-      return repeatedFixed64_.getLong(index);
-    }
-    private void ensureRepeatedFixed64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedFixed64_;
-      if (!tmp.isModifiable()) {
-        repeatedFixed64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed64 to set.
-     */
-    private void setRepeatedFixed64(
-        int index, long value) {
-      ensureRepeatedFixed64IsMutable();
-      repeatedFixed64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param value The repeatedFixed64 to add.
-     */
-    private void addRepeatedFixed64(long value) {
-      ensureRepeatedFixed64IsMutable();
-      repeatedFixed64_.addLong(value);
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param values The repeatedFixed64 to add.
-     */
-    private void addAllRepeatedFixed64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedFixed64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedFixed64_);
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     */
-    private void clearRepeatedFixed64() {
-      repeatedFixed64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_SFIXED32_FIELD_NUMBER = 39;
-    private com.google.protobuf.Internal.IntList repeatedSfixed32_;
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @return A list containing the repeatedSfixed32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedSfixed32List() {
-      return repeatedSfixed32_;
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @return The count of repeatedSfixed32.
-     */
-    @java.lang.Override
-    public int getRepeatedSfixed32Count() {
-      return repeatedSfixed32_.size();
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSfixed32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedSfixed32(int index) {
-      return repeatedSfixed32_.getInt(index);
-    }
-    private void ensureRepeatedSfixed32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedSfixed32_;
-      if (!tmp.isModifiable()) {
-        repeatedSfixed32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSfixed32 to set.
-     */
-    private void setRepeatedSfixed32(
-        int index, int value) {
-      ensureRepeatedSfixed32IsMutable();
-      repeatedSfixed32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param value The repeatedSfixed32 to add.
-     */
-    private void addRepeatedSfixed32(int value) {
-      ensureRepeatedSfixed32IsMutable();
-      repeatedSfixed32_.addInt(value);
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param values The repeatedSfixed32 to add.
-     */
-    private void addAllRepeatedSfixed32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedSfixed32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedSfixed32_);
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     */
-    private void clearRepeatedSfixed32() {
-      repeatedSfixed32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_SFIXED64_FIELD_NUMBER = 40;
-    private com.google.protobuf.Internal.LongList repeatedSfixed64_;
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @return A list containing the repeatedSfixed64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedSfixed64List() {
-      return repeatedSfixed64_;
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @return The count of repeatedSfixed64.
-     */
-    @java.lang.Override
-    public int getRepeatedSfixed64Count() {
-      return repeatedSfixed64_.size();
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSfixed64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedSfixed64(int index) {
-      return repeatedSfixed64_.getLong(index);
-    }
-    private void ensureRepeatedSfixed64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedSfixed64_;
-      if (!tmp.isModifiable()) {
-        repeatedSfixed64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSfixed64 to set.
-     */
-    private void setRepeatedSfixed64(
-        int index, long value) {
-      ensureRepeatedSfixed64IsMutable();
-      repeatedSfixed64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param value The repeatedSfixed64 to add.
-     */
-    private void addRepeatedSfixed64(long value) {
-      ensureRepeatedSfixed64IsMutable();
-      repeatedSfixed64_.addLong(value);
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param values The repeatedSfixed64 to add.
-     */
-    private void addAllRepeatedSfixed64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedSfixed64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedSfixed64_);
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     */
-    private void clearRepeatedSfixed64() {
-      repeatedSfixed64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_FLOAT_FIELD_NUMBER = 41;
-    private com.google.protobuf.Internal.FloatList repeatedFloat_;
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @return A list containing the repeatedFloat.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Float>
-        getRepeatedFloatList() {
-      return repeatedFloat_;
-    }
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @return The count of repeatedFloat.
-     */
-    @java.lang.Override
-    public int getRepeatedFloatCount() {
-      return repeatedFloat_.size();
-    }
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFloat at the given index.
-     */
-    @java.lang.Override
-    public float getRepeatedFloat(int index) {
-      return repeatedFloat_.getFloat(index);
-    }
-    private void ensureRepeatedFloatIsMutable() {
-      com.google.protobuf.Internal.FloatList tmp = repeatedFloat_;
-      if (!tmp.isModifiable()) {
-        repeatedFloat_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFloat to set.
-     */
-    private void setRepeatedFloat(
-        int index, float value) {
-      ensureRepeatedFloatIsMutable();
-      repeatedFloat_.setFloat(index, value);
-    }
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param value The repeatedFloat to add.
-     */
-    private void addRepeatedFloat(float value) {
-      ensureRepeatedFloatIsMutable();
-      repeatedFloat_.addFloat(value);
-    }
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param values The repeatedFloat to add.
-     */
-    private void addAllRepeatedFloat(
-        java.lang.Iterable<? extends java.lang.Float> values) {
-      ensureRepeatedFloatIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedFloat_);
-    }
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     */
-    private void clearRepeatedFloat() {
-      repeatedFloat_ = emptyFloatList();
-    }
-
-    public static final int REPEATED_DOUBLE_FIELD_NUMBER = 42;
-    private com.google.protobuf.Internal.DoubleList repeatedDouble_;
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @return A list containing the repeatedDouble.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Double>
-        getRepeatedDoubleList() {
-      return repeatedDouble_;
-    }
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @return The count of repeatedDouble.
-     */
-    @java.lang.Override
-    public int getRepeatedDoubleCount() {
-      return repeatedDouble_.size();
-    }
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedDouble at the given index.
-     */
-    @java.lang.Override
-    public double getRepeatedDouble(int index) {
-      return repeatedDouble_.getDouble(index);
-    }
-    private void ensureRepeatedDoubleIsMutable() {
-      com.google.protobuf.Internal.DoubleList tmp = repeatedDouble_;
-      if (!tmp.isModifiable()) {
-        repeatedDouble_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedDouble to set.
-     */
-    private void setRepeatedDouble(
-        int index, double value) {
-      ensureRepeatedDoubleIsMutable();
-      repeatedDouble_.setDouble(index, value);
-    }
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param value The repeatedDouble to add.
-     */
-    private void addRepeatedDouble(double value) {
-      ensureRepeatedDoubleIsMutable();
-      repeatedDouble_.addDouble(value);
-    }
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param values The repeatedDouble to add.
-     */
-    private void addAllRepeatedDouble(
-        java.lang.Iterable<? extends java.lang.Double> values) {
-      ensureRepeatedDoubleIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedDouble_);
-    }
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     */
-    private void clearRepeatedDouble() {
-      repeatedDouble_ = emptyDoubleList();
-    }
-
-    public static final int REPEATED_BOOL_FIELD_NUMBER = 43;
-    private com.google.protobuf.Internal.BooleanList repeatedBool_;
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @return A list containing the repeatedBool.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Boolean>
-        getRepeatedBoolList() {
-      return repeatedBool_;
-    }
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @return The count of repeatedBool.
-     */
-    @java.lang.Override
-    public int getRepeatedBoolCount() {
-      return repeatedBool_.size();
-    }
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedBool at the given index.
-     */
-    @java.lang.Override
-    public boolean getRepeatedBool(int index) {
-      return repeatedBool_.getBoolean(index);
-    }
-    private void ensureRepeatedBoolIsMutable() {
-      com.google.protobuf.Internal.BooleanList tmp = repeatedBool_;
-      if (!tmp.isModifiable()) {
-        repeatedBool_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedBool to set.
-     */
-    private void setRepeatedBool(
-        int index, boolean value) {
-      ensureRepeatedBoolIsMutable();
-      repeatedBool_.setBoolean(index, value);
-    }
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param value The repeatedBool to add.
-     */
-    private void addRepeatedBool(boolean value) {
-      ensureRepeatedBoolIsMutable();
-      repeatedBool_.addBoolean(value);
-    }
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param values The repeatedBool to add.
-     */
-    private void addAllRepeatedBool(
-        java.lang.Iterable<? extends java.lang.Boolean> values) {
-      ensureRepeatedBoolIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedBool_);
-    }
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     */
-    private void clearRepeatedBool() {
-      repeatedBool_ = emptyBooleanList();
-    }
-
-    public static final int REPEATED_STRING_FIELD_NUMBER = 44;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> repeatedString_;
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @return A list containing the repeatedString.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getRepeatedStringList() {
-      return repeatedString_;
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @return The count of repeatedString.
-     */
-    @java.lang.Override
-    public int getRepeatedStringCount() {
-      return repeatedString_.size();
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedString at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getRepeatedString(int index) {
-      return repeatedString_.get(index);
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the repeatedString at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getRepeatedStringBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          repeatedString_.get(index));
-    }
-    private void ensureRepeatedStringIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          repeatedString_;  if (!tmp.isModifiable()) {
-        repeatedString_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedString to set.
-     */
-    private void setRepeatedString(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureRepeatedStringIsMutable();
-      repeatedString_.set(index, value);
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param value The repeatedString to add.
-     */
-    private void addRepeatedString(
-        java.lang.String value) {
-      value.getClass();
-  ensureRepeatedStringIsMutable();
-      repeatedString_.add(value);
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param values The repeatedString to add.
-     */
-    private void addAllRepeatedString(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureRepeatedStringIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedString_);
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     */
-    private void clearRepeatedString() {
-      repeatedString_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param value The bytes of the repeatedString to add.
-     */
-    private void addRepeatedStringBytes(
-        com.google.protobuf.ByteString value) {
-      ensureRepeatedStringIsMutable();
-      repeatedString_.add(value.toStringUtf8());
-    }
-
-    public static final int REPEATED_BYTES_FIELD_NUMBER = 45;
-    private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.ByteString> repeatedBytes_;
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @return A list containing the repeatedBytes.
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.ByteString>
-        getRepeatedBytesList() {
-      return repeatedBytes_;
-    }
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @return The count of repeatedBytes.
-     */
-    @java.lang.Override
-    public int getRepeatedBytesCount() {
-      return repeatedBytes_.size();
-    }
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedBytes at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getRepeatedBytes(int index) {
-      return repeatedBytes_.get(index);
-    }
-    private void ensureRepeatedBytesIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<com.google.protobuf.ByteString> tmp = repeatedBytes_;
-      if (!tmp.isModifiable()) {
-        repeatedBytes_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedBytes to set.
-     */
-    private void setRepeatedBytes(
-        int index, com.google.protobuf.ByteString value) {
-      value.getClass();
-  ensureRepeatedBytesIsMutable();
-      repeatedBytes_.set(index, value);
-    }
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param value The repeatedBytes to add.
-     */
-    private void addRepeatedBytes(com.google.protobuf.ByteString value) {
-      value.getClass();
-  ensureRepeatedBytesIsMutable();
-      repeatedBytes_.add(value);
-    }
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param values The repeatedBytes to add.
-     */
-    private void addAllRepeatedBytes(
-        java.lang.Iterable<? extends com.google.protobuf.ByteString> values) {
-      ensureRepeatedBytesIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedBytes_);
-    }
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     */
-    private void clearRepeatedBytes() {
-      repeatedBytes_ = emptyProtobufList();
-    }
-
-    public static final int REPEATEDGROUP_FIELD_NUMBER = 46;
-    private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup> repeatedGroup_;
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup> getRepeatedGroupList() {
-      return repeatedGroup_;
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    public java.util.List<? extends com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroupOrBuilder> 
-        getRepeatedGroupOrBuilderList() {
-      return repeatedGroup_;
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    @java.lang.Override
-    public int getRepeatedGroupCount() {
-      return repeatedGroup_.size();
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup getRepeatedGroup(int index) {
-      return repeatedGroup_.get(index);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    public com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroupOrBuilder getRepeatedGroupOrBuilder(
-        int index) {
-      return repeatedGroup_.get(index);
-    }
-    private void ensureRepeatedGroupIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup> tmp = repeatedGroup_;
-      if (!tmp.isModifiable()) {
-        repeatedGroup_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    private void setRepeatedGroup(
-        int index, com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup value) {
-      value.getClass();
-  ensureRepeatedGroupIsMutable();
-      repeatedGroup_.set(index, value);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    private void addRepeatedGroup(com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup value) {
-      value.getClass();
-  ensureRepeatedGroupIsMutable();
-      repeatedGroup_.add(value);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    private void addRepeatedGroup(
-        int index, com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup value) {
-      value.getClass();
-  ensureRepeatedGroupIsMutable();
-      repeatedGroup_.add(index, value);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    private void addAllRepeatedGroup(
-        java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup> values) {
-      ensureRepeatedGroupIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedGroup_);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    private void clearRepeatedGroup() {
-      repeatedGroup_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    private void removeRepeatedGroup(int index) {
-      ensureRepeatedGroupIsMutable();
-      repeatedGroup_.remove(index);
-    }
-
-    public static final int REPEATED_NESTED_MESSAGE_FIELD_NUMBER = 48;
-    private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage> repeatedNestedMessage_;
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage> getRepeatedNestedMessageList() {
-      return repeatedNestedMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     */
-    public java.util.List<? extends com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessageOrBuilder> 
-        getRepeatedNestedMessageOrBuilderList() {
-      return repeatedNestedMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     */
-    @java.lang.Override
-    public int getRepeatedNestedMessageCount() {
-      return repeatedNestedMessage_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage getRepeatedNestedMessage(int index) {
-      return repeatedNestedMessage_.get(index);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     */
-    public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessageOrBuilder getRepeatedNestedMessageOrBuilder(
-        int index) {
-      return repeatedNestedMessage_.get(index);
-    }
-    private void ensureRepeatedNestedMessageIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage> tmp = repeatedNestedMessage_;
-      if (!tmp.isModifiable()) {
-        repeatedNestedMessage_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     */
-    private void setRepeatedNestedMessage(
-        int index, com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-      value.getClass();
-  ensureRepeatedNestedMessageIsMutable();
-      repeatedNestedMessage_.set(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     */
-    private void addRepeatedNestedMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-      value.getClass();
-  ensureRepeatedNestedMessageIsMutable();
-      repeatedNestedMessage_.add(value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     */
-    private void addRepeatedNestedMessage(
-        int index, com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-      value.getClass();
-  ensureRepeatedNestedMessageIsMutable();
-      repeatedNestedMessage_.add(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     */
-    private void addAllRepeatedNestedMessage(
-        java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage> values) {
-      ensureRepeatedNestedMessageIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedNestedMessage_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     */
-    private void clearRepeatedNestedMessage() {
-      repeatedNestedMessage_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-     */
-    private void removeRepeatedNestedMessage(int index) {
-      ensureRepeatedNestedMessageIsMutable();
-      repeatedNestedMessage_.remove(index);
-    }
-
-    public static final int REPEATED_FOREIGN_MESSAGE_FIELD_NUMBER = 49;
-    private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.ForeignMessageLite> repeatedForeignMessage_;
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.UnittestLite.ForeignMessageLite> getRepeatedForeignMessageList() {
-      return repeatedForeignMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     */
-    public java.util.List<? extends com.google.protobuf.UnittestLite.ForeignMessageLiteOrBuilder> 
-        getRepeatedForeignMessageOrBuilderList() {
-      return repeatedForeignMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     */
-    @java.lang.Override
-    public int getRepeatedForeignMessageCount() {
-      return repeatedForeignMessage_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.ForeignMessageLite getRepeatedForeignMessage(int index) {
-      return repeatedForeignMessage_.get(index);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     */
-    public com.google.protobuf.UnittestLite.ForeignMessageLiteOrBuilder getRepeatedForeignMessageOrBuilder(
-        int index) {
-      return repeatedForeignMessage_.get(index);
-    }
-    private void ensureRepeatedForeignMessageIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.ForeignMessageLite> tmp = repeatedForeignMessage_;
-      if (!tmp.isModifiable()) {
-        repeatedForeignMessage_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     */
-    private void setRepeatedForeignMessage(
-        int index, com.google.protobuf.UnittestLite.ForeignMessageLite value) {
-      value.getClass();
-  ensureRepeatedForeignMessageIsMutable();
-      repeatedForeignMessage_.set(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     */
-    private void addRepeatedForeignMessage(com.google.protobuf.UnittestLite.ForeignMessageLite value) {
-      value.getClass();
-  ensureRepeatedForeignMessageIsMutable();
-      repeatedForeignMessage_.add(value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     */
-    private void addRepeatedForeignMessage(
-        int index, com.google.protobuf.UnittestLite.ForeignMessageLite value) {
-      value.getClass();
-  ensureRepeatedForeignMessageIsMutable();
-      repeatedForeignMessage_.add(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     */
-    private void addAllRepeatedForeignMessage(
-        java.lang.Iterable<? extends com.google.protobuf.UnittestLite.ForeignMessageLite> values) {
-      ensureRepeatedForeignMessageIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedForeignMessage_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     */
-    private void clearRepeatedForeignMessage() {
-      repeatedForeignMessage_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-     */
-    private void removeRepeatedForeignMessage(int index) {
-      ensureRepeatedForeignMessageIsMutable();
-      repeatedForeignMessage_.remove(index);
-    }
-
-    public static final int REPEATED_IMPORT_MESSAGE_FIELD_NUMBER = 50;
-    private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestImportLite.ImportMessageLite> repeatedImportMessage_;
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.UnittestImportLite.ImportMessageLite> getRepeatedImportMessageList() {
-      return repeatedImportMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     */
-    public java.util.List<? extends com.google.protobuf.UnittestImportLite.ImportMessageLiteOrBuilder> 
-        getRepeatedImportMessageOrBuilderList() {
-      return repeatedImportMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     */
-    @java.lang.Override
-    public int getRepeatedImportMessageCount() {
-      return repeatedImportMessage_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestImportLite.ImportMessageLite getRepeatedImportMessage(int index) {
-      return repeatedImportMessage_.get(index);
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     */
-    public com.google.protobuf.UnittestImportLite.ImportMessageLiteOrBuilder getRepeatedImportMessageOrBuilder(
-        int index) {
-      return repeatedImportMessage_.get(index);
-    }
-    private void ensureRepeatedImportMessageIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestImportLite.ImportMessageLite> tmp = repeatedImportMessage_;
-      if (!tmp.isModifiable()) {
-        repeatedImportMessage_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     */
-    private void setRepeatedImportMessage(
-        int index, com.google.protobuf.UnittestImportLite.ImportMessageLite value) {
-      value.getClass();
-  ensureRepeatedImportMessageIsMutable();
-      repeatedImportMessage_.set(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     */
-    private void addRepeatedImportMessage(com.google.protobuf.UnittestImportLite.ImportMessageLite value) {
-      value.getClass();
-  ensureRepeatedImportMessageIsMutable();
-      repeatedImportMessage_.add(value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     */
-    private void addRepeatedImportMessage(
-        int index, com.google.protobuf.UnittestImportLite.ImportMessageLite value) {
-      value.getClass();
-  ensureRepeatedImportMessageIsMutable();
-      repeatedImportMessage_.add(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     */
-    private void addAllRepeatedImportMessage(
-        java.lang.Iterable<? extends com.google.protobuf.UnittestImportLite.ImportMessageLite> values) {
-      ensureRepeatedImportMessageIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedImportMessage_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     */
-    private void clearRepeatedImportMessage() {
-      repeatedImportMessage_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-     */
-    private void removeRepeatedImportMessage(int index) {
-      ensureRepeatedImportMessageIsMutable();
-      repeatedImportMessage_.remove(index);
-    }
-
-    public static final int REPEATED_NESTED_ENUM_FIELD_NUMBER = 51;
-    private com.google.protobuf.Internal.IntList repeatedNestedEnum_;
-    private static final com.google.protobuf.Internal.ListAdapter.Converter<
-        java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum> repeatedNestedEnum_converter_ =
-            new com.google.protobuf.Internal.ListAdapter.Converter<
-                java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum>() {
-              @java.lang.Override
-              public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum convert(java.lang.Integer from) {
-                com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum result = com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum.forNumber(from);
-                return result == null ? com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum.FOO : result;
-              }
-            };
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-     * @return A list containing the repeatedNestedEnum.
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum> getRepeatedNestedEnumList() {
-      return new com.google.protobuf.Internal.ListAdapter<
-          java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum>(repeatedNestedEnum_, repeatedNestedEnum_converter_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-     * @return The count of repeatedNestedEnum.
-     */
-    @java.lang.Override
-    public int getRepeatedNestedEnumCount() {
-      return repeatedNestedEnum_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedNestedEnum at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum getRepeatedNestedEnum(int index) {
-      return repeatedNestedEnum_converter_.convert(repeatedNestedEnum_.getInt(index));
-    }
-    private void ensureRepeatedNestedEnumIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedNestedEnum_;
-      if (!tmp.isModifiable()) {
-        repeatedNestedEnum_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedNestedEnum to set.
-     */
-    private void setRepeatedNestedEnum(
-        int index, com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum value) {
-      value.getClass();
-  ensureRepeatedNestedEnumIsMutable();
-      repeatedNestedEnum_.setInt(index, value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-     * @param value The repeatedNestedEnum to add.
-     */
-    private void addRepeatedNestedEnum(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum value) {
-      value.getClass();
-  ensureRepeatedNestedEnumIsMutable();
-      repeatedNestedEnum_.addInt(value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-     * @param values The repeatedNestedEnum to add.
-     */
-    private void addAllRepeatedNestedEnum(
-        java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum> values) {
-      ensureRepeatedNestedEnumIsMutable();
-      for (com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum value : values) {
-        repeatedNestedEnum_.addInt(value.getNumber());
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-     */
-    private void clearRepeatedNestedEnum() {
-      repeatedNestedEnum_ = emptyIntList();
-    }
-
-    public static final int REPEATED_FOREIGN_ENUM_FIELD_NUMBER = 52;
-    private com.google.protobuf.Internal.IntList repeatedForeignEnum_;
-    private static final com.google.protobuf.Internal.ListAdapter.Converter<
-        java.lang.Integer, com.google.protobuf.UnittestLite.ForeignEnumLite> repeatedForeignEnum_converter_ =
-            new com.google.protobuf.Internal.ListAdapter.Converter<
-                java.lang.Integer, com.google.protobuf.UnittestLite.ForeignEnumLite>() {
-              @java.lang.Override
-              public com.google.protobuf.UnittestLite.ForeignEnumLite convert(java.lang.Integer from) {
-                com.google.protobuf.UnittestLite.ForeignEnumLite result = com.google.protobuf.UnittestLite.ForeignEnumLite.forNumber(from);
-                return result == null ? com.google.protobuf.UnittestLite.ForeignEnumLite.FOREIGN_LITE_FOO : result;
-              }
-            };
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-     * @return A list containing the repeatedForeignEnum.
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.UnittestLite.ForeignEnumLite> getRepeatedForeignEnumList() {
-      return new com.google.protobuf.Internal.ListAdapter<
-          java.lang.Integer, com.google.protobuf.UnittestLite.ForeignEnumLite>(repeatedForeignEnum_, repeatedForeignEnum_converter_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-     * @return The count of repeatedForeignEnum.
-     */
-    @java.lang.Override
-    public int getRepeatedForeignEnumCount() {
-      return repeatedForeignEnum_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedForeignEnum at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.ForeignEnumLite getRepeatedForeignEnum(int index) {
-      return repeatedForeignEnum_converter_.convert(repeatedForeignEnum_.getInt(index));
-    }
-    private void ensureRepeatedForeignEnumIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedForeignEnum_;
-      if (!tmp.isModifiable()) {
-        repeatedForeignEnum_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedForeignEnum to set.
-     */
-    private void setRepeatedForeignEnum(
-        int index, com.google.protobuf.UnittestLite.ForeignEnumLite value) {
-      value.getClass();
-  ensureRepeatedForeignEnumIsMutable();
-      repeatedForeignEnum_.setInt(index, value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-     * @param value The repeatedForeignEnum to add.
-     */
-    private void addRepeatedForeignEnum(com.google.protobuf.UnittestLite.ForeignEnumLite value) {
-      value.getClass();
-  ensureRepeatedForeignEnumIsMutable();
-      repeatedForeignEnum_.addInt(value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-     * @param values The repeatedForeignEnum to add.
-     */
-    private void addAllRepeatedForeignEnum(
-        java.lang.Iterable<? extends com.google.protobuf.UnittestLite.ForeignEnumLite> values) {
-      ensureRepeatedForeignEnumIsMutable();
-      for (com.google.protobuf.UnittestLite.ForeignEnumLite value : values) {
-        repeatedForeignEnum_.addInt(value.getNumber());
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-     */
-    private void clearRepeatedForeignEnum() {
-      repeatedForeignEnum_ = emptyIntList();
-    }
-
-    public static final int REPEATED_IMPORT_ENUM_FIELD_NUMBER = 53;
-    private com.google.protobuf.Internal.IntList repeatedImportEnum_;
-    private static final com.google.protobuf.Internal.ListAdapter.Converter<
-        java.lang.Integer, com.google.protobuf.UnittestImportLite.ImportEnumLite> repeatedImportEnum_converter_ =
-            new com.google.protobuf.Internal.ListAdapter.Converter<
-                java.lang.Integer, com.google.protobuf.UnittestImportLite.ImportEnumLite>() {
-              @java.lang.Override
-              public com.google.protobuf.UnittestImportLite.ImportEnumLite convert(java.lang.Integer from) {
-                com.google.protobuf.UnittestImportLite.ImportEnumLite result = com.google.protobuf.UnittestImportLite.ImportEnumLite.forNumber(from);
-                return result == null ? com.google.protobuf.UnittestImportLite.ImportEnumLite.IMPORT_LITE_FOO : result;
-              }
-            };
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-     * @return A list containing the repeatedImportEnum.
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.UnittestImportLite.ImportEnumLite> getRepeatedImportEnumList() {
-      return new com.google.protobuf.Internal.ListAdapter<
-          java.lang.Integer, com.google.protobuf.UnittestImportLite.ImportEnumLite>(repeatedImportEnum_, repeatedImportEnum_converter_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-     * @return The count of repeatedImportEnum.
-     */
-    @java.lang.Override
-    public int getRepeatedImportEnumCount() {
-      return repeatedImportEnum_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedImportEnum at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestImportLite.ImportEnumLite getRepeatedImportEnum(int index) {
-      return repeatedImportEnum_converter_.convert(repeatedImportEnum_.getInt(index));
-    }
-    private void ensureRepeatedImportEnumIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedImportEnum_;
-      if (!tmp.isModifiable()) {
-        repeatedImportEnum_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedImportEnum to set.
-     */
-    private void setRepeatedImportEnum(
-        int index, com.google.protobuf.UnittestImportLite.ImportEnumLite value) {
-      value.getClass();
-  ensureRepeatedImportEnumIsMutable();
-      repeatedImportEnum_.setInt(index, value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-     * @param value The repeatedImportEnum to add.
-     */
-    private void addRepeatedImportEnum(com.google.protobuf.UnittestImportLite.ImportEnumLite value) {
-      value.getClass();
-  ensureRepeatedImportEnumIsMutable();
-      repeatedImportEnum_.addInt(value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-     * @param values The repeatedImportEnum to add.
-     */
-    private void addAllRepeatedImportEnum(
-        java.lang.Iterable<? extends com.google.protobuf.UnittestImportLite.ImportEnumLite> values) {
-      ensureRepeatedImportEnumIsMutable();
-      for (com.google.protobuf.UnittestImportLite.ImportEnumLite value : values) {
-        repeatedImportEnum_.addInt(value.getNumber());
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-     */
-    private void clearRepeatedImportEnum() {
-      repeatedImportEnum_ = emptyIntList();
-    }
-
-    public static final int REPEATED_STRING_PIECE_FIELD_NUMBER = 54;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> repeatedStringPiece_;
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @return A list containing the repeatedStringPiece.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getRepeatedStringPieceList() {
-      return repeatedStringPiece_;
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @return The count of repeatedStringPiece.
-     */
-    @java.lang.Override
-    public int getRepeatedStringPieceCount() {
-      return repeatedStringPiece_.size();
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedStringPiece at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getRepeatedStringPiece(int index) {
-      return repeatedStringPiece_.get(index);
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the repeatedStringPiece at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getRepeatedStringPieceBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          repeatedStringPiece_.get(index));
-    }
-    private void ensureRepeatedStringPieceIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          repeatedStringPiece_;  if (!tmp.isModifiable()) {
-        repeatedStringPiece_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedStringPiece to set.
-     */
-    private void setRepeatedStringPiece(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureRepeatedStringPieceIsMutable();
-      repeatedStringPiece_.set(index, value);
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param value The repeatedStringPiece to add.
-     */
-    private void addRepeatedStringPiece(
-        java.lang.String value) {
-      value.getClass();
-  ensureRepeatedStringPieceIsMutable();
-      repeatedStringPiece_.add(value);
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param values The repeatedStringPiece to add.
-     */
-    private void addAllRepeatedStringPiece(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureRepeatedStringPieceIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedStringPiece_);
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     */
-    private void clearRepeatedStringPiece() {
-      repeatedStringPiece_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param value The bytes of the repeatedStringPiece to add.
-     */
-    private void addRepeatedStringPieceBytes(
-        com.google.protobuf.ByteString value) {
-      ensureRepeatedStringPieceIsMutable();
-      repeatedStringPiece_.add(value.toStringUtf8());
-    }
-
-    public static final int REPEATED_CORD_FIELD_NUMBER = 55;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> repeatedCord_;
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @return A list containing the repeatedCord.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getRepeatedCordList() {
-      return repeatedCord_;
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @return The count of repeatedCord.
-     */
-    @java.lang.Override
-    public int getRepeatedCordCount() {
-      return repeatedCord_.size();
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedCord at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getRepeatedCord(int index) {
-      return repeatedCord_.get(index);
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the repeatedCord at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getRepeatedCordBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          repeatedCord_.get(index));
-    }
-    private void ensureRepeatedCordIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          repeatedCord_;  if (!tmp.isModifiable()) {
-        repeatedCord_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedCord to set.
-     */
-    private void setRepeatedCord(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureRepeatedCordIsMutable();
-      repeatedCord_.set(index, value);
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param value The repeatedCord to add.
-     */
-    private void addRepeatedCord(
-        java.lang.String value) {
-      value.getClass();
-  ensureRepeatedCordIsMutable();
-      repeatedCord_.add(value);
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param values The repeatedCord to add.
-     */
-    private void addAllRepeatedCord(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureRepeatedCordIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedCord_);
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     */
-    private void clearRepeatedCord() {
-      repeatedCord_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param value The bytes of the repeatedCord to add.
-     */
-    private void addRepeatedCordBytes(
-        com.google.protobuf.ByteString value) {
-      ensureRepeatedCordIsMutable();
-      repeatedCord_.add(value.toStringUtf8());
-    }
-
-    public static final int REPEATED_LAZY_MESSAGE_FIELD_NUMBER = 57;
-    private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage> repeatedLazyMessage_;
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage> getRepeatedLazyMessageList() {
-      return repeatedLazyMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    public java.util.List<? extends com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessageOrBuilder> 
-        getRepeatedLazyMessageOrBuilderList() {
-      return repeatedLazyMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public int getRepeatedLazyMessageCount() {
-      return repeatedLazyMessage_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage getRepeatedLazyMessage(int index) {
-      return repeatedLazyMessage_.get(index);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessageOrBuilder getRepeatedLazyMessageOrBuilder(
-        int index) {
-      return repeatedLazyMessage_.get(index);
-    }
-    private void ensureRepeatedLazyMessageIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage> tmp = repeatedLazyMessage_;
-      if (!tmp.isModifiable()) {
-        repeatedLazyMessage_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    private void setRepeatedLazyMessage(
-        int index, com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-      value.getClass();
-  ensureRepeatedLazyMessageIsMutable();
-      repeatedLazyMessage_.set(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    private void addRepeatedLazyMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-      value.getClass();
-  ensureRepeatedLazyMessageIsMutable();
-      repeatedLazyMessage_.add(value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    private void addRepeatedLazyMessage(
-        int index, com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-      value.getClass();
-  ensureRepeatedLazyMessageIsMutable();
-      repeatedLazyMessage_.add(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    private void addAllRepeatedLazyMessage(
-        java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage> values) {
-      ensureRepeatedLazyMessageIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedLazyMessage_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    private void clearRepeatedLazyMessage() {
-      repeatedLazyMessage_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    private void removeRepeatedLazyMessage(int index) {
-      ensureRepeatedLazyMessageIsMutable();
-      repeatedLazyMessage_.remove(index);
-    }
-
-    public static final int DEFAULT_INT32_FIELD_NUMBER = 61;
-    private int defaultInt32_;
-    /**
-     * <pre>
-     * Singular with defaults
-     * </pre>
-     *
-     * <code>optional int32 default_int32 = 61 [default = 41];</code>
-     * @return Whether the defaultInt32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultInt32() {
-      return ((bitField0_ & 0x04000000) != 0);
-    }
-    /**
-     * <pre>
-     * Singular with defaults
-     * </pre>
-     *
-     * <code>optional int32 default_int32 = 61 [default = 41];</code>
-     * @return The defaultInt32.
-     */
-    @java.lang.Override
-    public int getDefaultInt32() {
-      return defaultInt32_;
-    }
-    /**
-     * <pre>
-     * Singular with defaults
-     * </pre>
-     *
-     * <code>optional int32 default_int32 = 61 [default = 41];</code>
-     * @param value The defaultInt32 to set.
-     */
-    private void setDefaultInt32(int value) {
-      bitField0_ |= 0x04000000;
-      defaultInt32_ = value;
-    }
-    /**
-     * <pre>
-     * Singular with defaults
-     * </pre>
-     *
-     * <code>optional int32 default_int32 = 61 [default = 41];</code>
-     */
-    private void clearDefaultInt32() {
-      bitField0_ = (bitField0_ & ~0x04000000);
-      defaultInt32_ = 41;
-    }
-
-    public static final int DEFAULT_INT64_FIELD_NUMBER = 62;
-    private long defaultInt64_;
-    /**
-     * <code>optional int64 default_int64 = 62 [default = 42];</code>
-     * @return Whether the defaultInt64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultInt64() {
-      return ((bitField0_ & 0x08000000) != 0);
-    }
-    /**
-     * <code>optional int64 default_int64 = 62 [default = 42];</code>
-     * @return The defaultInt64.
-     */
-    @java.lang.Override
-    public long getDefaultInt64() {
-      return defaultInt64_;
-    }
-    /**
-     * <code>optional int64 default_int64 = 62 [default = 42];</code>
-     * @param value The defaultInt64 to set.
-     */
-    private void setDefaultInt64(long value) {
-      bitField0_ |= 0x08000000;
-      defaultInt64_ = value;
-    }
-    /**
-     * <code>optional int64 default_int64 = 62 [default = 42];</code>
-     */
-    private void clearDefaultInt64() {
-      bitField0_ = (bitField0_ & ~0x08000000);
-      defaultInt64_ = 42L;
-    }
-
-    public static final int DEFAULT_UINT32_FIELD_NUMBER = 63;
-    private int defaultUint32_;
-    /**
-     * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-     * @return Whether the defaultUint32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultUint32() {
-      return ((bitField0_ & 0x10000000) != 0);
-    }
-    /**
-     * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-     * @return The defaultUint32.
-     */
-    @java.lang.Override
-    public int getDefaultUint32() {
-      return defaultUint32_;
-    }
-    /**
-     * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-     * @param value The defaultUint32 to set.
-     */
-    private void setDefaultUint32(int value) {
-      bitField0_ |= 0x10000000;
-      defaultUint32_ = value;
-    }
-    /**
-     * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-     */
-    private void clearDefaultUint32() {
-      bitField0_ = (bitField0_ & ~0x10000000);
-      defaultUint32_ = 43;
-    }
-
-    public static final int DEFAULT_UINT64_FIELD_NUMBER = 64;
-    private long defaultUint64_;
-    /**
-     * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-     * @return Whether the defaultUint64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultUint64() {
-      return ((bitField0_ & 0x20000000) != 0);
-    }
-    /**
-     * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-     * @return The defaultUint64.
-     */
-    @java.lang.Override
-    public long getDefaultUint64() {
-      return defaultUint64_;
-    }
-    /**
-     * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-     * @param value The defaultUint64 to set.
-     */
-    private void setDefaultUint64(long value) {
-      bitField0_ |= 0x20000000;
-      defaultUint64_ = value;
-    }
-    /**
-     * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-     */
-    private void clearDefaultUint64() {
-      bitField0_ = (bitField0_ & ~0x20000000);
-      defaultUint64_ = 44L;
-    }
-
-    public static final int DEFAULT_SINT32_FIELD_NUMBER = 65;
-    private int defaultSint32_;
-    /**
-     * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-     * @return Whether the defaultSint32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultSint32() {
-      return ((bitField0_ & 0x40000000) != 0);
-    }
-    /**
-     * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-     * @return The defaultSint32.
-     */
-    @java.lang.Override
-    public int getDefaultSint32() {
-      return defaultSint32_;
-    }
-    /**
-     * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-     * @param value The defaultSint32 to set.
-     */
-    private void setDefaultSint32(int value) {
-      bitField0_ |= 0x40000000;
-      defaultSint32_ = value;
-    }
-    /**
-     * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-     */
-    private void clearDefaultSint32() {
-      bitField0_ = (bitField0_ & ~0x40000000);
-      defaultSint32_ = -45;
-    }
-
-    public static final int DEFAULT_SINT64_FIELD_NUMBER = 66;
-    private long defaultSint64_;
-    /**
-     * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-     * @return Whether the defaultSint64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultSint64() {
-      return ((bitField0_ & 0x80000000) != 0);
-    }
-    /**
-     * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-     * @return The defaultSint64.
-     */
-    @java.lang.Override
-    public long getDefaultSint64() {
-      return defaultSint64_;
-    }
-    /**
-     * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-     * @param value The defaultSint64 to set.
-     */
-    private void setDefaultSint64(long value) {
-      bitField0_ |= 0x80000000;
-      defaultSint64_ = value;
-    }
-    /**
-     * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-     */
-    private void clearDefaultSint64() {
-      bitField0_ = (bitField0_ & ~0x80000000);
-      defaultSint64_ = 46L;
-    }
-
-    public static final int DEFAULT_FIXED32_FIELD_NUMBER = 67;
-    private int defaultFixed32_;
-    /**
-     * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-     * @return Whether the defaultFixed32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultFixed32() {
-      return ((bitField1_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-     * @return The defaultFixed32.
-     */
-    @java.lang.Override
-    public int getDefaultFixed32() {
-      return defaultFixed32_;
-    }
-    /**
-     * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-     * @param value The defaultFixed32 to set.
-     */
-    private void setDefaultFixed32(int value) {
-      bitField1_ |= 0x00000001;
-      defaultFixed32_ = value;
-    }
-    /**
-     * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-     */
-    private void clearDefaultFixed32() {
-      bitField1_ = (bitField1_ & ~0x00000001);
-      defaultFixed32_ = 47;
-    }
-
-    public static final int DEFAULT_FIXED64_FIELD_NUMBER = 68;
-    private long defaultFixed64_;
-    /**
-     * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-     * @return Whether the defaultFixed64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultFixed64() {
-      return ((bitField1_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-     * @return The defaultFixed64.
-     */
-    @java.lang.Override
-    public long getDefaultFixed64() {
-      return defaultFixed64_;
-    }
-    /**
-     * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-     * @param value The defaultFixed64 to set.
-     */
-    private void setDefaultFixed64(long value) {
-      bitField1_ |= 0x00000002;
-      defaultFixed64_ = value;
-    }
-    /**
-     * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-     */
-    private void clearDefaultFixed64() {
-      bitField1_ = (bitField1_ & ~0x00000002);
-      defaultFixed64_ = 48L;
-    }
-
-    public static final int DEFAULT_SFIXED32_FIELD_NUMBER = 69;
-    private int defaultSfixed32_;
-    /**
-     * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-     * @return Whether the defaultSfixed32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultSfixed32() {
-      return ((bitField1_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-     * @return The defaultSfixed32.
-     */
-    @java.lang.Override
-    public int getDefaultSfixed32() {
-      return defaultSfixed32_;
-    }
-    /**
-     * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-     * @param value The defaultSfixed32 to set.
-     */
-    private void setDefaultSfixed32(int value) {
-      bitField1_ |= 0x00000004;
-      defaultSfixed32_ = value;
-    }
-    /**
-     * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-     */
-    private void clearDefaultSfixed32() {
-      bitField1_ = (bitField1_ & ~0x00000004);
-      defaultSfixed32_ = 49;
-    }
-
-    public static final int DEFAULT_SFIXED64_FIELD_NUMBER = 70;
-    private long defaultSfixed64_;
-    /**
-     * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-     * @return Whether the defaultSfixed64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultSfixed64() {
-      return ((bitField1_ & 0x00000008) != 0);
-    }
-    /**
-     * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-     * @return The defaultSfixed64.
-     */
-    @java.lang.Override
-    public long getDefaultSfixed64() {
-      return defaultSfixed64_;
-    }
-    /**
-     * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-     * @param value The defaultSfixed64 to set.
-     */
-    private void setDefaultSfixed64(long value) {
-      bitField1_ |= 0x00000008;
-      defaultSfixed64_ = value;
-    }
-    /**
-     * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-     */
-    private void clearDefaultSfixed64() {
-      bitField1_ = (bitField1_ & ~0x00000008);
-      defaultSfixed64_ = -50L;
-    }
-
-    public static final int DEFAULT_FLOAT_FIELD_NUMBER = 71;
-    private float defaultFloat_;
-    /**
-     * <code>optional float default_float = 71 [default = 51.5];</code>
-     * @return Whether the defaultFloat field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultFloat() {
-      return ((bitField1_ & 0x00000010) != 0);
-    }
-    /**
-     * <code>optional float default_float = 71 [default = 51.5];</code>
-     * @return The defaultFloat.
-     */
-    @java.lang.Override
-    public float getDefaultFloat() {
-      return defaultFloat_;
-    }
-    /**
-     * <code>optional float default_float = 71 [default = 51.5];</code>
-     * @param value The defaultFloat to set.
-     */
-    private void setDefaultFloat(float value) {
-      bitField1_ |= 0x00000010;
-      defaultFloat_ = value;
-    }
-    /**
-     * <code>optional float default_float = 71 [default = 51.5];</code>
-     */
-    private void clearDefaultFloat() {
-      bitField1_ = (bitField1_ & ~0x00000010);
-      defaultFloat_ = 51.5F;
-    }
-
-    public static final int DEFAULT_DOUBLE_FIELD_NUMBER = 72;
-    private double defaultDouble_;
-    /**
-     * <code>optional double default_double = 72 [default = 52000];</code>
-     * @return Whether the defaultDouble field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultDouble() {
-      return ((bitField1_ & 0x00000020) != 0);
-    }
-    /**
-     * <code>optional double default_double = 72 [default = 52000];</code>
-     * @return The defaultDouble.
-     */
-    @java.lang.Override
-    public double getDefaultDouble() {
-      return defaultDouble_;
-    }
-    /**
-     * <code>optional double default_double = 72 [default = 52000];</code>
-     * @param value The defaultDouble to set.
-     */
-    private void setDefaultDouble(double value) {
-      bitField1_ |= 0x00000020;
-      defaultDouble_ = value;
-    }
-    /**
-     * <code>optional double default_double = 72 [default = 52000];</code>
-     */
-    private void clearDefaultDouble() {
-      bitField1_ = (bitField1_ & ~0x00000020);
-      defaultDouble_ = 52000D;
-    }
-
-    public static final int DEFAULT_BOOL_FIELD_NUMBER = 73;
-    private boolean defaultBool_;
-    /**
-     * <code>optional bool default_bool = 73 [default = true];</code>
-     * @return Whether the defaultBool field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultBool() {
-      return ((bitField1_ & 0x00000040) != 0);
-    }
-    /**
-     * <code>optional bool default_bool = 73 [default = true];</code>
-     * @return The defaultBool.
-     */
-    @java.lang.Override
-    public boolean getDefaultBool() {
-      return defaultBool_;
-    }
-    /**
-     * <code>optional bool default_bool = 73 [default = true];</code>
-     * @param value The defaultBool to set.
-     */
-    private void setDefaultBool(boolean value) {
-      bitField1_ |= 0x00000040;
-      defaultBool_ = value;
-    }
-    /**
-     * <code>optional bool default_bool = 73 [default = true];</code>
-     */
-    private void clearDefaultBool() {
-      bitField1_ = (bitField1_ & ~0x00000040);
-      defaultBool_ = true;
-    }
-
-    public static final int DEFAULT_STRING_FIELD_NUMBER = 74;
-    private java.lang.String defaultString_;
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     * @return Whether the defaultString field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultString() {
-      return ((bitField1_ & 0x00000080) != 0);
-    }
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     * @return The defaultString.
-     */
-    @java.lang.Override
-    public java.lang.String getDefaultString() {
-      return defaultString_;
-    }
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     * @return The bytes for defaultString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getDefaultStringBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(defaultString_);
-    }
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     * @param value The defaultString to set.
-     */
-    private void setDefaultString(
-        java.lang.String value) {
-      value.getClass();
-  bitField1_ |= 0x00000080;
-      defaultString_ = value;
-    }
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     */
-    private void clearDefaultString() {
-      bitField1_ = (bitField1_ & ~0x00000080);
-      defaultString_ = getDefaultInstance().getDefaultString();
-    }
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     * @param value The bytes for defaultString to set.
-     */
-    private void setDefaultStringBytes(
-        com.google.protobuf.ByteString value) {
-      defaultString_ = value.toStringUtf8();
-      bitField1_ |= 0x00000080;
-    }
-
-    public static final int DEFAULT_BYTES_FIELD_NUMBER = 75;
-    private static final com.google.protobuf.ByteString DEFAULTBYTES_DEFAULT_VALUE = com.google.protobuf.Internal.bytesDefaultValue("world");
-    private com.google.protobuf.ByteString defaultBytes_;
-    /**
-     * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-     * @return Whether the defaultBytes field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultBytes() {
-      return ((bitField1_ & 0x00000100) != 0);
-    }
-    /**
-     * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-     * @return The defaultBytes.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getDefaultBytes() {
-      return defaultBytes_;
-    }
-    /**
-     * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-     * @param value The defaultBytes to set.
-     */
-    private void setDefaultBytes(com.google.protobuf.ByteString value) {
-      value.getClass();
-  bitField1_ |= 0x00000100;
-      defaultBytes_ = value;
-    }
-    /**
-     * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-     */
-    private void clearDefaultBytes() {
-      bitField1_ = (bitField1_ & ~0x00000100);
-      defaultBytes_ = getDefaultInstance().getDefaultBytes();
-    }
-
-    public static final int DEFAULT_NESTED_ENUM_FIELD_NUMBER = 81;
-    private int defaultNestedEnum_;
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-     * @return Whether the defaultNestedEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultNestedEnum() {
-      return ((bitField1_ & 0x00000200) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-     * @return The defaultNestedEnum.
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum getDefaultNestedEnum() {
-      com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum result = com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum.forNumber(defaultNestedEnum_);
-      return result == null ? com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum.BAR : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-     * @param value The defaultNestedEnum to set.
-     */
-    private void setDefaultNestedEnum(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum value) {
-      defaultNestedEnum_ = value.getNumber();
-      bitField1_ |= 0x00000200;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-     */
-    private void clearDefaultNestedEnum() {
-      bitField1_ = (bitField1_ & ~0x00000200);
-      defaultNestedEnum_ = 2;
-    }
-
-    public static final int DEFAULT_FOREIGN_ENUM_FIELD_NUMBER = 82;
-    private int defaultForeignEnum_;
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite default_foreign_enum = 82 [default = FOREIGN_LITE_BAR];</code>
-     * @return Whether the defaultForeignEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultForeignEnum() {
-      return ((bitField1_ & 0x00000400) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite default_foreign_enum = 82 [default = FOREIGN_LITE_BAR];</code>
-     * @return The defaultForeignEnum.
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.ForeignEnumLite getDefaultForeignEnum() {
-      com.google.protobuf.UnittestLite.ForeignEnumLite result = com.google.protobuf.UnittestLite.ForeignEnumLite.forNumber(defaultForeignEnum_);
-      return result == null ? com.google.protobuf.UnittestLite.ForeignEnumLite.FOREIGN_LITE_BAR : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite default_foreign_enum = 82 [default = FOREIGN_LITE_BAR];</code>
-     * @param value The defaultForeignEnum to set.
-     */
-    private void setDefaultForeignEnum(com.google.protobuf.UnittestLite.ForeignEnumLite value) {
-      defaultForeignEnum_ = value.getNumber();
-      bitField1_ |= 0x00000400;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite default_foreign_enum = 82 [default = FOREIGN_LITE_BAR];</code>
-     */
-    private void clearDefaultForeignEnum() {
-      bitField1_ = (bitField1_ & ~0x00000400);
-      defaultForeignEnum_ = 5;
-    }
-
-    public static final int DEFAULT_IMPORT_ENUM_FIELD_NUMBER = 83;
-    private int defaultImportEnum_;
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnumLite default_import_enum = 83 [default = IMPORT_LITE_BAR];</code>
-     * @return Whether the defaultImportEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultImportEnum() {
-      return ((bitField1_ & 0x00000800) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnumLite default_import_enum = 83 [default = IMPORT_LITE_BAR];</code>
-     * @return The defaultImportEnum.
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestImportLite.ImportEnumLite getDefaultImportEnum() {
-      com.google.protobuf.UnittestImportLite.ImportEnumLite result = com.google.protobuf.UnittestImportLite.ImportEnumLite.forNumber(defaultImportEnum_);
-      return result == null ? com.google.protobuf.UnittestImportLite.ImportEnumLite.IMPORT_LITE_BAR : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnumLite default_import_enum = 83 [default = IMPORT_LITE_BAR];</code>
-     * @param value The defaultImportEnum to set.
-     */
-    private void setDefaultImportEnum(com.google.protobuf.UnittestImportLite.ImportEnumLite value) {
-      defaultImportEnum_ = value.getNumber();
-      bitField1_ |= 0x00000800;
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnumLite default_import_enum = 83 [default = IMPORT_LITE_BAR];</code>
-     */
-    private void clearDefaultImportEnum() {
-      bitField1_ = (bitField1_ & ~0x00000800);
-      defaultImportEnum_ = 8;
-    }
-
-    public static final int DEFAULT_STRING_PIECE_FIELD_NUMBER = 84;
-    private java.lang.String defaultStringPiece_;
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     * @return Whether the defaultStringPiece field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultStringPiece() {
-      return ((bitField1_ & 0x00001000) != 0);
-    }
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     * @return The defaultStringPiece.
-     */
-    @java.lang.Override
-    public java.lang.String getDefaultStringPiece() {
-      return defaultStringPiece_;
-    }
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     * @return The bytes for defaultStringPiece.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getDefaultStringPieceBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(defaultStringPiece_);
-    }
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     * @param value The defaultStringPiece to set.
-     */
-    private void setDefaultStringPiece(
-        java.lang.String value) {
-      value.getClass();
-  bitField1_ |= 0x00001000;
-      defaultStringPiece_ = value;
-    }
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     */
-    private void clearDefaultStringPiece() {
-      bitField1_ = (bitField1_ & ~0x00001000);
-      defaultStringPiece_ = getDefaultInstance().getDefaultStringPiece();
-    }
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     * @param value The bytes for defaultStringPiece to set.
-     */
-    private void setDefaultStringPieceBytes(
-        com.google.protobuf.ByteString value) {
-      defaultStringPiece_ = value.toStringUtf8();
-      bitField1_ |= 0x00001000;
-    }
-
-    public static final int DEFAULT_CORD_FIELD_NUMBER = 85;
-    private java.lang.String defaultCord_;
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     * @return Whether the defaultCord field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultCord() {
-      return ((bitField1_ & 0x00002000) != 0);
-    }
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     * @return The defaultCord.
-     */
-    @java.lang.Override
-    public java.lang.String getDefaultCord() {
-      return defaultCord_;
-    }
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     * @return The bytes for defaultCord.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getDefaultCordBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(defaultCord_);
-    }
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     * @param value The defaultCord to set.
-     */
-    private void setDefaultCord(
-        java.lang.String value) {
-      value.getClass();
-  bitField1_ |= 0x00002000;
-      defaultCord_ = value;
-    }
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     */
-    private void clearDefaultCord() {
-      bitField1_ = (bitField1_ & ~0x00002000);
-      defaultCord_ = getDefaultInstance().getDefaultCord();
-    }
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     * @param value The bytes for defaultCord to set.
-     */
-    private void setDefaultCordBytes(
-        com.google.protobuf.ByteString value) {
-      defaultCord_ = value.toStringUtf8();
-      bitField1_ |= 0x00002000;
-    }
-
-    public static final int ONEOF_UINT32_FIELD_NUMBER = 111;
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     * @return Whether the oneofUint32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofUint32() {
-      return oneofFieldCase_ == 111;
-    }
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     * @return The oneofUint32.
-     */
-    @java.lang.Override
-    public int getOneofUint32() {
-      if (oneofFieldCase_ == 111) {
-        return (java.lang.Integer) oneofField_;
-      }
-      return 0;
-    }
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     * @param value The oneofUint32 to set.
-     */
-    private void setOneofUint32(int value) {
-      oneofFieldCase_ = 111;
-      oneofField_ = value;
-    }
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     */
-    private void clearOneofUint32() {
-      if (oneofFieldCase_ == 111) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static final int ONEOF_NESTED_MESSAGE_FIELD_NUMBER = 112;
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_nested_message = 112;</code>
-     */
-    @java.lang.Override
-    public boolean hasOneofNestedMessage() {
-      return oneofFieldCase_ == 112;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_nested_message = 112;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage getOneofNestedMessage() {
-      if (oneofFieldCase_ == 112) {
-         return (com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage) oneofField_;
-      }
-      return com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.getDefaultInstance();
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_nested_message = 112;</code>
-     */
-    private void setOneofNestedMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-      value.getClass();
-  oneofField_ = value;
-      oneofFieldCase_ = 112;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_nested_message = 112;</code>
-     */
-    private void mergeOneofNestedMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-      value.getClass();
-  if (oneofFieldCase_ == 112 &&
-          oneofField_ != com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.getDefaultInstance()) {
-        oneofField_ = com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.newBuilder((com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage) oneofField_)
-            .mergeFrom(value).buildPartial();
-      } else {
-        oneofField_ = value;
-      }
-      oneofFieldCase_ = 112;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_nested_message = 112;</code>
-     */
-    private void clearOneofNestedMessage() {
-      if (oneofFieldCase_ == 112) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static final int ONEOF_STRING_FIELD_NUMBER = 113;
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return Whether the oneofString field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofString() {
-      return oneofFieldCase_ == 113;
-    }
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return The oneofString.
-     */
-    @java.lang.Override
-    public java.lang.String getOneofString() {
-      java.lang.String ref = "";
-      if (oneofFieldCase_ == 113) {
-        ref = (java.lang.String) oneofField_;
-      }
-      return ref;
-    }
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return The bytes for oneofString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOneofStringBytes() {
-      java.lang.String ref = "";
-      if (oneofFieldCase_ == 113) {
-        ref = (java.lang.String) oneofField_;
-      }
-      return com.google.protobuf.ByteString.copyFromUtf8(ref);
-    }
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @param value The oneofString to set.
-     */
-    private void setOneofString(
-        java.lang.String value) {
-      value.getClass();
-  oneofFieldCase_ = 113;
-      oneofField_ = value;
-    }
-    /**
-     * <code>string oneof_string = 113;</code>
-     */
-    private void clearOneofString() {
-      if (oneofFieldCase_ == 113) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @param value The bytes for oneofString to set.
-     */
-    private void setOneofStringBytes(
-        com.google.protobuf.ByteString value) {
-      oneofField_ = value.toStringUtf8();
-      oneofFieldCase_ = 113;
-    }
-
-    public static final int ONEOF_BYTES_FIELD_NUMBER = 114;
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     * @return Whether the oneofBytes field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofBytes() {
-      return oneofFieldCase_ == 114;
-    }
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     * @return The oneofBytes.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getOneofBytes() {
-      if (oneofFieldCase_ == 114) {
-        return (com.google.protobuf.ByteString) oneofField_;
-      }
-      return com.google.protobuf.ByteString.EMPTY;
-    }
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     * @param value The oneofBytes to set.
-     */
-    private void setOneofBytes(com.google.protobuf.ByteString value) {
-      value.getClass();
-  oneofFieldCase_ = 114;
-      oneofField_ = value;
-    }
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     */
-    private void clearOneofBytes() {
-      if (oneofFieldCase_ == 114) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static final int ONEOF_LAZY_NESTED_MESSAGE_FIELD_NUMBER = 115;
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_lazy_nested_message = 115 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public boolean hasOneofLazyNestedMessage() {
-      return oneofFieldCase_ == 115;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_lazy_nested_message = 115 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage getOneofLazyNestedMessage() {
-      if (oneofFieldCase_ == 115) {
-         return (com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage) oneofField_;
-      }
-      return com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.getDefaultInstance();
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_lazy_nested_message = 115 [lazy = true];</code>
-     */
-    private void setOneofLazyNestedMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-      value.getClass();
-  oneofField_ = value;
-      oneofFieldCase_ = 115;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_lazy_nested_message = 115 [lazy = true];</code>
-     */
-    private void mergeOneofLazyNestedMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-      value.getClass();
-  if (oneofFieldCase_ == 115 &&
-          oneofField_ != com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.getDefaultInstance()) {
-        oneofField_ = com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.newBuilder((com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage) oneofField_)
-            .mergeFrom(value).buildPartial();
-      } else {
-        oneofField_ = value;
-      }
-      oneofFieldCase_ = 115;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_lazy_nested_message = 115 [lazy = true];</code>
-     */
-    private void clearOneofLazyNestedMessage() {
-      if (oneofFieldCase_ == 115) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static final int ONEOF_NESTED_MESSAGE2_FIELD_NUMBER = 117;
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage2 oneof_nested_message2 = 117;</code>
-     */
-    @java.lang.Override
-    public boolean hasOneofNestedMessage2() {
-      return oneofFieldCase_ == 117;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage2 oneof_nested_message2 = 117;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 getOneofNestedMessage2() {
-      if (oneofFieldCase_ == 117) {
-         return (com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2) oneofField_;
-      }
-      return com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2.getDefaultInstance();
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage2 oneof_nested_message2 = 117;</code>
-     */
-    private void setOneofNestedMessage2(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 value) {
-      value.getClass();
-  oneofField_ = value;
-      oneofFieldCase_ = 117;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage2 oneof_nested_message2 = 117;</code>
-     */
-    private void mergeOneofNestedMessage2(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 value) {
-      value.getClass();
-  if (oneofFieldCase_ == 117 &&
-          oneofField_ != com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2.getDefaultInstance()) {
-        oneofField_ = com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2.newBuilder((com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2) oneofField_)
-            .mergeFrom(value).buildPartial();
-      } else {
-        oneofField_ = value;
-      }
-      oneofFieldCase_ = 117;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage2 oneof_nested_message2 = 117;</code>
-     */
-    private void clearOneofNestedMessage2() {
-      if (oneofFieldCase_ == 117) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static final int DECEPTIVELY_NAMED_LIST_FIELD_NUMBER = 116;
-    private int deceptivelyNamedList_;
-    /**
-     * <pre>
-     * Tests toString for non-repeated fields with a list suffix
-     * </pre>
-     *
-     * <code>optional int32 deceptively_named_list = 116;</code>
-     * @return Whether the deceptivelyNamedList field is set.
-     */
-    @java.lang.Override
-    public boolean hasDeceptivelyNamedList() {
-      return ((bitField1_ & 0x00100000) != 0);
-    }
-    /**
-     * <pre>
-     * Tests toString for non-repeated fields with a list suffix
-     * </pre>
-     *
-     * <code>optional int32 deceptively_named_list = 116;</code>
-     * @return The deceptivelyNamedList.
-     */
-    @java.lang.Override
-    public int getDeceptivelyNamedList() {
-      return deceptivelyNamedList_;
-    }
-    /**
-     * <pre>
-     * Tests toString for non-repeated fields with a list suffix
-     * </pre>
-     *
-     * <code>optional int32 deceptively_named_list = 116;</code>
-     * @param value The deceptivelyNamedList to set.
-     */
-    private void setDeceptivelyNamedList(int value) {
-      bitField1_ |= 0x00100000;
-      deceptivelyNamedList_ = value;
-    }
-    /**
-     * <pre>
-     * Tests toString for non-repeated fields with a list suffix
-     * </pre>
-     *
-     * <code>optional int32 deceptively_named_list = 116;</code>
-     */
-    private void clearDeceptivelyNamedList() {
-      bitField1_ = (bitField1_ & ~0x00100000);
-      deceptivelyNamedList_ = 0;
-    }
-
-    public static com.google.protobuf.UnittestLite.TestAllTypesLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllTypesLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllTypesLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllTypesLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllTypesLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllTypesLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllTypesLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllTypesLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllTypesLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllTypesLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllTypesLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllTypesLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.TestAllTypesLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Same as TestAllTypes but with the lite runtime.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestAllTypesLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.UnittestLite.TestAllTypesLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestAllTypesLite)
-        com.google.protobuf.UnittestLite.TestAllTypesLiteOrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.TestAllTypesLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-      @java.lang.Override
-      public OneofFieldCase
-          getOneofFieldCase() {
-        return instance.getOneofFieldCase();
-      }
-
-      public Builder clearOneofField() {
-        copyOnWrite();
-        instance.clearOneofField();
-        return this;
-      }
-
-
-      /**
-       * <pre>
-       * Singular
-       * </pre>
-       *
-       * <code>optional int32 optional_int32 = 1;</code>
-       * @return Whether the optionalInt32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalInt32() {
-        return instance.hasOptionalInt32();
-      }
-      /**
-       * <pre>
-       * Singular
-       * </pre>
-       *
-       * <code>optional int32 optional_int32 = 1;</code>
-       * @return The optionalInt32.
-       */
-      @java.lang.Override
-      public int getOptionalInt32() {
-        return instance.getOptionalInt32();
-      }
-      /**
-       * <pre>
-       * Singular
-       * </pre>
-       *
-       * <code>optional int32 optional_int32 = 1;</code>
-       * @param value The optionalInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalInt32(int value) {
-        copyOnWrite();
-        instance.setOptionalInt32(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Singular
-       * </pre>
-       *
-       * <code>optional int32 optional_int32 = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalInt32() {
-        copyOnWrite();
-        instance.clearOptionalInt32();
-        return this;
-      }
-
-      /**
-       * <code>optional int64 optional_int64 = 2;</code>
-       * @return Whether the optionalInt64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalInt64() {
-        return instance.hasOptionalInt64();
-      }
-      /**
-       * <code>optional int64 optional_int64 = 2;</code>
-       * @return The optionalInt64.
-       */
-      @java.lang.Override
-      public long getOptionalInt64() {
-        return instance.getOptionalInt64();
-      }
-      /**
-       * <code>optional int64 optional_int64 = 2;</code>
-       * @param value The optionalInt64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalInt64(long value) {
-        copyOnWrite();
-        instance.setOptionalInt64(value);
-        return this;
-      }
-      /**
-       * <code>optional int64 optional_int64 = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalInt64() {
-        copyOnWrite();
-        instance.clearOptionalInt64();
-        return this;
-      }
-
-      /**
-       * <code>optional uint32 optional_uint32 = 3;</code>
-       * @return Whether the optionalUint32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalUint32() {
-        return instance.hasOptionalUint32();
-      }
-      /**
-       * <code>optional uint32 optional_uint32 = 3;</code>
-       * @return The optionalUint32.
-       */
-      @java.lang.Override
-      public int getOptionalUint32() {
-        return instance.getOptionalUint32();
-      }
-      /**
-       * <code>optional uint32 optional_uint32 = 3;</code>
-       * @param value The optionalUint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalUint32(int value) {
-        copyOnWrite();
-        instance.setOptionalUint32(value);
-        return this;
-      }
-      /**
-       * <code>optional uint32 optional_uint32 = 3;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalUint32() {
-        copyOnWrite();
-        instance.clearOptionalUint32();
-        return this;
-      }
-
-      /**
-       * <code>optional uint64 optional_uint64 = 4;</code>
-       * @return Whether the optionalUint64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalUint64() {
-        return instance.hasOptionalUint64();
-      }
-      /**
-       * <code>optional uint64 optional_uint64 = 4;</code>
-       * @return The optionalUint64.
-       */
-      @java.lang.Override
-      public long getOptionalUint64() {
-        return instance.getOptionalUint64();
-      }
-      /**
-       * <code>optional uint64 optional_uint64 = 4;</code>
-       * @param value The optionalUint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalUint64(long value) {
-        copyOnWrite();
-        instance.setOptionalUint64(value);
-        return this;
-      }
-      /**
-       * <code>optional uint64 optional_uint64 = 4;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalUint64() {
-        copyOnWrite();
-        instance.clearOptionalUint64();
-        return this;
-      }
-
-      /**
-       * <code>optional sint32 optional_sint32 = 5;</code>
-       * @return Whether the optionalSint32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalSint32() {
-        return instance.hasOptionalSint32();
-      }
-      /**
-       * <code>optional sint32 optional_sint32 = 5;</code>
-       * @return The optionalSint32.
-       */
-      @java.lang.Override
-      public int getOptionalSint32() {
-        return instance.getOptionalSint32();
-      }
-      /**
-       * <code>optional sint32 optional_sint32 = 5;</code>
-       * @param value The optionalSint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalSint32(int value) {
-        copyOnWrite();
-        instance.setOptionalSint32(value);
-        return this;
-      }
-      /**
-       * <code>optional sint32 optional_sint32 = 5;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalSint32() {
-        copyOnWrite();
-        instance.clearOptionalSint32();
-        return this;
-      }
-
-      /**
-       * <code>optional sint64 optional_sint64 = 6;</code>
-       * @return Whether the optionalSint64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalSint64() {
-        return instance.hasOptionalSint64();
-      }
-      /**
-       * <code>optional sint64 optional_sint64 = 6;</code>
-       * @return The optionalSint64.
-       */
-      @java.lang.Override
-      public long getOptionalSint64() {
-        return instance.getOptionalSint64();
-      }
-      /**
-       * <code>optional sint64 optional_sint64 = 6;</code>
-       * @param value The optionalSint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalSint64(long value) {
-        copyOnWrite();
-        instance.setOptionalSint64(value);
-        return this;
-      }
-      /**
-       * <code>optional sint64 optional_sint64 = 6;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalSint64() {
-        copyOnWrite();
-        instance.clearOptionalSint64();
-        return this;
-      }
-
-      /**
-       * <code>optional fixed32 optional_fixed32 = 7;</code>
-       * @return Whether the optionalFixed32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalFixed32() {
-        return instance.hasOptionalFixed32();
-      }
-      /**
-       * <code>optional fixed32 optional_fixed32 = 7;</code>
-       * @return The optionalFixed32.
-       */
-      @java.lang.Override
-      public int getOptionalFixed32() {
-        return instance.getOptionalFixed32();
-      }
-      /**
-       * <code>optional fixed32 optional_fixed32 = 7;</code>
-       * @param value The optionalFixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalFixed32(int value) {
-        copyOnWrite();
-        instance.setOptionalFixed32(value);
-        return this;
-      }
-      /**
-       * <code>optional fixed32 optional_fixed32 = 7;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalFixed32() {
-        copyOnWrite();
-        instance.clearOptionalFixed32();
-        return this;
-      }
-
-      /**
-       * <code>optional fixed64 optional_fixed64 = 8;</code>
-       * @return Whether the optionalFixed64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalFixed64() {
-        return instance.hasOptionalFixed64();
-      }
-      /**
-       * <code>optional fixed64 optional_fixed64 = 8;</code>
-       * @return The optionalFixed64.
-       */
-      @java.lang.Override
-      public long getOptionalFixed64() {
-        return instance.getOptionalFixed64();
-      }
-      /**
-       * <code>optional fixed64 optional_fixed64 = 8;</code>
-       * @param value The optionalFixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalFixed64(long value) {
-        copyOnWrite();
-        instance.setOptionalFixed64(value);
-        return this;
-      }
-      /**
-       * <code>optional fixed64 optional_fixed64 = 8;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalFixed64() {
-        copyOnWrite();
-        instance.clearOptionalFixed64();
-        return this;
-      }
-
-      /**
-       * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-       * @return Whether the optionalSfixed32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalSfixed32() {
-        return instance.hasOptionalSfixed32();
-      }
-      /**
-       * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-       * @return The optionalSfixed32.
-       */
-      @java.lang.Override
-      public int getOptionalSfixed32() {
-        return instance.getOptionalSfixed32();
-      }
-      /**
-       * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-       * @param value The optionalSfixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalSfixed32(int value) {
-        copyOnWrite();
-        instance.setOptionalSfixed32(value);
-        return this;
-      }
-      /**
-       * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalSfixed32() {
-        copyOnWrite();
-        instance.clearOptionalSfixed32();
-        return this;
-      }
-
-      /**
-       * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-       * @return Whether the optionalSfixed64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalSfixed64() {
-        return instance.hasOptionalSfixed64();
-      }
-      /**
-       * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-       * @return The optionalSfixed64.
-       */
-      @java.lang.Override
-      public long getOptionalSfixed64() {
-        return instance.getOptionalSfixed64();
-      }
-      /**
-       * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-       * @param value The optionalSfixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalSfixed64(long value) {
-        copyOnWrite();
-        instance.setOptionalSfixed64(value);
-        return this;
-      }
-      /**
-       * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalSfixed64() {
-        copyOnWrite();
-        instance.clearOptionalSfixed64();
-        return this;
-      }
-
-      /**
-       * <code>optional float optional_float = 11;</code>
-       * @return Whether the optionalFloat field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalFloat() {
-        return instance.hasOptionalFloat();
-      }
-      /**
-       * <code>optional float optional_float = 11;</code>
-       * @return The optionalFloat.
-       */
-      @java.lang.Override
-      public float getOptionalFloat() {
-        return instance.getOptionalFloat();
-      }
-      /**
-       * <code>optional float optional_float = 11;</code>
-       * @param value The optionalFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalFloat(float value) {
-        copyOnWrite();
-        instance.setOptionalFloat(value);
-        return this;
-      }
-      /**
-       * <code>optional float optional_float = 11;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalFloat() {
-        copyOnWrite();
-        instance.clearOptionalFloat();
-        return this;
-      }
-
-      /**
-       * <code>optional double optional_double = 12;</code>
-       * @return Whether the optionalDouble field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalDouble() {
-        return instance.hasOptionalDouble();
-      }
-      /**
-       * <code>optional double optional_double = 12;</code>
-       * @return The optionalDouble.
-       */
-      @java.lang.Override
-      public double getOptionalDouble() {
-        return instance.getOptionalDouble();
-      }
-      /**
-       * <code>optional double optional_double = 12;</code>
-       * @param value The optionalDouble to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalDouble(double value) {
-        copyOnWrite();
-        instance.setOptionalDouble(value);
-        return this;
-      }
-      /**
-       * <code>optional double optional_double = 12;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalDouble() {
-        copyOnWrite();
-        instance.clearOptionalDouble();
-        return this;
-      }
-
-      /**
-       * <code>optional bool optional_bool = 13;</code>
-       * @return Whether the optionalBool field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalBool() {
-        return instance.hasOptionalBool();
-      }
-      /**
-       * <code>optional bool optional_bool = 13;</code>
-       * @return The optionalBool.
-       */
-      @java.lang.Override
-      public boolean getOptionalBool() {
-        return instance.getOptionalBool();
-      }
-      /**
-       * <code>optional bool optional_bool = 13;</code>
-       * @param value The optionalBool to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalBool(boolean value) {
-        copyOnWrite();
-        instance.setOptionalBool(value);
-        return this;
-      }
-      /**
-       * <code>optional bool optional_bool = 13;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalBool() {
-        copyOnWrite();
-        instance.clearOptionalBool();
-        return this;
-      }
-
-      /**
-       * <code>optional string optional_string = 14;</code>
-       * @return Whether the optionalString field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalString() {
-        return instance.hasOptionalString();
-      }
-      /**
-       * <code>optional string optional_string = 14;</code>
-       * @return The optionalString.
-       */
-      @java.lang.Override
-      public java.lang.String getOptionalString() {
-        return instance.getOptionalString();
-      }
-      /**
-       * <code>optional string optional_string = 14;</code>
-       * @return The bytes for optionalString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getOptionalStringBytes() {
-        return instance.getOptionalStringBytes();
-      }
-      /**
-       * <code>optional string optional_string = 14;</code>
-       * @param value The optionalString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setOptionalString(value);
-        return this;
-      }
-      /**
-       * <code>optional string optional_string = 14;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalString() {
-        copyOnWrite();
-        instance.clearOptionalString();
-        return this;
-      }
-      /**
-       * <code>optional string optional_string = 14;</code>
-       * @param value The bytes for optionalString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOptionalStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional bytes optional_bytes = 15;</code>
-       * @return Whether the optionalBytes field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalBytes() {
-        return instance.hasOptionalBytes();
-      }
-      /**
-       * <code>optional bytes optional_bytes = 15;</code>
-       * @return The optionalBytes.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getOptionalBytes() {
-        return instance.getOptionalBytes();
-      }
-      /**
-       * <code>optional bytes optional_bytes = 15;</code>
-       * @param value The optionalBytes to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalBytes(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOptionalBytes(value);
-        return this;
-      }
-      /**
-       * <code>optional bytes optional_bytes = 15;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalBytes() {
-        copyOnWrite();
-        instance.clearOptionalBytes();
-        return this;
-      }
-
-      /**
-       * <code>optional group OptionalGroup = 16 { ... }</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalGroup() {
-        return instance.hasOptionalGroup();
-      }
-      /**
-       * <code>optional group OptionalGroup = 16 { ... }</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup getOptionalGroup() {
-        return instance.getOptionalGroup();
-      }
-      /**
-       * <code>optional group OptionalGroup = 16 { ... }</code>
-       */
-      public Builder setOptionalGroup(com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup value) {
-        copyOnWrite();
-        instance.setOptionalGroup(value);
-        return this;
-        }
-      /**
-       * <code>optional group OptionalGroup = 16 { ... }</code>
-       */
-      public Builder setOptionalGroup(
-          com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalGroup(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional group OptionalGroup = 16 { ... }</code>
-       */
-      public Builder mergeOptionalGroup(com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup value) {
-        copyOnWrite();
-        instance.mergeOptionalGroup(value);
-        return this;
-      }
-      /**
-       * <code>optional group OptionalGroup = 16 { ... }</code>
-       */
-      public Builder clearOptionalGroup() {  copyOnWrite();
-        instance.clearOptionalGroup();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_nested_message = 18;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalNestedMessage() {
-        return instance.hasOptionalNestedMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_nested_message = 18;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage getOptionalNestedMessage() {
-        return instance.getOptionalNestedMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_nested_message = 18;</code>
-       */
-      public Builder setOptionalNestedMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-        copyOnWrite();
-        instance.setOptionalNestedMessage(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_nested_message = 18;</code>
-       */
-      public Builder setOptionalNestedMessage(
-          com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalNestedMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_nested_message = 18;</code>
-       */
-      public Builder mergeOptionalNestedMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-        copyOnWrite();
-        instance.mergeOptionalNestedMessage(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_nested_message = 18;</code>
-       */
-      public Builder clearOptionalNestedMessage() {  copyOnWrite();
-        instance.clearOptionalNestedMessage();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessageLite optional_foreign_message = 19;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalForeignMessage() {
-        return instance.hasOptionalForeignMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessageLite optional_foreign_message = 19;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.ForeignMessageLite getOptionalForeignMessage() {
-        return instance.getOptionalForeignMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessageLite optional_foreign_message = 19;</code>
-       */
-      public Builder setOptionalForeignMessage(com.google.protobuf.UnittestLite.ForeignMessageLite value) {
-        copyOnWrite();
-        instance.setOptionalForeignMessage(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessageLite optional_foreign_message = 19;</code>
-       */
-      public Builder setOptionalForeignMessage(
-          com.google.protobuf.UnittestLite.ForeignMessageLite.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalForeignMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessageLite optional_foreign_message = 19;</code>
-       */
-      public Builder mergeOptionalForeignMessage(com.google.protobuf.UnittestLite.ForeignMessageLite value) {
-        copyOnWrite();
-        instance.mergeOptionalForeignMessage(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessageLite optional_foreign_message = 19;</code>
-       */
-      public Builder clearOptionalForeignMessage() {  copyOnWrite();
-        instance.clearOptionalForeignMessage();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest_import.ImportMessageLite optional_import_message = 20;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalImportMessage() {
-        return instance.hasOptionalImportMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportMessageLite optional_import_message = 20;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestImportLite.ImportMessageLite getOptionalImportMessage() {
-        return instance.getOptionalImportMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportMessageLite optional_import_message = 20;</code>
-       */
-      public Builder setOptionalImportMessage(com.google.protobuf.UnittestImportLite.ImportMessageLite value) {
-        copyOnWrite();
-        instance.setOptionalImportMessage(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportMessageLite optional_import_message = 20;</code>
-       */
-      public Builder setOptionalImportMessage(
-          com.google.protobuf.UnittestImportLite.ImportMessageLite.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalImportMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportMessageLite optional_import_message = 20;</code>
-       */
-      public Builder mergeOptionalImportMessage(com.google.protobuf.UnittestImportLite.ImportMessageLite value) {
-        copyOnWrite();
-        instance.mergeOptionalImportMessage(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportMessageLite optional_import_message = 20;</code>
-       */
-      public Builder clearOptionalImportMessage() {  copyOnWrite();
-        instance.clearOptionalImportMessage();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum optional_nested_enum = 21;</code>
-       * @return Whether the optionalNestedEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalNestedEnum() {
-        return instance.hasOptionalNestedEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum optional_nested_enum = 21;</code>
-       * @return The optionalNestedEnum.
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum getOptionalNestedEnum() {
-        return instance.getOptionalNestedEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum optional_nested_enum = 21;</code>
-       * @param value The enum numeric value on the wire for optionalNestedEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalNestedEnum(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum value) {
-        copyOnWrite();
-        instance.setOptionalNestedEnum(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum optional_nested_enum = 21;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalNestedEnum() {
-        copyOnWrite();
-        instance.clearOptionalNestedEnum();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnumLite optional_foreign_enum = 22;</code>
-       * @return Whether the optionalForeignEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalForeignEnum() {
-        return instance.hasOptionalForeignEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnumLite optional_foreign_enum = 22;</code>
-       * @return The optionalForeignEnum.
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.ForeignEnumLite getOptionalForeignEnum() {
-        return instance.getOptionalForeignEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnumLite optional_foreign_enum = 22;</code>
-       * @param value The enum numeric value on the wire for optionalForeignEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalForeignEnum(com.google.protobuf.UnittestLite.ForeignEnumLite value) {
-        copyOnWrite();
-        instance.setOptionalForeignEnum(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnumLite optional_foreign_enum = 22;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalForeignEnum() {
-        copyOnWrite();
-        instance.clearOptionalForeignEnum();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest_import.ImportEnumLite optional_import_enum = 23;</code>
-       * @return Whether the optionalImportEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalImportEnum() {
-        return instance.hasOptionalImportEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportEnumLite optional_import_enum = 23;</code>
-       * @return The optionalImportEnum.
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestImportLite.ImportEnumLite getOptionalImportEnum() {
-        return instance.getOptionalImportEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportEnumLite optional_import_enum = 23;</code>
-       * @param value The enum numeric value on the wire for optionalImportEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalImportEnum(com.google.protobuf.UnittestImportLite.ImportEnumLite value) {
-        copyOnWrite();
-        instance.setOptionalImportEnum(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportEnumLite optional_import_enum = 23;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalImportEnum() {
-        copyOnWrite();
-        instance.clearOptionalImportEnum();
-        return this;
-      }
-
-      /**
-       * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-       * @return Whether the optionalStringPiece field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalStringPiece() {
-        return instance.hasOptionalStringPiece();
-      }
-      /**
-       * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-       * @return The optionalStringPiece.
-       */
-      @java.lang.Override
-      public java.lang.String getOptionalStringPiece() {
-        return instance.getOptionalStringPiece();
-      }
-      /**
-       * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-       * @return The bytes for optionalStringPiece.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getOptionalStringPieceBytes() {
-        return instance.getOptionalStringPieceBytes();
-      }
-      /**
-       * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-       * @param value The optionalStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalStringPiece(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setOptionalStringPiece(value);
-        return this;
-      }
-      /**
-       * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalStringPiece() {
-        copyOnWrite();
-        instance.clearOptionalStringPiece();
-        return this;
-      }
-      /**
-       * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-       * @param value The bytes for optionalStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalStringPieceBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOptionalStringPieceBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-       * @return Whether the optionalCord field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalCord() {
-        return instance.hasOptionalCord();
-      }
-      /**
-       * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-       * @return The optionalCord.
-       */
-      @java.lang.Override
-      public java.lang.String getOptionalCord() {
-        return instance.getOptionalCord();
-      }
-      /**
-       * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-       * @return The bytes for optionalCord.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getOptionalCordBytes() {
-        return instance.getOptionalCordBytes();
-      }
-      /**
-       * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-       * @param value The optionalCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalCord(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setOptionalCord(value);
-        return this;
-      }
-      /**
-       * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalCord() {
-        copyOnWrite();
-        instance.clearOptionalCord();
-        return this;
-      }
-      /**
-       * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-       * @param value The bytes for optionalCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalCordBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOptionalCordBytes(value);
-        return this;
-      }
-
-      /**
-       * <pre>
-       * Defined in unittest_import_public.proto
-       * </pre>
-       *
-       * <code>optional .protobuf_unittest_import.PublicImportMessageLite optional_public_import_message = 26;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalPublicImportMessage() {
-        return instance.hasOptionalPublicImportMessage();
-      }
-      /**
-       * <pre>
-       * Defined in unittest_import_public.proto
-       * </pre>
-       *
-       * <code>optional .protobuf_unittest_import.PublicImportMessageLite optional_public_import_message = 26;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite getOptionalPublicImportMessage() {
-        return instance.getOptionalPublicImportMessage();
-      }
-      /**
-       * <pre>
-       * Defined in unittest_import_public.proto
-       * </pre>
-       *
-       * <code>optional .protobuf_unittest_import.PublicImportMessageLite optional_public_import_message = 26;</code>
-       */
-      public Builder setOptionalPublicImportMessage(com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite value) {
-        copyOnWrite();
-        instance.setOptionalPublicImportMessage(value);
-        return this;
-        }
-      /**
-       * <pre>
-       * Defined in unittest_import_public.proto
-       * </pre>
-       *
-       * <code>optional .protobuf_unittest_import.PublicImportMessageLite optional_public_import_message = 26;</code>
-       */
-      public Builder setOptionalPublicImportMessage(
-          com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalPublicImportMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <pre>
-       * Defined in unittest_import_public.proto
-       * </pre>
-       *
-       * <code>optional .protobuf_unittest_import.PublicImportMessageLite optional_public_import_message = 26;</code>
-       */
-      public Builder mergeOptionalPublicImportMessage(com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite value) {
-        copyOnWrite();
-        instance.mergeOptionalPublicImportMessage(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Defined in unittest_import_public.proto
-       * </pre>
-       *
-       * <code>optional .protobuf_unittest_import.PublicImportMessageLite optional_public_import_message = 26;</code>
-       */
-      public Builder clearOptionalPublicImportMessage() {  copyOnWrite();
-        instance.clearOptionalPublicImportMessage();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalLazyMessage() {
-        return instance.hasOptionalLazyMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage getOptionalLazyMessage() {
-        return instance.getOptionalLazyMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-       */
-      public Builder setOptionalLazyMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-        copyOnWrite();
-        instance.setOptionalLazyMessage(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-       */
-      public Builder setOptionalLazyMessage(
-          com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalLazyMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-       */
-      public Builder mergeOptionalLazyMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-        copyOnWrite();
-        instance.mergeOptionalLazyMessage(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-       */
-      public Builder clearOptionalLazyMessage() {  copyOnWrite();
-        instance.clearOptionalLazyMessage();
-        return this;
-      }
-
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @return A list containing the repeatedInt32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedInt32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedInt32List());
-      }
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @return The count of repeatedInt32.
-       */
-      @java.lang.Override
-      public int getRepeatedInt32Count() {
-        return instance.getRepeatedInt32Count();
-      }
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedInt32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedInt32(int index) {
-        return instance.getRepeatedInt32(index);
-      }
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @param value The repeatedInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedInt32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedInt32(index, value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @param value The repeatedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedInt32(int value) {
-        copyOnWrite();
-        instance.addRepeatedInt32(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @param values The repeatedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedInt32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedInt32(values);
-        return this;
-      }
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedInt32() {
-        copyOnWrite();
-        instance.clearRepeatedInt32();
-        return this;
-      }
-
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @return A list containing the repeatedInt64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedInt64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedInt64List());
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @return The count of repeatedInt64.
-       */
-      @java.lang.Override
-      public int getRepeatedInt64Count() {
-        return instance.getRepeatedInt64Count();
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedInt64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedInt64(int index) {
-        return instance.getRepeatedInt64(index);
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @param value The repeatedInt64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedInt64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedInt64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @param value The repeatedInt64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedInt64(long value) {
-        copyOnWrite();
-        instance.addRepeatedInt64(value);
-        return this;
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @param values The repeatedInt64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedInt64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedInt64(values);
-        return this;
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedInt64() {
-        copyOnWrite();
-        instance.clearRepeatedInt64();
-        return this;
-      }
-
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @return A list containing the repeatedUint32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedUint32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedUint32List());
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @return The count of repeatedUint32.
-       */
-      @java.lang.Override
-      public int getRepeatedUint32Count() {
-        return instance.getRepeatedUint32Count();
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedUint32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedUint32(int index) {
-        return instance.getRepeatedUint32(index);
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @param value The repeatedUint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedUint32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedUint32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @param value The repeatedUint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedUint32(int value) {
-        copyOnWrite();
-        instance.addRepeatedUint32(value);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @param values The repeatedUint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedUint32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedUint32(values);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedUint32() {
-        copyOnWrite();
-        instance.clearRepeatedUint32();
-        return this;
-      }
-
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @return A list containing the repeatedUint64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedUint64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedUint64List());
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @return The count of repeatedUint64.
-       */
-      @java.lang.Override
-      public int getRepeatedUint64Count() {
-        return instance.getRepeatedUint64Count();
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedUint64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedUint64(int index) {
-        return instance.getRepeatedUint64(index);
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @param value The repeatedUint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedUint64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedUint64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @param value The repeatedUint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedUint64(long value) {
-        copyOnWrite();
-        instance.addRepeatedUint64(value);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @param values The repeatedUint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedUint64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedUint64(values);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedUint64() {
-        copyOnWrite();
-        instance.clearRepeatedUint64();
-        return this;
-      }
-
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @return A list containing the repeatedSint32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedSint32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedSint32List());
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @return The count of repeatedSint32.
-       */
-      @java.lang.Override
-      public int getRepeatedSint32Count() {
-        return instance.getRepeatedSint32Count();
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedSint32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedSint32(int index) {
-        return instance.getRepeatedSint32(index);
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @param value The repeatedSint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedSint32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedSint32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @param value The repeatedSint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedSint32(int value) {
-        copyOnWrite();
-        instance.addRepeatedSint32(value);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @param values The repeatedSint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedSint32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedSint32(values);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedSint32() {
-        copyOnWrite();
-        instance.clearRepeatedSint32();
-        return this;
-      }
-
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @return A list containing the repeatedSint64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedSint64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedSint64List());
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @return The count of repeatedSint64.
-       */
-      @java.lang.Override
-      public int getRepeatedSint64Count() {
-        return instance.getRepeatedSint64Count();
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedSint64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedSint64(int index) {
-        return instance.getRepeatedSint64(index);
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @param value The repeatedSint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedSint64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedSint64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @param value The repeatedSint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedSint64(long value) {
-        copyOnWrite();
-        instance.addRepeatedSint64(value);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @param values The repeatedSint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedSint64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedSint64(values);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedSint64() {
-        copyOnWrite();
-        instance.clearRepeatedSint64();
-        return this;
-      }
-
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @return A list containing the repeatedFixed32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedFixed32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedFixed32List());
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @return The count of repeatedFixed32.
-       */
-      @java.lang.Override
-      public int getRepeatedFixed32Count() {
-        return instance.getRepeatedFixed32Count();
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedFixed32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedFixed32(int index) {
-        return instance.getRepeatedFixed32(index);
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @param value The repeatedFixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedFixed32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedFixed32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @param value The repeatedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedFixed32(int value) {
-        copyOnWrite();
-        instance.addRepeatedFixed32(value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @param values The repeatedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedFixed32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedFixed32(values);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedFixed32() {
-        copyOnWrite();
-        instance.clearRepeatedFixed32();
-        return this;
-      }
-
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @return A list containing the repeatedFixed64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedFixed64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedFixed64List());
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @return The count of repeatedFixed64.
-       */
-      @java.lang.Override
-      public int getRepeatedFixed64Count() {
-        return instance.getRepeatedFixed64Count();
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedFixed64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedFixed64(int index) {
-        return instance.getRepeatedFixed64(index);
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @param value The repeatedFixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedFixed64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedFixed64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @param value The repeatedFixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedFixed64(long value) {
-        copyOnWrite();
-        instance.addRepeatedFixed64(value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @param values The repeatedFixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedFixed64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedFixed64(values);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedFixed64() {
-        copyOnWrite();
-        instance.clearRepeatedFixed64();
-        return this;
-      }
-
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @return A list containing the repeatedSfixed32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedSfixed32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedSfixed32List());
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @return The count of repeatedSfixed32.
-       */
-      @java.lang.Override
-      public int getRepeatedSfixed32Count() {
-        return instance.getRepeatedSfixed32Count();
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedSfixed32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedSfixed32(int index) {
-        return instance.getRepeatedSfixed32(index);
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @param value The repeatedSfixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedSfixed32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedSfixed32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @param value The repeatedSfixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedSfixed32(int value) {
-        copyOnWrite();
-        instance.addRepeatedSfixed32(value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @param values The repeatedSfixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedSfixed32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedSfixed32(values);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedSfixed32() {
-        copyOnWrite();
-        instance.clearRepeatedSfixed32();
-        return this;
-      }
-
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @return A list containing the repeatedSfixed64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedSfixed64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedSfixed64List());
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @return The count of repeatedSfixed64.
-       */
-      @java.lang.Override
-      public int getRepeatedSfixed64Count() {
-        return instance.getRepeatedSfixed64Count();
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedSfixed64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedSfixed64(int index) {
-        return instance.getRepeatedSfixed64(index);
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @param value The repeatedSfixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedSfixed64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedSfixed64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @param value The repeatedSfixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedSfixed64(long value) {
-        copyOnWrite();
-        instance.addRepeatedSfixed64(value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @param values The repeatedSfixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedSfixed64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedSfixed64(values);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedSfixed64() {
-        copyOnWrite();
-        instance.clearRepeatedSfixed64();
-        return this;
-      }
-
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @return A list containing the repeatedFloat.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Float>
-          getRepeatedFloatList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedFloatList());
-      }
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @return The count of repeatedFloat.
-       */
-      @java.lang.Override
-      public int getRepeatedFloatCount() {
-        return instance.getRepeatedFloatCount();
-      }
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedFloat at the given index.
-       */
-      @java.lang.Override
-      public float getRepeatedFloat(int index) {
-        return instance.getRepeatedFloat(index);
-      }
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @param value The repeatedFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedFloat(
-          int index, float value) {
-        copyOnWrite();
-        instance.setRepeatedFloat(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @param value The repeatedFloat to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedFloat(float value) {
-        copyOnWrite();
-        instance.addRepeatedFloat(value);
-        return this;
-      }
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @param values The repeatedFloat to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedFloat(
-          java.lang.Iterable<? extends java.lang.Float> values) {
-        copyOnWrite();
-        instance.addAllRepeatedFloat(values);
-        return this;
-      }
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedFloat() {
-        copyOnWrite();
-        instance.clearRepeatedFloat();
-        return this;
-      }
-
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @return A list containing the repeatedDouble.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Double>
-          getRepeatedDoubleList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedDoubleList());
-      }
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @return The count of repeatedDouble.
-       */
-      @java.lang.Override
-      public int getRepeatedDoubleCount() {
-        return instance.getRepeatedDoubleCount();
-      }
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedDouble at the given index.
-       */
-      @java.lang.Override
-      public double getRepeatedDouble(int index) {
-        return instance.getRepeatedDouble(index);
-      }
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @param value The repeatedDouble to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedDouble(
-          int index, double value) {
-        copyOnWrite();
-        instance.setRepeatedDouble(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @param value The repeatedDouble to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedDouble(double value) {
-        copyOnWrite();
-        instance.addRepeatedDouble(value);
-        return this;
-      }
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @param values The repeatedDouble to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedDouble(
-          java.lang.Iterable<? extends java.lang.Double> values) {
-        copyOnWrite();
-        instance.addAllRepeatedDouble(values);
-        return this;
-      }
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedDouble() {
-        copyOnWrite();
-        instance.clearRepeatedDouble();
-        return this;
-      }
-
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @return A list containing the repeatedBool.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Boolean>
-          getRepeatedBoolList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedBoolList());
-      }
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @return The count of repeatedBool.
-       */
-      @java.lang.Override
-      public int getRepeatedBoolCount() {
-        return instance.getRepeatedBoolCount();
-      }
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedBool at the given index.
-       */
-      @java.lang.Override
-      public boolean getRepeatedBool(int index) {
-        return instance.getRepeatedBool(index);
-      }
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @param value The repeatedBool to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedBool(
-          int index, boolean value) {
-        copyOnWrite();
-        instance.setRepeatedBool(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @param value The repeatedBool to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedBool(boolean value) {
-        copyOnWrite();
-        instance.addRepeatedBool(value);
-        return this;
-      }
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @param values The repeatedBool to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedBool(
-          java.lang.Iterable<? extends java.lang.Boolean> values) {
-        copyOnWrite();
-        instance.addAllRepeatedBool(values);
-        return this;
-      }
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedBool() {
-        copyOnWrite();
-        instance.clearRepeatedBool();
-        return this;
-      }
-
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @return A list containing the repeatedString.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getRepeatedStringList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedStringList());
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @return The count of repeatedString.
-       */
-      @java.lang.Override
-      public int getRepeatedStringCount() {
-        return instance.getRepeatedStringCount();
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedString at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getRepeatedString(int index) {
-        return instance.getRepeatedString(index);
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the repeatedString at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getRepeatedStringBytes(int index) {
-        return instance.getRepeatedStringBytes(index);
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedString(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setRepeatedString(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @param value The repeatedString to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addRepeatedString(value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @param values The repeatedString to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedString(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllRepeatedString(values);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedString() {
-        copyOnWrite();
-        instance.clearRepeatedString();
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @param value The bytes of the repeatedString to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addRepeatedStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @return A list containing the repeatedBytes.
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.ByteString>
-          getRepeatedBytesList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedBytesList());
-      }
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @return The count of repeatedBytes.
-       */
-      @java.lang.Override
-      public int getRepeatedBytesCount() {
-        return instance.getRepeatedBytesCount();
-      }
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedBytes at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getRepeatedBytes(int index) {
-        return instance.getRepeatedBytes(index);
-      }
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @param value The repeatedBytes to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedBytes(
-          int index, com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setRepeatedBytes(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @param value The repeatedBytes to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedBytes(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addRepeatedBytes(value);
-        return this;
-      }
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @param values The repeatedBytes to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedBytes(
-          java.lang.Iterable<? extends com.google.protobuf.ByteString> values) {
-        copyOnWrite();
-        instance.addAllRepeatedBytes(values);
-        return this;
-      }
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedBytes() {
-        copyOnWrite();
-        instance.clearRepeatedBytes();
-        return this;
-      }
-
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup> getRepeatedGroupList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedGroupList());
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      @java.lang.Override
-      public int getRepeatedGroupCount() {
-        return instance.getRepeatedGroupCount();
-      }/**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup getRepeatedGroup(int index) {
-        return instance.getRepeatedGroup(index);
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      public Builder setRepeatedGroup(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup value) {
-        copyOnWrite();
-        instance.setRepeatedGroup(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      public Builder setRepeatedGroup(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedGroup(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      public Builder addRepeatedGroup(com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup value) {
-        copyOnWrite();
-        instance.addRepeatedGroup(value);
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      public Builder addRepeatedGroup(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup value) {
-        copyOnWrite();
-        instance.addRepeatedGroup(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      public Builder addRepeatedGroup(
-          com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedGroup(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      public Builder addRepeatedGroup(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedGroup(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      public Builder addAllRepeatedGroup(
-          java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup> values) {
-        copyOnWrite();
-        instance.addAllRepeatedGroup(values);
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      public Builder clearRepeatedGroup() {
-        copyOnWrite();
-        instance.clearRepeatedGroup();
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      public Builder removeRepeatedGroup(int index) {
-        copyOnWrite();
-        instance.removeRepeatedGroup(index);
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage> getRepeatedNestedMessageList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedNestedMessageList());
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-       */
-      @java.lang.Override
-      public int getRepeatedNestedMessageCount() {
-        return instance.getRepeatedNestedMessageCount();
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage getRepeatedNestedMessage(int index) {
-        return instance.getRepeatedNestedMessage(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder setRepeatedNestedMessage(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-        copyOnWrite();
-        instance.setRepeatedNestedMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder setRepeatedNestedMessage(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedNestedMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder addRepeatedNestedMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-        copyOnWrite();
-        instance.addRepeatedNestedMessage(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder addRepeatedNestedMessage(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-        copyOnWrite();
-        instance.addRepeatedNestedMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder addRepeatedNestedMessage(
-          com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedNestedMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder addRepeatedNestedMessage(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedNestedMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder addAllRepeatedNestedMessage(
-          java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage> values) {
-        copyOnWrite();
-        instance.addAllRepeatedNestedMessage(values);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder clearRepeatedNestedMessage() {
-        copyOnWrite();
-        instance.clearRepeatedNestedMessage();
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder removeRepeatedNestedMessage(int index) {
-        copyOnWrite();
-        instance.removeRepeatedNestedMessage(index);
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.UnittestLite.ForeignMessageLite> getRepeatedForeignMessageList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedForeignMessageList());
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-       */
-      @java.lang.Override
-      public int getRepeatedForeignMessageCount() {
-        return instance.getRepeatedForeignMessageCount();
-      }/**
-       * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.ForeignMessageLite getRepeatedForeignMessage(int index) {
-        return instance.getRepeatedForeignMessage(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-       */
-      public Builder setRepeatedForeignMessage(
-          int index, com.google.protobuf.UnittestLite.ForeignMessageLite value) {
-        copyOnWrite();
-        instance.setRepeatedForeignMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-       */
-      public Builder setRepeatedForeignMessage(
-          int index, com.google.protobuf.UnittestLite.ForeignMessageLite.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedForeignMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-       */
-      public Builder addRepeatedForeignMessage(com.google.protobuf.UnittestLite.ForeignMessageLite value) {
-        copyOnWrite();
-        instance.addRepeatedForeignMessage(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-       */
-      public Builder addRepeatedForeignMessage(
-          int index, com.google.protobuf.UnittestLite.ForeignMessageLite value) {
-        copyOnWrite();
-        instance.addRepeatedForeignMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-       */
-      public Builder addRepeatedForeignMessage(
-          com.google.protobuf.UnittestLite.ForeignMessageLite.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedForeignMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-       */
-      public Builder addRepeatedForeignMessage(
-          int index, com.google.protobuf.UnittestLite.ForeignMessageLite.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedForeignMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-       */
-      public Builder addAllRepeatedForeignMessage(
-          java.lang.Iterable<? extends com.google.protobuf.UnittestLite.ForeignMessageLite> values) {
-        copyOnWrite();
-        instance.addAllRepeatedForeignMessage(values);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-       */
-      public Builder clearRepeatedForeignMessage() {
-        copyOnWrite();
-        instance.clearRepeatedForeignMessage();
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessageLite repeated_foreign_message = 49;</code>
-       */
-      public Builder removeRepeatedForeignMessage(int index) {
-        copyOnWrite();
-        instance.removeRepeatedForeignMessage(index);
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.UnittestImportLite.ImportMessageLite> getRepeatedImportMessageList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedImportMessageList());
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-       */
-      @java.lang.Override
-      public int getRepeatedImportMessageCount() {
-        return instance.getRepeatedImportMessageCount();
-      }/**
-       * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestImportLite.ImportMessageLite getRepeatedImportMessage(int index) {
-        return instance.getRepeatedImportMessage(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-       */
-      public Builder setRepeatedImportMessage(
-          int index, com.google.protobuf.UnittestImportLite.ImportMessageLite value) {
-        copyOnWrite();
-        instance.setRepeatedImportMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-       */
-      public Builder setRepeatedImportMessage(
-          int index, com.google.protobuf.UnittestImportLite.ImportMessageLite.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedImportMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-       */
-      public Builder addRepeatedImportMessage(com.google.protobuf.UnittestImportLite.ImportMessageLite value) {
-        copyOnWrite();
-        instance.addRepeatedImportMessage(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-       */
-      public Builder addRepeatedImportMessage(
-          int index, com.google.protobuf.UnittestImportLite.ImportMessageLite value) {
-        copyOnWrite();
-        instance.addRepeatedImportMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-       */
-      public Builder addRepeatedImportMessage(
-          com.google.protobuf.UnittestImportLite.ImportMessageLite.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedImportMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-       */
-      public Builder addRepeatedImportMessage(
-          int index, com.google.protobuf.UnittestImportLite.ImportMessageLite.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedImportMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-       */
-      public Builder addAllRepeatedImportMessage(
-          java.lang.Iterable<? extends com.google.protobuf.UnittestImportLite.ImportMessageLite> values) {
-        copyOnWrite();
-        instance.addAllRepeatedImportMessage(values);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-       */
-      public Builder clearRepeatedImportMessage() {
-        copyOnWrite();
-        instance.clearRepeatedImportMessage();
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessageLite repeated_import_message = 50;</code>
-       */
-      public Builder removeRepeatedImportMessage(int index) {
-        copyOnWrite();
-        instance.removeRepeatedImportMessage(index);
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-       * @return A list containing the repeatedNestedEnum.
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum> getRepeatedNestedEnumList() {
-        return instance.getRepeatedNestedEnumList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-       * @return The count of repeatedNestedEnum.
-       */
-      @java.lang.Override
-      public int getRepeatedNestedEnumCount() {
-        return instance.getRepeatedNestedEnumCount();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedNestedEnum at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum getRepeatedNestedEnum(int index) {
-        return instance.getRepeatedNestedEnum(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedNestedEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedNestedEnum(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum value) {
-        copyOnWrite();
-        instance.setRepeatedNestedEnum(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-       * @param value The repeatedNestedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedNestedEnum(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum value) {
-        copyOnWrite();
-        instance.addRepeatedNestedEnum(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-       * @param values The repeatedNestedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedNestedEnum(
-          java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum> values) {
-        copyOnWrite();
-        instance.addAllRepeatedNestedEnum(values);  return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedEnum repeated_nested_enum = 51;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedNestedEnum() {
-        copyOnWrite();
-        instance.clearRepeatedNestedEnum();
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-       * @return A list containing the repeatedForeignEnum.
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.UnittestLite.ForeignEnumLite> getRepeatedForeignEnumList() {
-        return instance.getRepeatedForeignEnumList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-       * @return The count of repeatedForeignEnum.
-       */
-      @java.lang.Override
-      public int getRepeatedForeignEnumCount() {
-        return instance.getRepeatedForeignEnumCount();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedForeignEnum at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.ForeignEnumLite getRepeatedForeignEnum(int index) {
-        return instance.getRepeatedForeignEnum(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedForeignEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedForeignEnum(
-          int index, com.google.protobuf.UnittestLite.ForeignEnumLite value) {
-        copyOnWrite();
-        instance.setRepeatedForeignEnum(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-       * @param value The repeatedForeignEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedForeignEnum(com.google.protobuf.UnittestLite.ForeignEnumLite value) {
-        copyOnWrite();
-        instance.addRepeatedForeignEnum(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-       * @param values The repeatedForeignEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedForeignEnum(
-          java.lang.Iterable<? extends com.google.protobuf.UnittestLite.ForeignEnumLite> values) {
-        copyOnWrite();
-        instance.addAllRepeatedForeignEnum(values);  return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnumLite repeated_foreign_enum = 52;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedForeignEnum() {
-        copyOnWrite();
-        instance.clearRepeatedForeignEnum();
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-       * @return A list containing the repeatedImportEnum.
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.UnittestImportLite.ImportEnumLite> getRepeatedImportEnumList() {
-        return instance.getRepeatedImportEnumList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-       * @return The count of repeatedImportEnum.
-       */
-      @java.lang.Override
-      public int getRepeatedImportEnumCount() {
-        return instance.getRepeatedImportEnumCount();
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedImportEnum at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestImportLite.ImportEnumLite getRepeatedImportEnum(int index) {
-        return instance.getRepeatedImportEnum(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedImportEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedImportEnum(
-          int index, com.google.protobuf.UnittestImportLite.ImportEnumLite value) {
-        copyOnWrite();
-        instance.setRepeatedImportEnum(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-       * @param value The repeatedImportEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedImportEnum(com.google.protobuf.UnittestImportLite.ImportEnumLite value) {
-        copyOnWrite();
-        instance.addRepeatedImportEnum(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-       * @param values The repeatedImportEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedImportEnum(
-          java.lang.Iterable<? extends com.google.protobuf.UnittestImportLite.ImportEnumLite> values) {
-        copyOnWrite();
-        instance.addAllRepeatedImportEnum(values);  return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedImportEnum() {
-        copyOnWrite();
-        instance.clearRepeatedImportEnum();
-        return this;
-      }
-
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @return A list containing the repeatedStringPiece.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getRepeatedStringPieceList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedStringPieceList());
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @return The count of repeatedStringPiece.
-       */
-      @java.lang.Override
-      public int getRepeatedStringPieceCount() {
-        return instance.getRepeatedStringPieceCount();
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedStringPiece at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getRepeatedStringPiece(int index) {
-        return instance.getRepeatedStringPiece(index);
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the repeatedStringPiece at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getRepeatedStringPieceBytes(int index) {
-        return instance.getRepeatedStringPieceBytes(index);
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedStringPiece(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setRepeatedStringPiece(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @param value The repeatedStringPiece to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedStringPiece(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addRepeatedStringPiece(value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @param values The repeatedStringPiece to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedStringPiece(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllRepeatedStringPiece(values);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedStringPiece() {
-        copyOnWrite();
-        instance.clearRepeatedStringPiece();
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @param value The bytes of the repeatedStringPiece to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedStringPieceBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addRepeatedStringPieceBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @return A list containing the repeatedCord.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getRepeatedCordList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedCordList());
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @return The count of repeatedCord.
-       */
-      @java.lang.Override
-      public int getRepeatedCordCount() {
-        return instance.getRepeatedCordCount();
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedCord at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getRepeatedCord(int index) {
-        return instance.getRepeatedCord(index);
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the repeatedCord at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getRepeatedCordBytes(int index) {
-        return instance.getRepeatedCordBytes(index);
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedCord(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setRepeatedCord(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @param value The repeatedCord to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedCord(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addRepeatedCord(value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @param values The repeatedCord to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedCord(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllRepeatedCord(values);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedCord() {
-        copyOnWrite();
-        instance.clearRepeatedCord();
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @param value The bytes of the repeatedCord to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedCordBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addRepeatedCordBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage> getRepeatedLazyMessageList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedLazyMessageList());
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public int getRepeatedLazyMessageCount() {
-        return instance.getRepeatedLazyMessageCount();
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage getRepeatedLazyMessage(int index) {
-        return instance.getRepeatedLazyMessage(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder setRepeatedLazyMessage(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-        copyOnWrite();
-        instance.setRepeatedLazyMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder setRepeatedLazyMessage(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedLazyMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder addRepeatedLazyMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-        copyOnWrite();
-        instance.addRepeatedLazyMessage(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder addRepeatedLazyMessage(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-        copyOnWrite();
-        instance.addRepeatedLazyMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder addRepeatedLazyMessage(
-          com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedLazyMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder addRepeatedLazyMessage(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedLazyMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder addAllRepeatedLazyMessage(
-          java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage> values) {
-        copyOnWrite();
-        instance.addAllRepeatedLazyMessage(values);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder clearRepeatedLazyMessage() {
-        copyOnWrite();
-        instance.clearRepeatedLazyMessage();
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder removeRepeatedLazyMessage(int index) {
-        copyOnWrite();
-        instance.removeRepeatedLazyMessage(index);
-        return this;
-      }
-
-      /**
-       * <pre>
-       * Singular with defaults
-       * </pre>
-       *
-       * <code>optional int32 default_int32 = 61 [default = 41];</code>
-       * @return Whether the defaultInt32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultInt32() {
-        return instance.hasDefaultInt32();
-      }
-      /**
-       * <pre>
-       * Singular with defaults
-       * </pre>
-       *
-       * <code>optional int32 default_int32 = 61 [default = 41];</code>
-       * @return The defaultInt32.
-       */
-      @java.lang.Override
-      public int getDefaultInt32() {
-        return instance.getDefaultInt32();
-      }
-      /**
-       * <pre>
-       * Singular with defaults
-       * </pre>
-       *
-       * <code>optional int32 default_int32 = 61 [default = 41];</code>
-       * @param value The defaultInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultInt32(int value) {
-        copyOnWrite();
-        instance.setDefaultInt32(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Singular with defaults
-       * </pre>
-       *
-       * <code>optional int32 default_int32 = 61 [default = 41];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultInt32() {
-        copyOnWrite();
-        instance.clearDefaultInt32();
-        return this;
-      }
-
-      /**
-       * <code>optional int64 default_int64 = 62 [default = 42];</code>
-       * @return Whether the defaultInt64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultInt64() {
-        return instance.hasDefaultInt64();
-      }
-      /**
-       * <code>optional int64 default_int64 = 62 [default = 42];</code>
-       * @return The defaultInt64.
-       */
-      @java.lang.Override
-      public long getDefaultInt64() {
-        return instance.getDefaultInt64();
-      }
-      /**
-       * <code>optional int64 default_int64 = 62 [default = 42];</code>
-       * @param value The defaultInt64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultInt64(long value) {
-        copyOnWrite();
-        instance.setDefaultInt64(value);
-        return this;
-      }
-      /**
-       * <code>optional int64 default_int64 = 62 [default = 42];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultInt64() {
-        copyOnWrite();
-        instance.clearDefaultInt64();
-        return this;
-      }
-
-      /**
-       * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-       * @return Whether the defaultUint32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultUint32() {
-        return instance.hasDefaultUint32();
-      }
-      /**
-       * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-       * @return The defaultUint32.
-       */
-      @java.lang.Override
-      public int getDefaultUint32() {
-        return instance.getDefaultUint32();
-      }
-      /**
-       * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-       * @param value The defaultUint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultUint32(int value) {
-        copyOnWrite();
-        instance.setDefaultUint32(value);
-        return this;
-      }
-      /**
-       * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultUint32() {
-        copyOnWrite();
-        instance.clearDefaultUint32();
-        return this;
-      }
-
-      /**
-       * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-       * @return Whether the defaultUint64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultUint64() {
-        return instance.hasDefaultUint64();
-      }
-      /**
-       * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-       * @return The defaultUint64.
-       */
-      @java.lang.Override
-      public long getDefaultUint64() {
-        return instance.getDefaultUint64();
-      }
-      /**
-       * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-       * @param value The defaultUint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultUint64(long value) {
-        copyOnWrite();
-        instance.setDefaultUint64(value);
-        return this;
-      }
-      /**
-       * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultUint64() {
-        copyOnWrite();
-        instance.clearDefaultUint64();
-        return this;
-      }
-
-      /**
-       * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-       * @return Whether the defaultSint32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultSint32() {
-        return instance.hasDefaultSint32();
-      }
-      /**
-       * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-       * @return The defaultSint32.
-       */
-      @java.lang.Override
-      public int getDefaultSint32() {
-        return instance.getDefaultSint32();
-      }
-      /**
-       * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-       * @param value The defaultSint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultSint32(int value) {
-        copyOnWrite();
-        instance.setDefaultSint32(value);
-        return this;
-      }
-      /**
-       * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultSint32() {
-        copyOnWrite();
-        instance.clearDefaultSint32();
-        return this;
-      }
-
-      /**
-       * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-       * @return Whether the defaultSint64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultSint64() {
-        return instance.hasDefaultSint64();
-      }
-      /**
-       * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-       * @return The defaultSint64.
-       */
-      @java.lang.Override
-      public long getDefaultSint64() {
-        return instance.getDefaultSint64();
-      }
-      /**
-       * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-       * @param value The defaultSint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultSint64(long value) {
-        copyOnWrite();
-        instance.setDefaultSint64(value);
-        return this;
-      }
-      /**
-       * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultSint64() {
-        copyOnWrite();
-        instance.clearDefaultSint64();
-        return this;
-      }
-
-      /**
-       * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-       * @return Whether the defaultFixed32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultFixed32() {
-        return instance.hasDefaultFixed32();
-      }
-      /**
-       * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-       * @return The defaultFixed32.
-       */
-      @java.lang.Override
-      public int getDefaultFixed32() {
-        return instance.getDefaultFixed32();
-      }
-      /**
-       * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-       * @param value The defaultFixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultFixed32(int value) {
-        copyOnWrite();
-        instance.setDefaultFixed32(value);
-        return this;
-      }
-      /**
-       * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultFixed32() {
-        copyOnWrite();
-        instance.clearDefaultFixed32();
-        return this;
-      }
-
-      /**
-       * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-       * @return Whether the defaultFixed64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultFixed64() {
-        return instance.hasDefaultFixed64();
-      }
-      /**
-       * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-       * @return The defaultFixed64.
-       */
-      @java.lang.Override
-      public long getDefaultFixed64() {
-        return instance.getDefaultFixed64();
-      }
-      /**
-       * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-       * @param value The defaultFixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultFixed64(long value) {
-        copyOnWrite();
-        instance.setDefaultFixed64(value);
-        return this;
-      }
-      /**
-       * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultFixed64() {
-        copyOnWrite();
-        instance.clearDefaultFixed64();
-        return this;
-      }
-
-      /**
-       * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-       * @return Whether the defaultSfixed32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultSfixed32() {
-        return instance.hasDefaultSfixed32();
-      }
-      /**
-       * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-       * @return The defaultSfixed32.
-       */
-      @java.lang.Override
-      public int getDefaultSfixed32() {
-        return instance.getDefaultSfixed32();
-      }
-      /**
-       * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-       * @param value The defaultSfixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultSfixed32(int value) {
-        copyOnWrite();
-        instance.setDefaultSfixed32(value);
-        return this;
-      }
-      /**
-       * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultSfixed32() {
-        copyOnWrite();
-        instance.clearDefaultSfixed32();
-        return this;
-      }
-
-      /**
-       * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-       * @return Whether the defaultSfixed64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultSfixed64() {
-        return instance.hasDefaultSfixed64();
-      }
-      /**
-       * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-       * @return The defaultSfixed64.
-       */
-      @java.lang.Override
-      public long getDefaultSfixed64() {
-        return instance.getDefaultSfixed64();
-      }
-      /**
-       * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-       * @param value The defaultSfixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultSfixed64(long value) {
-        copyOnWrite();
-        instance.setDefaultSfixed64(value);
-        return this;
-      }
-      /**
-       * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultSfixed64() {
-        copyOnWrite();
-        instance.clearDefaultSfixed64();
-        return this;
-      }
-
-      /**
-       * <code>optional float default_float = 71 [default = 51.5];</code>
-       * @return Whether the defaultFloat field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultFloat() {
-        return instance.hasDefaultFloat();
-      }
-      /**
-       * <code>optional float default_float = 71 [default = 51.5];</code>
-       * @return The defaultFloat.
-       */
-      @java.lang.Override
-      public float getDefaultFloat() {
-        return instance.getDefaultFloat();
-      }
-      /**
-       * <code>optional float default_float = 71 [default = 51.5];</code>
-       * @param value The defaultFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultFloat(float value) {
-        copyOnWrite();
-        instance.setDefaultFloat(value);
-        return this;
-      }
-      /**
-       * <code>optional float default_float = 71 [default = 51.5];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultFloat() {
-        copyOnWrite();
-        instance.clearDefaultFloat();
-        return this;
-      }
-
-      /**
-       * <code>optional double default_double = 72 [default = 52000];</code>
-       * @return Whether the defaultDouble field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultDouble() {
-        return instance.hasDefaultDouble();
-      }
-      /**
-       * <code>optional double default_double = 72 [default = 52000];</code>
-       * @return The defaultDouble.
-       */
-      @java.lang.Override
-      public double getDefaultDouble() {
-        return instance.getDefaultDouble();
-      }
-      /**
-       * <code>optional double default_double = 72 [default = 52000];</code>
-       * @param value The defaultDouble to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultDouble(double value) {
-        copyOnWrite();
-        instance.setDefaultDouble(value);
-        return this;
-      }
-      /**
-       * <code>optional double default_double = 72 [default = 52000];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultDouble() {
-        copyOnWrite();
-        instance.clearDefaultDouble();
-        return this;
-      }
-
-      /**
-       * <code>optional bool default_bool = 73 [default = true];</code>
-       * @return Whether the defaultBool field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultBool() {
-        return instance.hasDefaultBool();
-      }
-      /**
-       * <code>optional bool default_bool = 73 [default = true];</code>
-       * @return The defaultBool.
-       */
-      @java.lang.Override
-      public boolean getDefaultBool() {
-        return instance.getDefaultBool();
-      }
-      /**
-       * <code>optional bool default_bool = 73 [default = true];</code>
-       * @param value The defaultBool to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultBool(boolean value) {
-        copyOnWrite();
-        instance.setDefaultBool(value);
-        return this;
-      }
-      /**
-       * <code>optional bool default_bool = 73 [default = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultBool() {
-        copyOnWrite();
-        instance.clearDefaultBool();
-        return this;
-      }
-
-      /**
-       * <code>optional string default_string = 74 [default = "hello"];</code>
-       * @return Whether the defaultString field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultString() {
-        return instance.hasDefaultString();
-      }
-      /**
-       * <code>optional string default_string = 74 [default = "hello"];</code>
-       * @return The defaultString.
-       */
-      @java.lang.Override
-      public java.lang.String getDefaultString() {
-        return instance.getDefaultString();
-      }
-      /**
-       * <code>optional string default_string = 74 [default = "hello"];</code>
-       * @return The bytes for defaultString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getDefaultStringBytes() {
-        return instance.getDefaultStringBytes();
-      }
-      /**
-       * <code>optional string default_string = 74 [default = "hello"];</code>
-       * @param value The defaultString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setDefaultString(value);
-        return this;
-      }
-      /**
-       * <code>optional string default_string = 74 [default = "hello"];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultString() {
-        copyOnWrite();
-        instance.clearDefaultString();
-        return this;
-      }
-      /**
-       * <code>optional string default_string = 74 [default = "hello"];</code>
-       * @param value The bytes for defaultString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setDefaultStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-       * @return Whether the defaultBytes field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultBytes() {
-        return instance.hasDefaultBytes();
-      }
-      /**
-       * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-       * @return The defaultBytes.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getDefaultBytes() {
-        return instance.getDefaultBytes();
-      }
-      /**
-       * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-       * @param value The defaultBytes to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultBytes(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setDefaultBytes(value);
-        return this;
-      }
-      /**
-       * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultBytes() {
-        copyOnWrite();
-        instance.clearDefaultBytes();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-       * @return Whether the defaultNestedEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultNestedEnum() {
-        return instance.hasDefaultNestedEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-       * @return The defaultNestedEnum.
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum getDefaultNestedEnum() {
-        return instance.getDefaultNestedEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-       * @param value The enum numeric value on the wire for defaultNestedEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultNestedEnum(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum value) {
-        copyOnWrite();
-        instance.setDefaultNestedEnum(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultNestedEnum() {
-        copyOnWrite();
-        instance.clearDefaultNestedEnum();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnumLite default_foreign_enum = 82 [default = FOREIGN_LITE_BAR];</code>
-       * @return Whether the defaultForeignEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultForeignEnum() {
-        return instance.hasDefaultForeignEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnumLite default_foreign_enum = 82 [default = FOREIGN_LITE_BAR];</code>
-       * @return The defaultForeignEnum.
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.ForeignEnumLite getDefaultForeignEnum() {
-        return instance.getDefaultForeignEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnumLite default_foreign_enum = 82 [default = FOREIGN_LITE_BAR];</code>
-       * @param value The enum numeric value on the wire for defaultForeignEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultForeignEnum(com.google.protobuf.UnittestLite.ForeignEnumLite value) {
-        copyOnWrite();
-        instance.setDefaultForeignEnum(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnumLite default_foreign_enum = 82 [default = FOREIGN_LITE_BAR];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultForeignEnum() {
-        copyOnWrite();
-        instance.clearDefaultForeignEnum();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest_import.ImportEnumLite default_import_enum = 83 [default = IMPORT_LITE_BAR];</code>
-       * @return Whether the defaultImportEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultImportEnum() {
-        return instance.hasDefaultImportEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportEnumLite default_import_enum = 83 [default = IMPORT_LITE_BAR];</code>
-       * @return The defaultImportEnum.
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestImportLite.ImportEnumLite getDefaultImportEnum() {
-        return instance.getDefaultImportEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportEnumLite default_import_enum = 83 [default = IMPORT_LITE_BAR];</code>
-       * @param value The enum numeric value on the wire for defaultImportEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultImportEnum(com.google.protobuf.UnittestImportLite.ImportEnumLite value) {
-        copyOnWrite();
-        instance.setDefaultImportEnum(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportEnumLite default_import_enum = 83 [default = IMPORT_LITE_BAR];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultImportEnum() {
-        copyOnWrite();
-        instance.clearDefaultImportEnum();
-        return this;
-      }
-
-      /**
-       * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-       * @return Whether the defaultStringPiece field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultStringPiece() {
-        return instance.hasDefaultStringPiece();
-      }
-      /**
-       * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-       * @return The defaultStringPiece.
-       */
-      @java.lang.Override
-      public java.lang.String getDefaultStringPiece() {
-        return instance.getDefaultStringPiece();
-      }
-      /**
-       * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-       * @return The bytes for defaultStringPiece.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getDefaultStringPieceBytes() {
-        return instance.getDefaultStringPieceBytes();
-      }
-      /**
-       * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-       * @param value The defaultStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultStringPiece(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setDefaultStringPiece(value);
-        return this;
-      }
-      /**
-       * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultStringPiece() {
-        copyOnWrite();
-        instance.clearDefaultStringPiece();
-        return this;
-      }
-      /**
-       * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-       * @param value The bytes for defaultStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultStringPieceBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setDefaultStringPieceBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-       * @return Whether the defaultCord field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultCord() {
-        return instance.hasDefaultCord();
-      }
-      /**
-       * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-       * @return The defaultCord.
-       */
-      @java.lang.Override
-      public java.lang.String getDefaultCord() {
-        return instance.getDefaultCord();
-      }
-      /**
-       * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-       * @return The bytes for defaultCord.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getDefaultCordBytes() {
-        return instance.getDefaultCordBytes();
-      }
-      /**
-       * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-       * @param value The defaultCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultCord(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setDefaultCord(value);
-        return this;
-      }
-      /**
-       * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultCord() {
-        copyOnWrite();
-        instance.clearDefaultCord();
-        return this;
-      }
-      /**
-       * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-       * @param value The bytes for defaultCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultCordBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setDefaultCordBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>uint32 oneof_uint32 = 111;</code>
-       * @return Whether the oneofUint32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofUint32() {
-        return instance.hasOneofUint32();
-      }
-      /**
-       * <code>uint32 oneof_uint32 = 111;</code>
-       * @return The oneofUint32.
-       */
-      @java.lang.Override
-      public int getOneofUint32() {
-        return instance.getOneofUint32();
-      }
-      /**
-       * <code>uint32 oneof_uint32 = 111;</code>
-       * @param value The oneofUint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofUint32(int value) {
-        copyOnWrite();
-        instance.setOneofUint32(value);
-        return this;
-      }
-      /**
-       * <code>uint32 oneof_uint32 = 111;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofUint32() {
-        copyOnWrite();
-        instance.clearOneofUint32();
-        return this;
-      }
-
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_nested_message = 112;</code>
-       */
-      @java.lang.Override
-      public boolean hasOneofNestedMessage() {
-        return instance.hasOneofNestedMessage();
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_nested_message = 112;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage getOneofNestedMessage() {
-        return instance.getOneofNestedMessage();
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_nested_message = 112;</code>
-       */
-      public Builder setOneofNestedMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-        copyOnWrite();
-        instance.setOneofNestedMessage(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_nested_message = 112;</code>
-       */
-      public Builder setOneofNestedMessage(
-          com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOneofNestedMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_nested_message = 112;</code>
-       */
-      public Builder mergeOneofNestedMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-        copyOnWrite();
-        instance.mergeOneofNestedMessage(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_nested_message = 112;</code>
-       */
-      public Builder clearOneofNestedMessage() {
-        copyOnWrite();
-        instance.clearOneofNestedMessage();
-        return this;
-      }
-
-      /**
-       * <code>string oneof_string = 113;</code>
-       * @return Whether the oneofString field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofString() {
-        return instance.hasOneofString();
-      }
-      /**
-       * <code>string oneof_string = 113;</code>
-       * @return The oneofString.
-       */
-      @java.lang.Override
-      public java.lang.String getOneofString() {
-        return instance.getOneofString();
-      }
-      /**
-       * <code>string oneof_string = 113;</code>
-       * @return The bytes for oneofString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getOneofStringBytes() {
-        return instance.getOneofStringBytes();
-      }
-      /**
-       * <code>string oneof_string = 113;</code>
-       * @param value The oneofString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setOneofString(value);
-        return this;
-      }
-      /**
-       * <code>string oneof_string = 113;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofString() {
-        copyOnWrite();
-        instance.clearOneofString();
-        return this;
-      }
-      /**
-       * <code>string oneof_string = 113;</code>
-       * @param value The bytes for oneofString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOneofStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>bytes oneof_bytes = 114;</code>
-       * @return Whether the oneofBytes field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofBytes() {
-        return instance.hasOneofBytes();
-      }
-      /**
-       * <code>bytes oneof_bytes = 114;</code>
-       * @return The oneofBytes.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getOneofBytes() {
-        return instance.getOneofBytes();
-      }
-      /**
-       * <code>bytes oneof_bytes = 114;</code>
-       * @param value The oneofBytes to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofBytes(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOneofBytes(value);
-        return this;
-      }
-      /**
-       * <code>bytes oneof_bytes = 114;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofBytes() {
-        copyOnWrite();
-        instance.clearOneofBytes();
-        return this;
-      }
-
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_lazy_nested_message = 115 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public boolean hasOneofLazyNestedMessage() {
-        return instance.hasOneofLazyNestedMessage();
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_lazy_nested_message = 115 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage getOneofLazyNestedMessage() {
-        return instance.getOneofLazyNestedMessage();
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_lazy_nested_message = 115 [lazy = true];</code>
-       */
-      public Builder setOneofLazyNestedMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-        copyOnWrite();
-        instance.setOneofLazyNestedMessage(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_lazy_nested_message = 115 [lazy = true];</code>
-       */
-      public Builder setOneofLazyNestedMessage(
-          com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOneofLazyNestedMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_lazy_nested_message = 115 [lazy = true];</code>
-       */
-      public Builder mergeOneofLazyNestedMessage(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage value) {
-        copyOnWrite();
-        instance.mergeOneofLazyNestedMessage(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage oneof_lazy_nested_message = 115 [lazy = true];</code>
-       */
-      public Builder clearOneofLazyNestedMessage() {
-        copyOnWrite();
-        instance.clearOneofLazyNestedMessage();
-        return this;
-      }
-
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage2 oneof_nested_message2 = 117;</code>
-       */
-      @java.lang.Override
-      public boolean hasOneofNestedMessage2() {
-        return instance.hasOneofNestedMessage2();
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage2 oneof_nested_message2 = 117;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 getOneofNestedMessage2() {
-        return instance.getOneofNestedMessage2();
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage2 oneof_nested_message2 = 117;</code>
-       */
-      public Builder setOneofNestedMessage2(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 value) {
-        copyOnWrite();
-        instance.setOneofNestedMessage2(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage2 oneof_nested_message2 = 117;</code>
-       */
-      public Builder setOneofNestedMessage2(
-          com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOneofNestedMessage2(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage2 oneof_nested_message2 = 117;</code>
-       */
-      public Builder mergeOneofNestedMessage2(com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2 value) {
-        copyOnWrite();
-        instance.mergeOneofNestedMessage2(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite.NestedMessage2 oneof_nested_message2 = 117;</code>
-       */
-      public Builder clearOneofNestedMessage2() {
-        copyOnWrite();
-        instance.clearOneofNestedMessage2();
-        return this;
-      }
-
-      /**
-       * <pre>
-       * Tests toString for non-repeated fields with a list suffix
-       * </pre>
-       *
-       * <code>optional int32 deceptively_named_list = 116;</code>
-       * @return Whether the deceptivelyNamedList field is set.
-       */
-      @java.lang.Override
-      public boolean hasDeceptivelyNamedList() {
-        return instance.hasDeceptivelyNamedList();
-      }
-      /**
-       * <pre>
-       * Tests toString for non-repeated fields with a list suffix
-       * </pre>
-       *
-       * <code>optional int32 deceptively_named_list = 116;</code>
-       * @return The deceptivelyNamedList.
-       */
-      @java.lang.Override
-      public int getDeceptivelyNamedList() {
-        return instance.getDeceptivelyNamedList();
-      }
-      /**
-       * <pre>
-       * Tests toString for non-repeated fields with a list suffix
-       * </pre>
-       *
-       * <code>optional int32 deceptively_named_list = 116;</code>
-       * @param value The deceptivelyNamedList to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDeceptivelyNamedList(int value) {
-        copyOnWrite();
-        instance.setDeceptivelyNamedList(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Tests toString for non-repeated fields with a list suffix
-       * </pre>
-       *
-       * <code>optional int32 deceptively_named_list = 116;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDeceptivelyNamedList() {
-        copyOnWrite();
-        instance.clearDeceptivelyNamedList();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestAllTypesLite)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.TestAllTypesLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "oneofField_",
-              "oneofFieldCase_",
-              "bitField0_",
-              "bitField1_",
-              "optionalInt32_",
-              "optionalInt64_",
-              "optionalUint32_",
-              "optionalUint64_",
-              "optionalSint32_",
-              "optionalSint64_",
-              "optionalFixed32_",
-              "optionalFixed64_",
-              "optionalSfixed32_",
-              "optionalSfixed64_",
-              "optionalFloat_",
-              "optionalDouble_",
-              "optionalBool_",
-              "optionalString_",
-              "optionalBytes_",
-              "optionalGroup_",
-              "optionalNestedMessage_",
-              "optionalForeignMessage_",
-              "optionalImportMessage_",
-              "optionalNestedEnum_",
-              com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum.internalGetVerifier(),
-              "optionalForeignEnum_",
-              com.google.protobuf.UnittestLite.ForeignEnumLite.internalGetVerifier(),
-              "optionalImportEnum_",
-              com.google.protobuf.UnittestImportLite.ImportEnumLite.internalGetVerifier(),
-              "optionalStringPiece_",
-              "optionalCord_",
-              "optionalPublicImportMessage_",
-              "optionalLazyMessage_",
-              "repeatedInt32_",
-              "repeatedInt64_",
-              "repeatedUint32_",
-              "repeatedUint64_",
-              "repeatedSint32_",
-              "repeatedSint64_",
-              "repeatedFixed32_",
-              "repeatedFixed64_",
-              "repeatedSfixed32_",
-              "repeatedSfixed64_",
-              "repeatedFloat_",
-              "repeatedDouble_",
-              "repeatedBool_",
-              "repeatedString_",
-              "repeatedBytes_",
-              "repeatedGroup_",
-              com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup.class,
-              "repeatedNestedMessage_",
-              com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.class,
-              "repeatedForeignMessage_",
-              com.google.protobuf.UnittestLite.ForeignMessageLite.class,
-              "repeatedImportMessage_",
-              com.google.protobuf.UnittestImportLite.ImportMessageLite.class,
-              "repeatedNestedEnum_",
-              com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum.internalGetVerifier(),
-              "repeatedForeignEnum_",
-              com.google.protobuf.UnittestLite.ForeignEnumLite.internalGetVerifier(),
-              "repeatedImportEnum_",
-              com.google.protobuf.UnittestImportLite.ImportEnumLite.internalGetVerifier(),
-              "repeatedStringPiece_",
-              "repeatedCord_",
-              "repeatedLazyMessage_",
-              com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.class,
-              "defaultInt32_",
-              "defaultInt64_",
-              "defaultUint32_",
-              "defaultUint64_",
-              "defaultSint32_",
-              "defaultSint64_",
-              "defaultFixed32_",
-              "defaultFixed64_",
-              "defaultSfixed32_",
-              "defaultSfixed64_",
-              "defaultFloat_",
-              "defaultDouble_",
-              "defaultBool_",
-              "defaultString_",
-              "defaultBytes_",
-              "defaultNestedEnum_",
-              com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum.internalGetVerifier(),
-              "defaultForeignEnum_",
-              com.google.protobuf.UnittestLite.ForeignEnumLite.internalGetVerifier(),
-              "defaultImportEnum_",
-              com.google.protobuf.UnittestImportLite.ImportEnumLite.internalGetVerifier(),
-              "defaultStringPiece_",
-              "defaultCord_",
-              com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.class,
-              com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.class,
-              "deceptivelyNamedList_",
-              com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2.class,
-            };
-            java.lang.String info =
-                "\u0001N\u0001\u0002\u0001uN\u0000\u0019\u0000\u0001\u1004\u0000\u0002\u1002\u0001" +
-                "\u0003\u100b\u0002\u0004\u1003\u0003\u0005\u100f\u0004\u0006\u1010\u0005\u0007\u1006" +
-                "\u0006\b\u1005\u0007\t\u100d\b\n\u100e\t\u000b\u1001\n\f\u1000\u000b\r\u1007\f\u000e" +
-                "\u1008\r\u000f\u100a\u000e\u0010\u1011\u000f\u0012\u1009\u0010\u0013\u1009\u0011" +
-                "\u0014\u1009\u0012\u0015\u100c\u0013\u0016\u100c\u0014\u0017\u100c\u0015\u0018\u1008" +
-                "\u0016\u0019\u1008\u0017\u001a\u1009\u0018\u001b\u1009\u0019\u001f\u0016 \u0014!" +
-                "\u001d\"\u0015#!$\"%\u0018&\u0017\'\u001f( )\u0013*\u0012+\u0019,\u001a-\u001c.1" +
-                "0\u001b1\u001b2\u001b3\u001e4\u001e5\u001e6\u001a7\u001a9\u001b=\u1004\u001a>\u1002" +
-                "\u001b?\u100b\u001c@\u1003\u001dA\u100f\u001eB\u1010\u001fC\u1006 D\u1005!E\u100d" +
-                "\"F\u100e#G\u1001$H\u1000%I\u1007&J\u1008\'K\u100a(Q\u100c)R\u100c*S\u100c+T\u1008" +
-                ",U\u1008-o\u103e\u0000p\u103c\u0000q\u103b\u0000r\u103d\u0000s\u103c\u0000t\u1004" +
-                "4u\u103c\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestAllTypesLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.TestAllTypesLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestAllTypesLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestAllTypesLite)
-    private static final com.google.protobuf.UnittestLite.TestAllTypesLite DEFAULT_INSTANCE;
-    static {
-      TestAllTypesLite defaultInstance = new TestAllTypesLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestAllTypesLite.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.TestAllTypesLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestAllTypesLite> PARSER;
-
-    public static com.google.protobuf.Parser<TestAllTypesLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface ForeignMessageLiteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.ForeignMessageLite)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional int32 c = 1;</code>
-     * @return Whether the c field is set.
-     */
-    boolean hasC();
-    /**
-     * <code>optional int32 c = 1;</code>
-     * @return The c.
-     */
-    int getC();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.ForeignMessageLite}
-   */
-  public  static final class ForeignMessageLite extends
-      com.google.protobuf.GeneratedMessageLite<
-          ForeignMessageLite, ForeignMessageLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.ForeignMessageLite)
-      ForeignMessageLiteOrBuilder {
-    private ForeignMessageLite() {
-    }
-    private int bitField0_;
-    public static final int C_FIELD_NUMBER = 1;
-    private int c_;
-    /**
-     * <code>optional int32 c = 1;</code>
-     * @return Whether the c field is set.
-     */
-    @java.lang.Override
-    public boolean hasC() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 c = 1;</code>
-     * @return The c.
-     */
-    @java.lang.Override
-    public int getC() {
-      return c_;
-    }
-    /**
-     * <code>optional int32 c = 1;</code>
-     * @param value The c to set.
-     */
-    private void setC(int value) {
-      bitField0_ |= 0x00000001;
-      c_ = value;
-    }
-    /**
-     * <code>optional int32 c = 1;</code>
-     */
-    private void clearC() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      c_ = 0;
-    }
-
-    public static com.google.protobuf.UnittestLite.ForeignMessageLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.ForeignMessageLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.ForeignMessageLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.ForeignMessageLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.ForeignMessageLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.ForeignMessageLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.ForeignMessageLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.ForeignMessageLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.ForeignMessageLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.ForeignMessageLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.ForeignMessageLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.ForeignMessageLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.ForeignMessageLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.ForeignMessageLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.UnittestLite.ForeignMessageLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.ForeignMessageLite)
-        com.google.protobuf.UnittestLite.ForeignMessageLiteOrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.ForeignMessageLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int32 c = 1;</code>
-       * @return Whether the c field is set.
-       */
-      @java.lang.Override
-      public boolean hasC() {
-        return instance.hasC();
-      }
-      /**
-       * <code>optional int32 c = 1;</code>
-       * @return The c.
-       */
-      @java.lang.Override
-      public int getC() {
-        return instance.getC();
-      }
-      /**
-       * <code>optional int32 c = 1;</code>
-       * @param value The c to set.
-       * @return This builder for chaining.
-       */
-      public Builder setC(int value) {
-        copyOnWrite();
-        instance.setC(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 c = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearC() {
-        copyOnWrite();
-        instance.clearC();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.ForeignMessageLite)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.ForeignMessageLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "c_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1004\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.ForeignMessageLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.ForeignMessageLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.ForeignMessageLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.ForeignMessageLite)
-    private static final com.google.protobuf.UnittestLite.ForeignMessageLite DEFAULT_INSTANCE;
-    static {
-      ForeignMessageLite defaultInstance = new ForeignMessageLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        ForeignMessageLite.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.ForeignMessageLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<ForeignMessageLite> PARSER;
-
-    public static com.google.protobuf.Parser<ForeignMessageLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestPackedTypesLiteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestPackedTypesLite)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @return A list containing the packedInt32.
-     */
-    java.util.List<java.lang.Integer> getPackedInt32List();
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @return The count of packedInt32.
-     */
-    int getPackedInt32Count();
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedInt32 at the given index.
-     */
-    int getPackedInt32(int index);
-
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @return A list containing the packedInt64.
-     */
-    java.util.List<java.lang.Long> getPackedInt64List();
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @return The count of packedInt64.
-     */
-    int getPackedInt64Count();
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedInt64 at the given index.
-     */
-    long getPackedInt64(int index);
-
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @return A list containing the packedUint32.
-     */
-    java.util.List<java.lang.Integer> getPackedUint32List();
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @return The count of packedUint32.
-     */
-    int getPackedUint32Count();
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedUint32 at the given index.
-     */
-    int getPackedUint32(int index);
-
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @return A list containing the packedUint64.
-     */
-    java.util.List<java.lang.Long> getPackedUint64List();
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @return The count of packedUint64.
-     */
-    int getPackedUint64Count();
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedUint64 at the given index.
-     */
-    long getPackedUint64(int index);
-
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @return A list containing the packedSint32.
-     */
-    java.util.List<java.lang.Integer> getPackedSint32List();
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @return The count of packedSint32.
-     */
-    int getPackedSint32Count();
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSint32 at the given index.
-     */
-    int getPackedSint32(int index);
-
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @return A list containing the packedSint64.
-     */
-    java.util.List<java.lang.Long> getPackedSint64List();
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @return The count of packedSint64.
-     */
-    int getPackedSint64Count();
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSint64 at the given index.
-     */
-    long getPackedSint64(int index);
-
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @return A list containing the packedFixed32.
-     */
-    java.util.List<java.lang.Integer> getPackedFixed32List();
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @return The count of packedFixed32.
-     */
-    int getPackedFixed32Count();
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedFixed32 at the given index.
-     */
-    int getPackedFixed32(int index);
-
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @return A list containing the packedFixed64.
-     */
-    java.util.List<java.lang.Long> getPackedFixed64List();
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @return The count of packedFixed64.
-     */
-    int getPackedFixed64Count();
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedFixed64 at the given index.
-     */
-    long getPackedFixed64(int index);
-
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @return A list containing the packedSfixed32.
-     */
-    java.util.List<java.lang.Integer> getPackedSfixed32List();
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @return The count of packedSfixed32.
-     */
-    int getPackedSfixed32Count();
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSfixed32 at the given index.
-     */
-    int getPackedSfixed32(int index);
-
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @return A list containing the packedSfixed64.
-     */
-    java.util.List<java.lang.Long> getPackedSfixed64List();
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @return The count of packedSfixed64.
-     */
-    int getPackedSfixed64Count();
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSfixed64 at the given index.
-     */
-    long getPackedSfixed64(int index);
-
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @return A list containing the packedFloat.
-     */
-    java.util.List<java.lang.Float> getPackedFloatList();
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @return The count of packedFloat.
-     */
-    int getPackedFloatCount();
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedFloat at the given index.
-     */
-    float getPackedFloat(int index);
-
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @return A list containing the packedDouble.
-     */
-    java.util.List<java.lang.Double> getPackedDoubleList();
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @return The count of packedDouble.
-     */
-    int getPackedDoubleCount();
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedDouble at the given index.
-     */
-    double getPackedDouble(int index);
-
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @return A list containing the packedBool.
-     */
-    java.util.List<java.lang.Boolean> getPackedBoolList();
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @return The count of packedBool.
-     */
-    int getPackedBoolCount();
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedBool at the given index.
-     */
-    boolean getPackedBool(int index);
-
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-     * @return A list containing the packedEnum.
-     */
-    java.util.List<com.google.protobuf.UnittestLite.ForeignEnumLite> getPackedEnumList();
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-     * @return The count of packedEnum.
-     */
-    int getPackedEnumCount();
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedEnum at the given index.
-     */
-    com.google.protobuf.UnittestLite.ForeignEnumLite getPackedEnum(int index);
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestPackedTypesLite}
-   */
-  public  static final class TestPackedTypesLite extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestPackedTypesLite, TestPackedTypesLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestPackedTypesLite)
-      TestPackedTypesLiteOrBuilder {
-    private TestPackedTypesLite() {
-      packedInt32_ = emptyIntList();
-      packedInt64_ = emptyLongList();
-      packedUint32_ = emptyIntList();
-      packedUint64_ = emptyLongList();
-      packedSint32_ = emptyIntList();
-      packedSint64_ = emptyLongList();
-      packedFixed32_ = emptyIntList();
-      packedFixed64_ = emptyLongList();
-      packedSfixed32_ = emptyIntList();
-      packedSfixed64_ = emptyLongList();
-      packedFloat_ = emptyFloatList();
-      packedDouble_ = emptyDoubleList();
-      packedBool_ = emptyBooleanList();
-      packedEnum_ = emptyIntList();
-    }
-    public static final int PACKED_INT32_FIELD_NUMBER = 90;
-    private com.google.protobuf.Internal.IntList packedInt32_;
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @return A list containing the packedInt32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getPackedInt32List() {
-      return packedInt32_;
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @return The count of packedInt32.
-     */
-    @java.lang.Override
-    public int getPackedInt32Count() {
-      return packedInt32_.size();
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedInt32 at the given index.
-     */
-    @java.lang.Override
-    public int getPackedInt32(int index) {
-      return packedInt32_.getInt(index);
-    }
-    private int packedInt32MemoizedSerializedSize = -1;
-    private void ensurePackedInt32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedInt32_;
-      if (!tmp.isModifiable()) {
-        packedInt32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedInt32 to set.
-     */
-    private void setPackedInt32(
-        int index, int value) {
-      ensurePackedInt32IsMutable();
-      packedInt32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param value The packedInt32 to add.
-     */
-    private void addPackedInt32(int value) {
-      ensurePackedInt32IsMutable();
-      packedInt32_.addInt(value);
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param values The packedInt32 to add.
-     */
-    private void addAllPackedInt32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensurePackedInt32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedInt32_);
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     */
-    private void clearPackedInt32() {
-      packedInt32_ = emptyIntList();
-    }
-
-    public static final int PACKED_INT64_FIELD_NUMBER = 91;
-    private com.google.protobuf.Internal.LongList packedInt64_;
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @return A list containing the packedInt64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getPackedInt64List() {
-      return packedInt64_;
-    }
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @return The count of packedInt64.
-     */
-    @java.lang.Override
-    public int getPackedInt64Count() {
-      return packedInt64_.size();
-    }
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedInt64 at the given index.
-     */
-    @java.lang.Override
-    public long getPackedInt64(int index) {
-      return packedInt64_.getLong(index);
-    }
-    private int packedInt64MemoizedSerializedSize = -1;
-    private void ensurePackedInt64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = packedInt64_;
-      if (!tmp.isModifiable()) {
-        packedInt64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedInt64 to set.
-     */
-    private void setPackedInt64(
-        int index, long value) {
-      ensurePackedInt64IsMutable();
-      packedInt64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param value The packedInt64 to add.
-     */
-    private void addPackedInt64(long value) {
-      ensurePackedInt64IsMutable();
-      packedInt64_.addLong(value);
-    }
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param values The packedInt64 to add.
-     */
-    private void addAllPackedInt64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensurePackedInt64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedInt64_);
-    }
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     */
-    private void clearPackedInt64() {
-      packedInt64_ = emptyLongList();
-    }
-
-    public static final int PACKED_UINT32_FIELD_NUMBER = 92;
-    private com.google.protobuf.Internal.IntList packedUint32_;
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @return A list containing the packedUint32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getPackedUint32List() {
-      return packedUint32_;
-    }
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @return The count of packedUint32.
-     */
-    @java.lang.Override
-    public int getPackedUint32Count() {
-      return packedUint32_.size();
-    }
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedUint32 at the given index.
-     */
-    @java.lang.Override
-    public int getPackedUint32(int index) {
-      return packedUint32_.getInt(index);
-    }
-    private int packedUint32MemoizedSerializedSize = -1;
-    private void ensurePackedUint32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedUint32_;
-      if (!tmp.isModifiable()) {
-        packedUint32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedUint32 to set.
-     */
-    private void setPackedUint32(
-        int index, int value) {
-      ensurePackedUint32IsMutable();
-      packedUint32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param value The packedUint32 to add.
-     */
-    private void addPackedUint32(int value) {
-      ensurePackedUint32IsMutable();
-      packedUint32_.addInt(value);
-    }
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param values The packedUint32 to add.
-     */
-    private void addAllPackedUint32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensurePackedUint32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedUint32_);
-    }
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     */
-    private void clearPackedUint32() {
-      packedUint32_ = emptyIntList();
-    }
-
-    public static final int PACKED_UINT64_FIELD_NUMBER = 93;
-    private com.google.protobuf.Internal.LongList packedUint64_;
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @return A list containing the packedUint64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getPackedUint64List() {
-      return packedUint64_;
-    }
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @return The count of packedUint64.
-     */
-    @java.lang.Override
-    public int getPackedUint64Count() {
-      return packedUint64_.size();
-    }
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedUint64 at the given index.
-     */
-    @java.lang.Override
-    public long getPackedUint64(int index) {
-      return packedUint64_.getLong(index);
-    }
-    private int packedUint64MemoizedSerializedSize = -1;
-    private void ensurePackedUint64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = packedUint64_;
-      if (!tmp.isModifiable()) {
-        packedUint64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedUint64 to set.
-     */
-    private void setPackedUint64(
-        int index, long value) {
-      ensurePackedUint64IsMutable();
-      packedUint64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param value The packedUint64 to add.
-     */
-    private void addPackedUint64(long value) {
-      ensurePackedUint64IsMutable();
-      packedUint64_.addLong(value);
-    }
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param values The packedUint64 to add.
-     */
-    private void addAllPackedUint64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensurePackedUint64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedUint64_);
-    }
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     */
-    private void clearPackedUint64() {
-      packedUint64_ = emptyLongList();
-    }
-
-    public static final int PACKED_SINT32_FIELD_NUMBER = 94;
-    private com.google.protobuf.Internal.IntList packedSint32_;
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @return A list containing the packedSint32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getPackedSint32List() {
-      return packedSint32_;
-    }
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @return The count of packedSint32.
-     */
-    @java.lang.Override
-    public int getPackedSint32Count() {
-      return packedSint32_.size();
-    }
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSint32 at the given index.
-     */
-    @java.lang.Override
-    public int getPackedSint32(int index) {
-      return packedSint32_.getInt(index);
-    }
-    private int packedSint32MemoizedSerializedSize = -1;
-    private void ensurePackedSint32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedSint32_;
-      if (!tmp.isModifiable()) {
-        packedSint32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSint32 to set.
-     */
-    private void setPackedSint32(
-        int index, int value) {
-      ensurePackedSint32IsMutable();
-      packedSint32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param value The packedSint32 to add.
-     */
-    private void addPackedSint32(int value) {
-      ensurePackedSint32IsMutable();
-      packedSint32_.addInt(value);
-    }
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param values The packedSint32 to add.
-     */
-    private void addAllPackedSint32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensurePackedSint32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedSint32_);
-    }
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     */
-    private void clearPackedSint32() {
-      packedSint32_ = emptyIntList();
-    }
-
-    public static final int PACKED_SINT64_FIELD_NUMBER = 95;
-    private com.google.protobuf.Internal.LongList packedSint64_;
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @return A list containing the packedSint64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getPackedSint64List() {
-      return packedSint64_;
-    }
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @return The count of packedSint64.
-     */
-    @java.lang.Override
-    public int getPackedSint64Count() {
-      return packedSint64_.size();
-    }
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSint64 at the given index.
-     */
-    @java.lang.Override
-    public long getPackedSint64(int index) {
-      return packedSint64_.getLong(index);
-    }
-    private int packedSint64MemoizedSerializedSize = -1;
-    private void ensurePackedSint64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = packedSint64_;
-      if (!tmp.isModifiable()) {
-        packedSint64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSint64 to set.
-     */
-    private void setPackedSint64(
-        int index, long value) {
-      ensurePackedSint64IsMutable();
-      packedSint64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param value The packedSint64 to add.
-     */
-    private void addPackedSint64(long value) {
-      ensurePackedSint64IsMutable();
-      packedSint64_.addLong(value);
-    }
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param values The packedSint64 to add.
-     */
-    private void addAllPackedSint64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensurePackedSint64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedSint64_);
-    }
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     */
-    private void clearPackedSint64() {
-      packedSint64_ = emptyLongList();
-    }
-
-    public static final int PACKED_FIXED32_FIELD_NUMBER = 96;
-    private com.google.protobuf.Internal.IntList packedFixed32_;
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @return A list containing the packedFixed32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getPackedFixed32List() {
-      return packedFixed32_;
-    }
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @return The count of packedFixed32.
-     */
-    @java.lang.Override
-    public int getPackedFixed32Count() {
-      return packedFixed32_.size();
-    }
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedFixed32 at the given index.
-     */
-    @java.lang.Override
-    public int getPackedFixed32(int index) {
-      return packedFixed32_.getInt(index);
-    }
-    private int packedFixed32MemoizedSerializedSize = -1;
-    private void ensurePackedFixed32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedFixed32_;
-      if (!tmp.isModifiable()) {
-        packedFixed32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedFixed32 to set.
-     */
-    private void setPackedFixed32(
-        int index, int value) {
-      ensurePackedFixed32IsMutable();
-      packedFixed32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param value The packedFixed32 to add.
-     */
-    private void addPackedFixed32(int value) {
-      ensurePackedFixed32IsMutable();
-      packedFixed32_.addInt(value);
-    }
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param values The packedFixed32 to add.
-     */
-    private void addAllPackedFixed32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensurePackedFixed32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedFixed32_);
-    }
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     */
-    private void clearPackedFixed32() {
-      packedFixed32_ = emptyIntList();
-    }
-
-    public static final int PACKED_FIXED64_FIELD_NUMBER = 97;
-    private com.google.protobuf.Internal.LongList packedFixed64_;
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @return A list containing the packedFixed64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getPackedFixed64List() {
-      return packedFixed64_;
-    }
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @return The count of packedFixed64.
-     */
-    @java.lang.Override
-    public int getPackedFixed64Count() {
-      return packedFixed64_.size();
-    }
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedFixed64 at the given index.
-     */
-    @java.lang.Override
-    public long getPackedFixed64(int index) {
-      return packedFixed64_.getLong(index);
-    }
-    private int packedFixed64MemoizedSerializedSize = -1;
-    private void ensurePackedFixed64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = packedFixed64_;
-      if (!tmp.isModifiable()) {
-        packedFixed64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedFixed64 to set.
-     */
-    private void setPackedFixed64(
-        int index, long value) {
-      ensurePackedFixed64IsMutable();
-      packedFixed64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param value The packedFixed64 to add.
-     */
-    private void addPackedFixed64(long value) {
-      ensurePackedFixed64IsMutable();
-      packedFixed64_.addLong(value);
-    }
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param values The packedFixed64 to add.
-     */
-    private void addAllPackedFixed64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensurePackedFixed64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedFixed64_);
-    }
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     */
-    private void clearPackedFixed64() {
-      packedFixed64_ = emptyLongList();
-    }
-
-    public static final int PACKED_SFIXED32_FIELD_NUMBER = 98;
-    private com.google.protobuf.Internal.IntList packedSfixed32_;
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @return A list containing the packedSfixed32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getPackedSfixed32List() {
-      return packedSfixed32_;
-    }
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @return The count of packedSfixed32.
-     */
-    @java.lang.Override
-    public int getPackedSfixed32Count() {
-      return packedSfixed32_.size();
-    }
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSfixed32 at the given index.
-     */
-    @java.lang.Override
-    public int getPackedSfixed32(int index) {
-      return packedSfixed32_.getInt(index);
-    }
-    private int packedSfixed32MemoizedSerializedSize = -1;
-    private void ensurePackedSfixed32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedSfixed32_;
-      if (!tmp.isModifiable()) {
-        packedSfixed32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSfixed32 to set.
-     */
-    private void setPackedSfixed32(
-        int index, int value) {
-      ensurePackedSfixed32IsMutable();
-      packedSfixed32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param value The packedSfixed32 to add.
-     */
-    private void addPackedSfixed32(int value) {
-      ensurePackedSfixed32IsMutable();
-      packedSfixed32_.addInt(value);
-    }
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param values The packedSfixed32 to add.
-     */
-    private void addAllPackedSfixed32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensurePackedSfixed32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedSfixed32_);
-    }
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     */
-    private void clearPackedSfixed32() {
-      packedSfixed32_ = emptyIntList();
-    }
-
-    public static final int PACKED_SFIXED64_FIELD_NUMBER = 99;
-    private com.google.protobuf.Internal.LongList packedSfixed64_;
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @return A list containing the packedSfixed64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getPackedSfixed64List() {
-      return packedSfixed64_;
-    }
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @return The count of packedSfixed64.
-     */
-    @java.lang.Override
-    public int getPackedSfixed64Count() {
-      return packedSfixed64_.size();
-    }
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSfixed64 at the given index.
-     */
-    @java.lang.Override
-    public long getPackedSfixed64(int index) {
-      return packedSfixed64_.getLong(index);
-    }
-    private int packedSfixed64MemoizedSerializedSize = -1;
-    private void ensurePackedSfixed64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = packedSfixed64_;
-      if (!tmp.isModifiable()) {
-        packedSfixed64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSfixed64 to set.
-     */
-    private void setPackedSfixed64(
-        int index, long value) {
-      ensurePackedSfixed64IsMutable();
-      packedSfixed64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param value The packedSfixed64 to add.
-     */
-    private void addPackedSfixed64(long value) {
-      ensurePackedSfixed64IsMutable();
-      packedSfixed64_.addLong(value);
-    }
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param values The packedSfixed64 to add.
-     */
-    private void addAllPackedSfixed64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensurePackedSfixed64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedSfixed64_);
-    }
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     */
-    private void clearPackedSfixed64() {
-      packedSfixed64_ = emptyLongList();
-    }
-
-    public static final int PACKED_FLOAT_FIELD_NUMBER = 100;
-    private com.google.protobuf.Internal.FloatList packedFloat_;
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @return A list containing the packedFloat.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Float>
-        getPackedFloatList() {
-      return packedFloat_;
-    }
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @return The count of packedFloat.
-     */
-    @java.lang.Override
-    public int getPackedFloatCount() {
-      return packedFloat_.size();
-    }
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedFloat at the given index.
-     */
-    @java.lang.Override
-    public float getPackedFloat(int index) {
-      return packedFloat_.getFloat(index);
-    }
-    private int packedFloatMemoizedSerializedSize = -1;
-    private void ensurePackedFloatIsMutable() {
-      com.google.protobuf.Internal.FloatList tmp = packedFloat_;
-      if (!tmp.isModifiable()) {
-        packedFloat_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedFloat to set.
-     */
-    private void setPackedFloat(
-        int index, float value) {
-      ensurePackedFloatIsMutable();
-      packedFloat_.setFloat(index, value);
-    }
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param value The packedFloat to add.
-     */
-    private void addPackedFloat(float value) {
-      ensurePackedFloatIsMutable();
-      packedFloat_.addFloat(value);
-    }
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param values The packedFloat to add.
-     */
-    private void addAllPackedFloat(
-        java.lang.Iterable<? extends java.lang.Float> values) {
-      ensurePackedFloatIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedFloat_);
-    }
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     */
-    private void clearPackedFloat() {
-      packedFloat_ = emptyFloatList();
-    }
-
-    public static final int PACKED_DOUBLE_FIELD_NUMBER = 101;
-    private com.google.protobuf.Internal.DoubleList packedDouble_;
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @return A list containing the packedDouble.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Double>
-        getPackedDoubleList() {
-      return packedDouble_;
-    }
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @return The count of packedDouble.
-     */
-    @java.lang.Override
-    public int getPackedDoubleCount() {
-      return packedDouble_.size();
-    }
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedDouble at the given index.
-     */
-    @java.lang.Override
-    public double getPackedDouble(int index) {
-      return packedDouble_.getDouble(index);
-    }
-    private int packedDoubleMemoizedSerializedSize = -1;
-    private void ensurePackedDoubleIsMutable() {
-      com.google.protobuf.Internal.DoubleList tmp = packedDouble_;
-      if (!tmp.isModifiable()) {
-        packedDouble_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedDouble to set.
-     */
-    private void setPackedDouble(
-        int index, double value) {
-      ensurePackedDoubleIsMutable();
-      packedDouble_.setDouble(index, value);
-    }
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param value The packedDouble to add.
-     */
-    private void addPackedDouble(double value) {
-      ensurePackedDoubleIsMutable();
-      packedDouble_.addDouble(value);
-    }
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param values The packedDouble to add.
-     */
-    private void addAllPackedDouble(
-        java.lang.Iterable<? extends java.lang.Double> values) {
-      ensurePackedDoubleIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedDouble_);
-    }
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     */
-    private void clearPackedDouble() {
-      packedDouble_ = emptyDoubleList();
-    }
-
-    public static final int PACKED_BOOL_FIELD_NUMBER = 102;
-    private com.google.protobuf.Internal.BooleanList packedBool_;
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @return A list containing the packedBool.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Boolean>
-        getPackedBoolList() {
-      return packedBool_;
-    }
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @return The count of packedBool.
-     */
-    @java.lang.Override
-    public int getPackedBoolCount() {
-      return packedBool_.size();
-    }
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedBool at the given index.
-     */
-    @java.lang.Override
-    public boolean getPackedBool(int index) {
-      return packedBool_.getBoolean(index);
-    }
-    private int packedBoolMemoizedSerializedSize = -1;
-    private void ensurePackedBoolIsMutable() {
-      com.google.protobuf.Internal.BooleanList tmp = packedBool_;
-      if (!tmp.isModifiable()) {
-        packedBool_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedBool to set.
-     */
-    private void setPackedBool(
-        int index, boolean value) {
-      ensurePackedBoolIsMutable();
-      packedBool_.setBoolean(index, value);
-    }
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param value The packedBool to add.
-     */
-    private void addPackedBool(boolean value) {
-      ensurePackedBoolIsMutable();
-      packedBool_.addBoolean(value);
-    }
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param values The packedBool to add.
-     */
-    private void addAllPackedBool(
-        java.lang.Iterable<? extends java.lang.Boolean> values) {
-      ensurePackedBoolIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedBool_);
-    }
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     */
-    private void clearPackedBool() {
-      packedBool_ = emptyBooleanList();
-    }
-
-    public static final int PACKED_ENUM_FIELD_NUMBER = 103;
-    private com.google.protobuf.Internal.IntList packedEnum_;
-    private static final com.google.protobuf.Internal.ListAdapter.Converter<
-        java.lang.Integer, com.google.protobuf.UnittestLite.ForeignEnumLite> packedEnum_converter_ =
-            new com.google.protobuf.Internal.ListAdapter.Converter<
-                java.lang.Integer, com.google.protobuf.UnittestLite.ForeignEnumLite>() {
-              @java.lang.Override
-              public com.google.protobuf.UnittestLite.ForeignEnumLite convert(java.lang.Integer from) {
-                com.google.protobuf.UnittestLite.ForeignEnumLite result = com.google.protobuf.UnittestLite.ForeignEnumLite.forNumber(from);
-                return result == null ? com.google.protobuf.UnittestLite.ForeignEnumLite.FOREIGN_LITE_FOO : result;
-              }
-            };
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-     * @return A list containing the packedEnum.
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.UnittestLite.ForeignEnumLite> getPackedEnumList() {
-      return new com.google.protobuf.Internal.ListAdapter<
-          java.lang.Integer, com.google.protobuf.UnittestLite.ForeignEnumLite>(packedEnum_, packedEnum_converter_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-     * @return The count of packedEnum.
-     */
-    @java.lang.Override
-    public int getPackedEnumCount() {
-      return packedEnum_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedEnum at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.ForeignEnumLite getPackedEnum(int index) {
-      return packedEnum_converter_.convert(packedEnum_.getInt(index));
-    }
-    private int packedEnumMemoizedSerializedSize;
-    private void ensurePackedEnumIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedEnum_;
-      if (!tmp.isModifiable()) {
-        packedEnum_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedEnum to set.
-     */
-    private void setPackedEnum(
-        int index, com.google.protobuf.UnittestLite.ForeignEnumLite value) {
-      value.getClass();
-  ensurePackedEnumIsMutable();
-      packedEnum_.setInt(index, value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-     * @param value The packedEnum to add.
-     */
-    private void addPackedEnum(com.google.protobuf.UnittestLite.ForeignEnumLite value) {
-      value.getClass();
-  ensurePackedEnumIsMutable();
-      packedEnum_.addInt(value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-     * @param values The packedEnum to add.
-     */
-    private void addAllPackedEnum(
-        java.lang.Iterable<? extends com.google.protobuf.UnittestLite.ForeignEnumLite> values) {
-      ensurePackedEnumIsMutable();
-      for (com.google.protobuf.UnittestLite.ForeignEnumLite value : values) {
-        packedEnum_.addInt(value.getNumber());
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-     */
-    private void clearPackedEnum() {
-      packedEnum_ = emptyIntList();
-    }
-
-    public static com.google.protobuf.UnittestLite.TestPackedTypesLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedTypesLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedTypesLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedTypesLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedTypesLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedTypesLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedTypesLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedTypesLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedTypesLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedTypesLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedTypesLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedTypesLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.TestPackedTypesLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestPackedTypesLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.UnittestLite.TestPackedTypesLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestPackedTypesLite)
-        com.google.protobuf.UnittestLite.TestPackedTypesLiteOrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.TestPackedTypesLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @return A list containing the packedInt32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getPackedInt32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedInt32List());
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @return The count of packedInt32.
-       */
-      @java.lang.Override
-      public int getPackedInt32Count() {
-        return instance.getPackedInt32Count();
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedInt32 at the given index.
-       */
-      @java.lang.Override
-      public int getPackedInt32(int index) {
-        return instance.getPackedInt32(index);
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @param value The packedInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedInt32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setPackedInt32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @param value The packedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedInt32(int value) {
-        copyOnWrite();
-        instance.addPackedInt32(value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @param values The packedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedInt32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllPackedInt32(values);
-        return this;
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedInt32() {
-        copyOnWrite();
-        instance.clearPackedInt32();
-        return this;
-      }
-
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @return A list containing the packedInt64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getPackedInt64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedInt64List());
-      }
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @return The count of packedInt64.
-       */
-      @java.lang.Override
-      public int getPackedInt64Count() {
-        return instance.getPackedInt64Count();
-      }
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedInt64 at the given index.
-       */
-      @java.lang.Override
-      public long getPackedInt64(int index) {
-        return instance.getPackedInt64(index);
-      }
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @param value The packedInt64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedInt64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setPackedInt64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @param value The packedInt64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedInt64(long value) {
-        copyOnWrite();
-        instance.addPackedInt64(value);
-        return this;
-      }
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @param values The packedInt64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedInt64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllPackedInt64(values);
-        return this;
-      }
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedInt64() {
-        copyOnWrite();
-        instance.clearPackedInt64();
-        return this;
-      }
-
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @return A list containing the packedUint32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getPackedUint32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedUint32List());
-      }
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @return The count of packedUint32.
-       */
-      @java.lang.Override
-      public int getPackedUint32Count() {
-        return instance.getPackedUint32Count();
-      }
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedUint32 at the given index.
-       */
-      @java.lang.Override
-      public int getPackedUint32(int index) {
-        return instance.getPackedUint32(index);
-      }
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @param value The packedUint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedUint32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setPackedUint32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @param value The packedUint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedUint32(int value) {
-        copyOnWrite();
-        instance.addPackedUint32(value);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @param values The packedUint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedUint32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllPackedUint32(values);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedUint32() {
-        copyOnWrite();
-        instance.clearPackedUint32();
-        return this;
-      }
-
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @return A list containing the packedUint64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getPackedUint64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedUint64List());
-      }
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @return The count of packedUint64.
-       */
-      @java.lang.Override
-      public int getPackedUint64Count() {
-        return instance.getPackedUint64Count();
-      }
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedUint64 at the given index.
-       */
-      @java.lang.Override
-      public long getPackedUint64(int index) {
-        return instance.getPackedUint64(index);
-      }
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @param value The packedUint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedUint64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setPackedUint64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @param value The packedUint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedUint64(long value) {
-        copyOnWrite();
-        instance.addPackedUint64(value);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @param values The packedUint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedUint64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllPackedUint64(values);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedUint64() {
-        copyOnWrite();
-        instance.clearPackedUint64();
-        return this;
-      }
-
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @return A list containing the packedSint32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getPackedSint32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedSint32List());
-      }
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @return The count of packedSint32.
-       */
-      @java.lang.Override
-      public int getPackedSint32Count() {
-        return instance.getPackedSint32Count();
-      }
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedSint32 at the given index.
-       */
-      @java.lang.Override
-      public int getPackedSint32(int index) {
-        return instance.getPackedSint32(index);
-      }
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @param value The packedSint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedSint32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setPackedSint32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @param value The packedSint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedSint32(int value) {
-        copyOnWrite();
-        instance.addPackedSint32(value);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @param values The packedSint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedSint32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllPackedSint32(values);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedSint32() {
-        copyOnWrite();
-        instance.clearPackedSint32();
-        return this;
-      }
-
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @return A list containing the packedSint64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getPackedSint64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedSint64List());
-      }
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @return The count of packedSint64.
-       */
-      @java.lang.Override
-      public int getPackedSint64Count() {
-        return instance.getPackedSint64Count();
-      }
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedSint64 at the given index.
-       */
-      @java.lang.Override
-      public long getPackedSint64(int index) {
-        return instance.getPackedSint64(index);
-      }
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @param value The packedSint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedSint64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setPackedSint64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @param value The packedSint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedSint64(long value) {
-        copyOnWrite();
-        instance.addPackedSint64(value);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @param values The packedSint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedSint64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllPackedSint64(values);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedSint64() {
-        copyOnWrite();
-        instance.clearPackedSint64();
-        return this;
-      }
-
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @return A list containing the packedFixed32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getPackedFixed32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedFixed32List());
-      }
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @return The count of packedFixed32.
-       */
-      @java.lang.Override
-      public int getPackedFixed32Count() {
-        return instance.getPackedFixed32Count();
-      }
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedFixed32 at the given index.
-       */
-      @java.lang.Override
-      public int getPackedFixed32(int index) {
-        return instance.getPackedFixed32(index);
-      }
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @param value The packedFixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedFixed32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setPackedFixed32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @param value The packedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedFixed32(int value) {
-        copyOnWrite();
-        instance.addPackedFixed32(value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @param values The packedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedFixed32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllPackedFixed32(values);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedFixed32() {
-        copyOnWrite();
-        instance.clearPackedFixed32();
-        return this;
-      }
-
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @return A list containing the packedFixed64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getPackedFixed64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedFixed64List());
-      }
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @return The count of packedFixed64.
-       */
-      @java.lang.Override
-      public int getPackedFixed64Count() {
-        return instance.getPackedFixed64Count();
-      }
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedFixed64 at the given index.
-       */
-      @java.lang.Override
-      public long getPackedFixed64(int index) {
-        return instance.getPackedFixed64(index);
-      }
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @param value The packedFixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedFixed64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setPackedFixed64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @param value The packedFixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedFixed64(long value) {
-        copyOnWrite();
-        instance.addPackedFixed64(value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @param values The packedFixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedFixed64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllPackedFixed64(values);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedFixed64() {
-        copyOnWrite();
-        instance.clearPackedFixed64();
-        return this;
-      }
-
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @return A list containing the packedSfixed32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getPackedSfixed32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedSfixed32List());
-      }
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @return The count of packedSfixed32.
-       */
-      @java.lang.Override
-      public int getPackedSfixed32Count() {
-        return instance.getPackedSfixed32Count();
-      }
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedSfixed32 at the given index.
-       */
-      @java.lang.Override
-      public int getPackedSfixed32(int index) {
-        return instance.getPackedSfixed32(index);
-      }
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @param value The packedSfixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedSfixed32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setPackedSfixed32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @param value The packedSfixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedSfixed32(int value) {
-        copyOnWrite();
-        instance.addPackedSfixed32(value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @param values The packedSfixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedSfixed32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllPackedSfixed32(values);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedSfixed32() {
-        copyOnWrite();
-        instance.clearPackedSfixed32();
-        return this;
-      }
-
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @return A list containing the packedSfixed64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getPackedSfixed64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedSfixed64List());
-      }
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @return The count of packedSfixed64.
-       */
-      @java.lang.Override
-      public int getPackedSfixed64Count() {
-        return instance.getPackedSfixed64Count();
-      }
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedSfixed64 at the given index.
-       */
-      @java.lang.Override
-      public long getPackedSfixed64(int index) {
-        return instance.getPackedSfixed64(index);
-      }
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @param value The packedSfixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedSfixed64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setPackedSfixed64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @param value The packedSfixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedSfixed64(long value) {
-        copyOnWrite();
-        instance.addPackedSfixed64(value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @param values The packedSfixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedSfixed64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllPackedSfixed64(values);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedSfixed64() {
-        copyOnWrite();
-        instance.clearPackedSfixed64();
-        return this;
-      }
-
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @return A list containing the packedFloat.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Float>
-          getPackedFloatList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedFloatList());
-      }
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @return The count of packedFloat.
-       */
-      @java.lang.Override
-      public int getPackedFloatCount() {
-        return instance.getPackedFloatCount();
-      }
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedFloat at the given index.
-       */
-      @java.lang.Override
-      public float getPackedFloat(int index) {
-        return instance.getPackedFloat(index);
-      }
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @param value The packedFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedFloat(
-          int index, float value) {
-        copyOnWrite();
-        instance.setPackedFloat(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @param value The packedFloat to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedFloat(float value) {
-        copyOnWrite();
-        instance.addPackedFloat(value);
-        return this;
-      }
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @param values The packedFloat to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedFloat(
-          java.lang.Iterable<? extends java.lang.Float> values) {
-        copyOnWrite();
-        instance.addAllPackedFloat(values);
-        return this;
-      }
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedFloat() {
-        copyOnWrite();
-        instance.clearPackedFloat();
-        return this;
-      }
-
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @return A list containing the packedDouble.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Double>
-          getPackedDoubleList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedDoubleList());
-      }
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @return The count of packedDouble.
-       */
-      @java.lang.Override
-      public int getPackedDoubleCount() {
-        return instance.getPackedDoubleCount();
-      }
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedDouble at the given index.
-       */
-      @java.lang.Override
-      public double getPackedDouble(int index) {
-        return instance.getPackedDouble(index);
-      }
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @param value The packedDouble to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedDouble(
-          int index, double value) {
-        copyOnWrite();
-        instance.setPackedDouble(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @param value The packedDouble to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedDouble(double value) {
-        copyOnWrite();
-        instance.addPackedDouble(value);
-        return this;
-      }
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @param values The packedDouble to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedDouble(
-          java.lang.Iterable<? extends java.lang.Double> values) {
-        copyOnWrite();
-        instance.addAllPackedDouble(values);
-        return this;
-      }
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedDouble() {
-        copyOnWrite();
-        instance.clearPackedDouble();
-        return this;
-      }
-
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @return A list containing the packedBool.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Boolean>
-          getPackedBoolList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedBoolList());
-      }
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @return The count of packedBool.
-       */
-      @java.lang.Override
-      public int getPackedBoolCount() {
-        return instance.getPackedBoolCount();
-      }
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedBool at the given index.
-       */
-      @java.lang.Override
-      public boolean getPackedBool(int index) {
-        return instance.getPackedBool(index);
-      }
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @param value The packedBool to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedBool(
-          int index, boolean value) {
-        copyOnWrite();
-        instance.setPackedBool(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @param value The packedBool to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedBool(boolean value) {
-        copyOnWrite();
-        instance.addPackedBool(value);
-        return this;
-      }
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @param values The packedBool to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedBool(
-          java.lang.Iterable<? extends java.lang.Boolean> values) {
-        copyOnWrite();
-        instance.addAllPackedBool(values);
-        return this;
-      }
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedBool() {
-        copyOnWrite();
-        instance.clearPackedBool();
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-       * @return A list containing the packedEnum.
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.UnittestLite.ForeignEnumLite> getPackedEnumList() {
-        return instance.getPackedEnumList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-       * @return The count of packedEnum.
-       */
-      @java.lang.Override
-      public int getPackedEnumCount() {
-        return instance.getPackedEnumCount();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedEnum at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.ForeignEnumLite getPackedEnum(int index) {
-        return instance.getPackedEnum(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-       * @param index The index to set the value at.
-       * @param value The packedEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedEnum(
-          int index, com.google.protobuf.UnittestLite.ForeignEnumLite value) {
-        copyOnWrite();
-        instance.setPackedEnum(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-       * @param value The packedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedEnum(com.google.protobuf.UnittestLite.ForeignEnumLite value) {
-        copyOnWrite();
-        instance.addPackedEnum(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-       * @param values The packedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedEnum(
-          java.lang.Iterable<? extends com.google.protobuf.UnittestLite.ForeignEnumLite> values) {
-        copyOnWrite();
-        instance.addAllPackedEnum(values);  return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnumLite packed_enum = 103 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedEnum() {
-        copyOnWrite();
-        instance.clearPackedEnum();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestPackedTypesLite)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.TestPackedTypesLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "packedInt32_",
-              "packedInt64_",
-              "packedUint32_",
-              "packedUint64_",
-              "packedSint32_",
-              "packedSint64_",
-              "packedFixed32_",
-              "packedFixed64_",
-              "packedSfixed32_",
-              "packedSfixed64_",
-              "packedFloat_",
-              "packedDouble_",
-              "packedBool_",
-              "packedEnum_",
-              com.google.protobuf.UnittestLite.ForeignEnumLite.internalGetVerifier(),
-            };
-            java.lang.String info =
-                "\u0001\u000e\u0000\u0000Zg\u000e\u0000\u000e\u0000Z\'[%\\+]&^/_0`)a(b-c.d$e#f*g," +
-                "";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestPackedTypesLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.TestPackedTypesLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestPackedTypesLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestPackedTypesLite)
-    private static final com.google.protobuf.UnittestLite.TestPackedTypesLite DEFAULT_INSTANCE;
-    static {
-      TestPackedTypesLite defaultInstance = new TestPackedTypesLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestPackedTypesLite.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.TestPackedTypesLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestPackedTypesLite> PARSER;
-
-    public static com.google.protobuf.Parser<TestPackedTypesLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestAllExtensionsLiteOrBuilder extends 
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestAllExtensionsLite)
-       com.google.protobuf.GeneratedMessageLite.
-            ExtendableMessageOrBuilder<
-                TestAllExtensionsLite, TestAllExtensionsLite.Builder> {
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestAllExtensionsLite}
-   */
-  public  static final class TestAllExtensionsLite extends
-      com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
-        TestAllExtensionsLite, TestAllExtensionsLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestAllExtensionsLite)
-      TestAllExtensionsLiteOrBuilder {
-    private TestAllExtensionsLite() {
-    }
-    public static com.google.protobuf.UnittestLite.TestAllExtensionsLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllExtensionsLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllExtensionsLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllExtensionsLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllExtensionsLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllExtensionsLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllExtensionsLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllExtensionsLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllExtensionsLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllExtensionsLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllExtensionsLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestAllExtensionsLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.TestAllExtensionsLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestAllExtensionsLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
-          com.google.protobuf.UnittestLite.TestAllExtensionsLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestAllExtensionsLite)
-        com.google.protobuf.UnittestLite.TestAllExtensionsLiteOrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.TestAllExtensionsLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestAllExtensionsLite)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.TestAllExtensionsLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestAllExtensionsLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.TestAllExtensionsLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestAllExtensionsLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestAllExtensionsLite)
-    private static final com.google.protobuf.UnittestLite.TestAllExtensionsLite DEFAULT_INSTANCE;
-    static {
-      TestAllExtensionsLite defaultInstance = new TestAllExtensionsLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestAllExtensionsLite.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.TestAllExtensionsLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestAllExtensionsLite> PARSER;
-
-    public static com.google.protobuf.Parser<TestAllExtensionsLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface OptionalGroup_extension_liteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.OptionalGroup_extension_lite)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional int32 a = 17;</code>
-     * @return Whether the a field is set.
-     */
-    boolean hasA();
-    /**
-     * <code>optional int32 a = 17;</code>
-     * @return The a.
-     */
-    int getA();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.OptionalGroup_extension_lite}
-   */
-  public  static final class OptionalGroup_extension_lite extends
-      com.google.protobuf.GeneratedMessageLite<
-          OptionalGroup_extension_lite, OptionalGroup_extension_lite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.OptionalGroup_extension_lite)
-      OptionalGroup_extension_liteOrBuilder {
-    private OptionalGroup_extension_lite() {
-    }
-    private int bitField0_;
-    public static final int A_FIELD_NUMBER = 17;
-    private int a_;
-    /**
-     * <code>optional int32 a = 17;</code>
-     * @return Whether the a field is set.
-     */
-    @java.lang.Override
-    public boolean hasA() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 a = 17;</code>
-     * @return The a.
-     */
-    @java.lang.Override
-    public int getA() {
-      return a_;
-    }
-    /**
-     * <code>optional int32 a = 17;</code>
-     * @param value The a to set.
-     */
-    private void setA(int value) {
-      bitField0_ |= 0x00000001;
-      a_ = value;
-    }
-    /**
-     * <code>optional int32 a = 17;</code>
-     */
-    private void clearA() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      a_ = 0;
-    }
-
-    public static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.OptionalGroup_extension_lite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.OptionalGroup_extension_lite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.UnittestLite.OptionalGroup_extension_lite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.OptionalGroup_extension_lite)
-        com.google.protobuf.UnittestLite.OptionalGroup_extension_liteOrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.OptionalGroup_extension_lite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return instance.hasA();
-      }
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public int getA() {
-        return instance.getA();
-      }
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @param value The a to set.
-       * @return This builder for chaining.
-       */
-      public Builder setA(int value) {
-        copyOnWrite();
-        instance.setA(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearA() {
-        copyOnWrite();
-        instance.clearA();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.OptionalGroup_extension_lite)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.OptionalGroup_extension_lite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "a_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0011\u0011\u0001\u0000\u0000\u0000\u0011\u1004\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.OptionalGroup_extension_lite> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.OptionalGroup_extension_lite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.OptionalGroup_extension_lite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.OptionalGroup_extension_lite)
-    private static final com.google.protobuf.UnittestLite.OptionalGroup_extension_lite DEFAULT_INSTANCE;
-    static {
-      OptionalGroup_extension_lite defaultInstance = new OptionalGroup_extension_lite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        OptionalGroup_extension_lite.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<OptionalGroup_extension_lite> PARSER;
-
-    public static com.google.protobuf.Parser<OptionalGroup_extension_lite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface RepeatedGroup_extension_liteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.RepeatedGroup_extension_lite)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional int32 a = 47;</code>
-     * @return Whether the a field is set.
-     */
-    boolean hasA();
-    /**
-     * <code>optional int32 a = 47;</code>
-     * @return The a.
-     */
-    int getA();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.RepeatedGroup_extension_lite}
-   */
-  public  static final class RepeatedGroup_extension_lite extends
-      com.google.protobuf.GeneratedMessageLite<
-          RepeatedGroup_extension_lite, RepeatedGroup_extension_lite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.RepeatedGroup_extension_lite)
-      RepeatedGroup_extension_liteOrBuilder {
-    private RepeatedGroup_extension_lite() {
-    }
-    private int bitField0_;
-    public static final int A_FIELD_NUMBER = 47;
-    private int a_;
-    /**
-     * <code>optional int32 a = 47;</code>
-     * @return Whether the a field is set.
-     */
-    @java.lang.Override
-    public boolean hasA() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 a = 47;</code>
-     * @return The a.
-     */
-    @java.lang.Override
-    public int getA() {
-      return a_;
-    }
-    /**
-     * <code>optional int32 a = 47;</code>
-     * @param value The a to set.
-     */
-    private void setA(int value) {
-      bitField0_ |= 0x00000001;
-      a_ = value;
-    }
-    /**
-     * <code>optional int32 a = 47;</code>
-     */
-    private void clearA() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      a_ = 0;
-    }
-
-    public static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.RepeatedGroup_extension_lite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.RepeatedGroup_extension_lite)
-        com.google.protobuf.UnittestLite.RepeatedGroup_extension_liteOrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int32 a = 47;</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return instance.hasA();
-      }
-      /**
-       * <code>optional int32 a = 47;</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public int getA() {
-        return instance.getA();
-      }
-      /**
-       * <code>optional int32 a = 47;</code>
-       * @param value The a to set.
-       * @return This builder for chaining.
-       */
-      public Builder setA(int value) {
-        copyOnWrite();
-        instance.setA(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 a = 47;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearA() {
-        copyOnWrite();
-        instance.clearA();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.RepeatedGroup_extension_lite)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "a_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001//\u0001\u0000\u0000\u0000/\u1004\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.RepeatedGroup_extension_lite)
-    private static final com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite DEFAULT_INSTANCE;
-    static {
-      RepeatedGroup_extension_lite defaultInstance = new RepeatedGroup_extension_lite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        RepeatedGroup_extension_lite.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<RepeatedGroup_extension_lite> PARSER;
-
-    public static com.google.protobuf.Parser<RepeatedGroup_extension_lite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestPackedExtensionsLiteOrBuilder extends 
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestPackedExtensionsLite)
-       com.google.protobuf.GeneratedMessageLite.
-            ExtendableMessageOrBuilder<
-                TestPackedExtensionsLite, TestPackedExtensionsLite.Builder> {
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestPackedExtensionsLite}
-   */
-  public  static final class TestPackedExtensionsLite extends
-      com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
-        TestPackedExtensionsLite, TestPackedExtensionsLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestPackedExtensionsLite)
-      TestPackedExtensionsLiteOrBuilder {
-    private TestPackedExtensionsLite() {
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedExtensionsLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedExtensionsLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedExtensionsLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedExtensionsLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedExtensionsLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedExtensionsLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedExtensionsLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedExtensionsLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedExtensionsLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedExtensionsLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedExtensionsLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestPackedExtensionsLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.TestPackedExtensionsLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestPackedExtensionsLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
-          com.google.protobuf.UnittestLite.TestPackedExtensionsLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestPackedExtensionsLite)
-        com.google.protobuf.UnittestLite.TestPackedExtensionsLiteOrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.TestPackedExtensionsLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestPackedExtensionsLite)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.TestPackedExtensionsLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestPackedExtensionsLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.TestPackedExtensionsLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestPackedExtensionsLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestPackedExtensionsLite)
-    private static final com.google.protobuf.UnittestLite.TestPackedExtensionsLite DEFAULT_INSTANCE;
-    static {
-      TestPackedExtensionsLite defaultInstance = new TestPackedExtensionsLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestPackedExtensionsLite.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.TestPackedExtensionsLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestPackedExtensionsLite> PARSER;
-
-    public static com.google.protobuf.Parser<TestPackedExtensionsLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestNestedExtensionLiteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestNestedExtensionLite)
-      com.google.protobuf.MessageLiteOrBuilder {
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestNestedExtensionLite}
-   */
-  public  static final class TestNestedExtensionLite extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestNestedExtensionLite, TestNestedExtensionLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestNestedExtensionLite)
-      TestNestedExtensionLiteOrBuilder {
-    private TestNestedExtensionLite() {
-    }
-    public static com.google.protobuf.UnittestLite.TestNestedExtensionLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestNestedExtensionLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestNestedExtensionLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestNestedExtensionLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestNestedExtensionLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestNestedExtensionLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestNestedExtensionLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestNestedExtensionLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestNestedExtensionLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestNestedExtensionLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestNestedExtensionLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestNestedExtensionLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.TestNestedExtensionLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestNestedExtensionLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.UnittestLite.TestNestedExtensionLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestNestedExtensionLite)
-        com.google.protobuf.UnittestLite.TestNestedExtensionLiteOrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.TestNestedExtensionLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestNestedExtensionLite)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.TestNestedExtensionLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestNestedExtensionLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.TestNestedExtensionLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestNestedExtensionLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestNestedExtensionLite)
-    private static final com.google.protobuf.UnittestLite.TestNestedExtensionLite DEFAULT_INSTANCE;
-    static {
-      TestNestedExtensionLite defaultInstance = new TestNestedExtensionLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestNestedExtensionLite.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.TestNestedExtensionLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestNestedExtensionLite> PARSER;
-
-    public static com.google.protobuf.Parser<TestNestedExtensionLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-    public static final int NESTED_EXTENSION_FIELD_NUMBER = 12345;
-    /**
-     * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-     */
-    public static final
-      com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-        java.lang.Integer> nestedExtension = com.google.protobuf.GeneratedMessageLite
-            .newSingularGeneratedExtension(
-          com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-          0,
-          null,
-          null,
-          12345,
-          com.google.protobuf.WireFormat.FieldType.INT32,
-          java.lang.Integer.class);
-  }
-
-  public interface TestDeprecatedLiteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestDeprecatedLite)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional int32 deprecated_field = 1 [deprecated = true];</code>
-     * @return Whether the deprecatedField field is set.
-     */
-    @java.lang.Deprecated boolean hasDeprecatedField();
-    /**
-     * <code>optional int32 deprecated_field = 1 [deprecated = true];</code>
-     * @return The deprecatedField.
-     */
-    @java.lang.Deprecated int getDeprecatedField();
-
-    /**
-     * <code>required int32 deprecated_field2 = 2 [deprecated = true];</code>
-     * @return Whether the deprecatedField2 field is set.
-     */
-    @java.lang.Deprecated boolean hasDeprecatedField2();
-    /**
-     * <code>required int32 deprecated_field2 = 2 [deprecated = true];</code>
-     * @return The deprecatedField2.
-     */
-    @java.lang.Deprecated int getDeprecatedField2();
-
-    /**
-     * <code>optional string deprecated_field3 = 3 [deprecated = true];</code>
-     * @return Whether the deprecatedField3 field is set.
-     */
-    @java.lang.Deprecated boolean hasDeprecatedField3();
-    /**
-     * <code>optional string deprecated_field3 = 3 [deprecated = true];</code>
-     * @return The deprecatedField3.
-     */
-    @java.lang.Deprecated java.lang.String getDeprecatedField3();
-    /**
-     * <code>optional string deprecated_field3 = 3 [deprecated = true];</code>
-     * @return The bytes for deprecatedField3.
-     */
-    @java.lang.Deprecated com.google.protobuf.ByteString
-        getDeprecatedField3Bytes();
-
-    /**
-     * <code>optional .protobuf_unittest.TestDeprecatedLite deprecated_field4 = 4 [deprecated = true];</code>
-     * @return Whether the deprecatedField4 field is set.
-     */
-    @java.lang.Deprecated boolean hasDeprecatedField4();
-    /**
-     * <code>optional .protobuf_unittest.TestDeprecatedLite deprecated_field4 = 4 [deprecated = true];</code>
-     * @return The deprecatedField4.
-     */
-    @java.lang.Deprecated com.google.protobuf.UnittestLite.TestDeprecatedLite getDeprecatedField4();
-  }
-  /**
-   * <pre>
-   * Test that deprecated fields work.  We only verify that they compile (at one
-   * point this failed).
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestDeprecatedLite}
-   */
-  public  static final class TestDeprecatedLite extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestDeprecatedLite, TestDeprecatedLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestDeprecatedLite)
-      TestDeprecatedLiteOrBuilder {
-    private TestDeprecatedLite() {
-      deprecatedField3_ = "";
-    }
-    private int bitField0_;
-    public static final int DEPRECATED_FIELD_FIELD_NUMBER = 1;
-    private int deprecatedField_;
-    /**
-     * <code>optional int32 deprecated_field = 1 [deprecated = true];</code>
-     * @return Whether the deprecatedField field is set.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated public boolean hasDeprecatedField() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 deprecated_field = 1 [deprecated = true];</code>
-     * @return The deprecatedField.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated public int getDeprecatedField() {
-      return deprecatedField_;
-    }
-    /**
-     * <code>optional int32 deprecated_field = 1 [deprecated = true];</code>
-     * @param value The deprecatedField to set.
-     */
-    private void setDeprecatedField(int value) {
-      bitField0_ |= 0x00000001;
-      deprecatedField_ = value;
-    }
-    /**
-     * <code>optional int32 deprecated_field = 1 [deprecated = true];</code>
-     */
-    private void clearDeprecatedField() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      deprecatedField_ = 0;
-    }
-
-    public static final int DEPRECATED_FIELD2_FIELD_NUMBER = 2;
-    private int deprecatedField2_;
-    /**
-     * <code>required int32 deprecated_field2 = 2 [deprecated = true];</code>
-     * @return Whether the deprecatedField2 field is set.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated public boolean hasDeprecatedField2() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>required int32 deprecated_field2 = 2 [deprecated = true];</code>
-     * @return The deprecatedField2.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated public int getDeprecatedField2() {
-      return deprecatedField2_;
-    }
-    /**
-     * <code>required int32 deprecated_field2 = 2 [deprecated = true];</code>
-     * @param value The deprecatedField2 to set.
-     */
-    private void setDeprecatedField2(int value) {
-      bitField0_ |= 0x00000002;
-      deprecatedField2_ = value;
-    }
-    /**
-     * <code>required int32 deprecated_field2 = 2 [deprecated = true];</code>
-     */
-    private void clearDeprecatedField2() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      deprecatedField2_ = 0;
-    }
-
-    public static final int DEPRECATED_FIELD3_FIELD_NUMBER = 3;
-    private java.lang.String deprecatedField3_;
-    /**
-     * <code>optional string deprecated_field3 = 3 [deprecated = true];</code>
-     * @return Whether the deprecatedField3 field is set.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated public boolean hasDeprecatedField3() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional string deprecated_field3 = 3 [deprecated = true];</code>
-     * @return The deprecatedField3.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated public java.lang.String getDeprecatedField3() {
-      return deprecatedField3_;
-    }
-    /**
-     * <code>optional string deprecated_field3 = 3 [deprecated = true];</code>
-     * @return The bytes for deprecatedField3.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated public com.google.protobuf.ByteString
-        getDeprecatedField3Bytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(deprecatedField3_);
-    }
-    /**
-     * <code>optional string deprecated_field3 = 3 [deprecated = true];</code>
-     * @param value The deprecatedField3 to set.
-     */
-    private void setDeprecatedField3(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00000004;
-      deprecatedField3_ = value;
-    }
-    /**
-     * <code>optional string deprecated_field3 = 3 [deprecated = true];</code>
-     */
-    private void clearDeprecatedField3() {
-      bitField0_ = (bitField0_ & ~0x00000004);
-      deprecatedField3_ = getDefaultInstance().getDeprecatedField3();
-    }
-    /**
-     * <code>optional string deprecated_field3 = 3 [deprecated = true];</code>
-     * @param value The bytes for deprecatedField3 to set.
-     */
-    private void setDeprecatedField3Bytes(
-        com.google.protobuf.ByteString value) {
-      deprecatedField3_ = value.toStringUtf8();
-      bitField0_ |= 0x00000004;
-    }
-
-    public static final int DEPRECATED_FIELD4_FIELD_NUMBER = 4;
-    private com.google.protobuf.UnittestLite.TestDeprecatedLite deprecatedField4_;
-    /**
-     * <code>optional .protobuf_unittest.TestDeprecatedLite deprecated_field4 = 4 [deprecated = true];</code>
-     */
-    @java.lang.Override
-    @java.lang.Deprecated public boolean hasDeprecatedField4() {
-      return ((bitField0_ & 0x00000008) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestDeprecatedLite deprecated_field4 = 4 [deprecated = true];</code>
-     */
-    @java.lang.Override
-    @java.lang.Deprecated public com.google.protobuf.UnittestLite.TestDeprecatedLite getDeprecatedField4() {
-      return deprecatedField4_ == null ? com.google.protobuf.UnittestLite.TestDeprecatedLite.getDefaultInstance() : deprecatedField4_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestDeprecatedLite deprecated_field4 = 4 [deprecated = true];</code>
-     */
-    private void setDeprecatedField4(com.google.protobuf.UnittestLite.TestDeprecatedLite value) {
-      value.getClass();
-  deprecatedField4_ = value;
-      bitField0_ |= 0x00000008;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestDeprecatedLite deprecated_field4 = 4 [deprecated = true];</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeDeprecatedField4(com.google.protobuf.UnittestLite.TestDeprecatedLite value) {
-      value.getClass();
-  if (deprecatedField4_ != null &&
-          deprecatedField4_ != com.google.protobuf.UnittestLite.TestDeprecatedLite.getDefaultInstance()) {
-        deprecatedField4_ =
-          com.google.protobuf.UnittestLite.TestDeprecatedLite.newBuilder(deprecatedField4_).mergeFrom(value).buildPartial();
-      } else {
-        deprecatedField4_ = value;
-      }
-      bitField0_ |= 0x00000008;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestDeprecatedLite deprecated_field4 = 4 [deprecated = true];</code>
-     */
-    private void clearDeprecatedField4() {  deprecatedField4_ = null;
-      bitField0_ = (bitField0_ & ~0x00000008);
-    }
-
-    public static com.google.protobuf.UnittestLite.TestDeprecatedLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestDeprecatedLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestDeprecatedLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestDeprecatedLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestDeprecatedLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestDeprecatedLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestDeprecatedLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestDeprecatedLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestDeprecatedLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestDeprecatedLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestDeprecatedLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestDeprecatedLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.TestDeprecatedLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Test that deprecated fields work.  We only verify that they compile (at one
-     * point this failed).
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestDeprecatedLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.UnittestLite.TestDeprecatedLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestDeprecatedLite)
-        com.google.protobuf.UnittestLite.TestDeprecatedLiteOrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.TestDeprecatedLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int32 deprecated_field = 1 [deprecated = true];</code>
-       * @return Whether the deprecatedField field is set.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated public boolean hasDeprecatedField() {
-        return instance.hasDeprecatedField();
-      }
-      /**
-       * <code>optional int32 deprecated_field = 1 [deprecated = true];</code>
-       * @return The deprecatedField.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated public int getDeprecatedField() {
-        return instance.getDeprecatedField();
-      }
-      /**
-       * <code>optional int32 deprecated_field = 1 [deprecated = true];</code>
-       * @param value The deprecatedField to set.
-       * @return This builder for chaining.
-       */
-      @java.lang.Deprecated public Builder setDeprecatedField(int value) {
-        copyOnWrite();
-        instance.setDeprecatedField(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 deprecated_field = 1 [deprecated = true];</code>
-       * @return This builder for chaining.
-       */
-      @java.lang.Deprecated public Builder clearDeprecatedField() {
-        copyOnWrite();
-        instance.clearDeprecatedField();
-        return this;
-      }
-
-      /**
-       * <code>required int32 deprecated_field2 = 2 [deprecated = true];</code>
-       * @return Whether the deprecatedField2 field is set.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated public boolean hasDeprecatedField2() {
-        return instance.hasDeprecatedField2();
-      }
-      /**
-       * <code>required int32 deprecated_field2 = 2 [deprecated = true];</code>
-       * @return The deprecatedField2.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated public int getDeprecatedField2() {
-        return instance.getDeprecatedField2();
-      }
-      /**
-       * <code>required int32 deprecated_field2 = 2 [deprecated = true];</code>
-       * @param value The deprecatedField2 to set.
-       * @return This builder for chaining.
-       */
-      @java.lang.Deprecated public Builder setDeprecatedField2(int value) {
-        copyOnWrite();
-        instance.setDeprecatedField2(value);
-        return this;
-      }
-      /**
-       * <code>required int32 deprecated_field2 = 2 [deprecated = true];</code>
-       * @return This builder for chaining.
-       */
-      @java.lang.Deprecated public Builder clearDeprecatedField2() {
-        copyOnWrite();
-        instance.clearDeprecatedField2();
-        return this;
-      }
-
-      /**
-       * <code>optional string deprecated_field3 = 3 [deprecated = true];</code>
-       * @return Whether the deprecatedField3 field is set.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated public boolean hasDeprecatedField3() {
-        return instance.hasDeprecatedField3();
-      }
-      /**
-       * <code>optional string deprecated_field3 = 3 [deprecated = true];</code>
-       * @return The deprecatedField3.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated public java.lang.String getDeprecatedField3() {
-        return instance.getDeprecatedField3();
-      }
-      /**
-       * <code>optional string deprecated_field3 = 3 [deprecated = true];</code>
-       * @return The bytes for deprecatedField3.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated public com.google.protobuf.ByteString
-          getDeprecatedField3Bytes() {
-        return instance.getDeprecatedField3Bytes();
-      }
-      /**
-       * <code>optional string deprecated_field3 = 3 [deprecated = true];</code>
-       * @param value The deprecatedField3 to set.
-       * @return This builder for chaining.
-       */
-      @java.lang.Deprecated public Builder setDeprecatedField3(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setDeprecatedField3(value);
-        return this;
-      }
-      /**
-       * <code>optional string deprecated_field3 = 3 [deprecated = true];</code>
-       * @return This builder for chaining.
-       */
-      @java.lang.Deprecated public Builder clearDeprecatedField3() {
-        copyOnWrite();
-        instance.clearDeprecatedField3();
-        return this;
-      }
-      /**
-       * <code>optional string deprecated_field3 = 3 [deprecated = true];</code>
-       * @param value The bytes for deprecatedField3 to set.
-       * @return This builder for chaining.
-       */
-      @java.lang.Deprecated public Builder setDeprecatedField3Bytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setDeprecatedField3Bytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.TestDeprecatedLite deprecated_field4 = 4 [deprecated = true];</code>
-       */
-      @java.lang.Override
-      @java.lang.Deprecated public boolean hasDeprecatedField4() {
-        return instance.hasDeprecatedField4();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestDeprecatedLite deprecated_field4 = 4 [deprecated = true];</code>
-       */
-      @java.lang.Override
-      @java.lang.Deprecated public com.google.protobuf.UnittestLite.TestDeprecatedLite getDeprecatedField4() {
-        return instance.getDeprecatedField4();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestDeprecatedLite deprecated_field4 = 4 [deprecated = true];</code>
-       */
-      @java.lang.Deprecated public Builder setDeprecatedField4(com.google.protobuf.UnittestLite.TestDeprecatedLite value) {
-        copyOnWrite();
-        instance.setDeprecatedField4(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestDeprecatedLite deprecated_field4 = 4 [deprecated = true];</code>
-       */
-      @java.lang.Deprecated public Builder setDeprecatedField4(
-          com.google.protobuf.UnittestLite.TestDeprecatedLite.Builder builderForValue) {
-        copyOnWrite();
-        instance.setDeprecatedField4(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestDeprecatedLite deprecated_field4 = 4 [deprecated = true];</code>
-       */
-      @java.lang.Deprecated public Builder mergeDeprecatedField4(com.google.protobuf.UnittestLite.TestDeprecatedLite value) {
-        copyOnWrite();
-        instance.mergeDeprecatedField4(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestDeprecatedLite deprecated_field4 = 4 [deprecated = true];</code>
-       */
-      @java.lang.Deprecated public Builder clearDeprecatedField4() {  copyOnWrite();
-        instance.clearDeprecatedField4();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestDeprecatedLite)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.TestDeprecatedLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "deprecatedField_",
-              "deprecatedField2_",
-              "deprecatedField3_",
-              "deprecatedField4_",
-            };
-            java.lang.String info =
-                "\u0001\u0004\u0000\u0001\u0001\u0004\u0004\u0000\u0000\u0002\u0001\u1004\u0000\u0002" +
-                "\u1504\u0001\u0003\u1008\u0002\u0004\u1409\u0003";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestDeprecatedLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.TestDeprecatedLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestDeprecatedLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestDeprecatedLite)
-    private static final com.google.protobuf.UnittestLite.TestDeprecatedLite DEFAULT_INSTANCE;
-    static {
-      TestDeprecatedLite defaultInstance = new TestDeprecatedLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestDeprecatedLite.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.TestDeprecatedLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestDeprecatedLite> PARSER;
-
-    public static com.google.protobuf.Parser<TestDeprecatedLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestParsingMergeLiteOrBuilder extends 
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestParsingMergeLite)
-       com.google.protobuf.GeneratedMessageLite.
-            ExtendableMessageOrBuilder<
-                TestParsingMergeLite, TestParsingMergeLite.Builder> {
-
-    /**
-     * <code>required .protobuf_unittest.TestAllTypesLite required_all_types = 1;</code>
-     * @return Whether the requiredAllTypes field is set.
-     */
-    boolean hasRequiredAllTypes();
-    /**
-     * <code>required .protobuf_unittest.TestAllTypesLite required_all_types = 1;</code>
-     * @return The requiredAllTypes.
-     */
-    com.google.protobuf.UnittestLite.TestAllTypesLite getRequiredAllTypes();
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite optional_all_types = 2;</code>
-     * @return Whether the optionalAllTypes field is set.
-     */
-    boolean hasOptionalAllTypes();
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite optional_all_types = 2;</code>
-     * @return The optionalAllTypes.
-     */
-    com.google.protobuf.UnittestLite.TestAllTypesLite getOptionalAllTypes();
-
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     */
-    java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite> 
-        getRepeatedAllTypesList();
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     */
-    com.google.protobuf.UnittestLite.TestAllTypesLite getRepeatedAllTypes(int index);
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     */
-    int getRepeatedAllTypesCount();
-
-    /**
-     * <code>optional group OptionalGroup = 10 { ... }</code>
-     * @return Whether the optionalgroup field is set.
-     */
-    boolean hasOptionalGroup();
-    /**
-     * <code>optional group OptionalGroup = 10 { ... }</code>
-     * @return The optionalgroup.
-     */
-    com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup getOptionalGroup();
-
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    java.util.List<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup> 
-        getRepeatedGroupList();
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup getRepeatedGroup(int index);
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    int getRepeatedGroupCount();
-  }
-  /**
-   * <pre>
-   * See the comments of the same type in unittest.proto.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestParsingMergeLite}
-   */
-  public  static final class TestParsingMergeLite extends
-      com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
-        TestParsingMergeLite, TestParsingMergeLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestParsingMergeLite)
-      TestParsingMergeLiteOrBuilder {
-    private TestParsingMergeLite() {
-      repeatedAllTypes_ = emptyProtobufList();
-      repeatedGroup_ = emptyProtobufList();
-    }
-    public interface RepeatedFieldsGeneratorOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       */
-      java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite> 
-          getField1List();
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       */
-      com.google.protobuf.UnittestLite.TestAllTypesLite getField1(int index);
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       */
-      int getField1Count();
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       */
-      java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite> 
-          getField2List();
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       */
-      com.google.protobuf.UnittestLite.TestAllTypesLite getField2(int index);
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       */
-      int getField2Count();
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       */
-      java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite> 
-          getField3List();
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       */
-      com.google.protobuf.UnittestLite.TestAllTypesLite getField3(int index);
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       */
-      int getField3Count();
-
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      java.util.List<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1> 
-          getGroup1List();
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 getGroup1(int index);
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      int getGroup1Count();
-
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      java.util.List<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2> 
-          getGroup2List();
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 getGroup2(int index);
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      int getGroup2Count();
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       */
-      java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite> 
-          getExt1List();
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       */
-      com.google.protobuf.UnittestLite.TestAllTypesLite getExt1(int index);
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       */
-      int getExt1Count();
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       */
-      java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite> 
-          getExt2List();
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       */
-      com.google.protobuf.UnittestLite.TestAllTypesLite getExt2(int index);
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       */
-      int getExt2Count();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator}
-     */
-    public  static final class RepeatedFieldsGenerator extends
-        com.google.protobuf.GeneratedMessageLite<
-            RepeatedFieldsGenerator, RepeatedFieldsGenerator.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator)
-        RepeatedFieldsGeneratorOrBuilder {
-      private RepeatedFieldsGenerator() {
-        field1_ = emptyProtobufList();
-        field2_ = emptyProtobufList();
-        field3_ = emptyProtobufList();
-        group1_ = emptyProtobufList();
-        group2_ = emptyProtobufList();
-        ext1_ = emptyProtobufList();
-        ext2_ = emptyProtobufList();
-      }
-      public interface Group1OrBuilder extends
-          // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator.Group1)
-          com.google.protobuf.MessageLiteOrBuilder {
-
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 11;</code>
-         * @return Whether the field1 field is set.
-         */
-        boolean hasField1();
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 11;</code>
-         * @return The field1.
-         */
-        com.google.protobuf.UnittestLite.TestAllTypesLite getField1();
-      }
-      /**
-       * Protobuf type {@code protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator.Group1}
-       */
-      public  static final class Group1 extends
-          com.google.protobuf.GeneratedMessageLite<
-              Group1, Group1.Builder> implements
-          // @@protoc_insertion_point(message_implements:protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator.Group1)
-          Group1OrBuilder {
-        private Group1() {
-        }
-        private int bitField0_;
-        public static final int FIELD1_FIELD_NUMBER = 11;
-        private com.google.protobuf.UnittestLite.TestAllTypesLite field1_;
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 11;</code>
-         */
-        @java.lang.Override
-        public boolean hasField1() {
-          return ((bitField0_ & 0x00000001) != 0);
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 11;</code>
-         */
-        @java.lang.Override
-        public com.google.protobuf.UnittestLite.TestAllTypesLite getField1() {
-          return field1_ == null ? com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance() : field1_;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 11;</code>
-         */
-        private void setField1(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          value.getClass();
-  field1_ = value;
-          bitField0_ |= 0x00000001;
-          }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 11;</code>
-         */
-        @java.lang.SuppressWarnings({"ReferenceEquality"})
-        private void mergeField1(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          value.getClass();
-  if (field1_ != null &&
-              field1_ != com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance()) {
-            field1_ =
-              com.google.protobuf.UnittestLite.TestAllTypesLite.newBuilder(field1_).mergeFrom(value).buildPartial();
-          } else {
-            field1_ = value;
-          }
-          bitField0_ |= 0x00000001;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 11;</code>
-         */
-        private void clearField1() {  field1_ = null;
-          bitField0_ = (bitField0_ & ~0x00000001);
-        }
-
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 parseFrom(
-            java.nio.ByteBuffer data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 parseFrom(
-            java.nio.ByteBuffer data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data, extensionRegistry);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 parseFrom(
-            com.google.protobuf.ByteString data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 parseFrom(
-            com.google.protobuf.ByteString data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data, extensionRegistry);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 parseFrom(byte[] data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 parseFrom(
-            byte[] data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data, extensionRegistry);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 parseFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 parseFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input, extensionRegistry);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 parseDelimitedFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 parseDelimitedFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 parseFrom(
-            com.google.protobuf.CodedInputStream input)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 parseFrom(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input, extensionRegistry);
-        }
-
-        public static Builder newBuilder() {
-          return (Builder) DEFAULT_INSTANCE.createBuilder();
-        }
-        public static Builder newBuilder(com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 prototype) {
-          return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-        }
-
-        /**
-         * Protobuf type {@code protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator.Group1}
-         */
-        public static final class Builder extends
-            com.google.protobuf.GeneratedMessageLite.Builder<
-              com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1, Builder> implements
-            // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator.Group1)
-            com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1OrBuilder {
-          // Construct using com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1.newBuilder()
-          private Builder() {
-            super(DEFAULT_INSTANCE);
-          }
-
-
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 11;</code>
-           */
-          @java.lang.Override
-          public boolean hasField1() {
-            return instance.hasField1();
-          }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 11;</code>
-           */
-          @java.lang.Override
-          public com.google.protobuf.UnittestLite.TestAllTypesLite getField1() {
-            return instance.getField1();
-          }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 11;</code>
-           */
-          public Builder setField1(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-            copyOnWrite();
-            instance.setField1(value);
-            return this;
-            }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 11;</code>
-           */
-          public Builder setField1(
-              com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-            copyOnWrite();
-            instance.setField1(builderForValue.build());
-            return this;
-          }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 11;</code>
-           */
-          public Builder mergeField1(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-            copyOnWrite();
-            instance.mergeField1(value);
-            return this;
-          }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 11;</code>
-           */
-          public Builder clearField1() {  copyOnWrite();
-            instance.clearField1();
-            return this;
-          }
-
-          // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator.Group1)
-        }
-        @java.lang.Override
-        @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-        protected final java.lang.Object dynamicMethod(
-            com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-            java.lang.Object arg0, java.lang.Object arg1) {
-          switch (method) {
-            case NEW_MUTABLE_INSTANCE: {
-              return new com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1();
-            }
-            case NEW_BUILDER: {
-              return new Builder();
-            }
-            case BUILD_MESSAGE_INFO: {
-                java.lang.Object[] objects = new java.lang.Object[] {
-                  "bitField0_",
-                  "field1_",
-                };
-                java.lang.String info =
-                    "\u0001\u0001\u0000\u0001\u000b\u000b\u0001\u0000\u0000\u0000\u000b\u1009\u0000";
-                return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-            }
-            // fall through
-            case GET_DEFAULT_INSTANCE: {
-              return DEFAULT_INSTANCE;
-            }
-            case GET_PARSER: {
-              com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1> parser = PARSER;
-              if (parser == null) {
-                synchronized (com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1.class) {
-                  parser = PARSER;
-                  if (parser == null) {
-                    parser =
-                        new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1>(
-                            DEFAULT_INSTANCE);
-                    PARSER = parser;
-                  }
-                }
-              }
-              return parser;
-          }
-          case GET_MEMOIZED_IS_INITIALIZED: {
-            return (byte) 1;
-          }
-          case SET_MEMOIZED_IS_INITIALIZED: {
-            return null;
-          }
-          }
-          throw new UnsupportedOperationException();
-        }
-
-
-        // @@protoc_insertion_point(class_scope:protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator.Group1)
-        private static final com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 DEFAULT_INSTANCE;
-        static {
-          Group1 defaultInstance = new Group1();
-          // New instances are implicitly immutable so no need to make
-          // immutable.
-          DEFAULT_INSTANCE = defaultInstance;
-          com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-            Group1.class, defaultInstance);
-        }
-
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 getDefaultInstance() {
-          return DEFAULT_INSTANCE;
-        }
-
-        private static volatile com.google.protobuf.Parser<Group1> PARSER;
-
-        public static com.google.protobuf.Parser<Group1> parser() {
-          return DEFAULT_INSTANCE.getParserForType();
-        }
-      }
-
-      public interface Group2OrBuilder extends
-          // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator.Group2)
-          com.google.protobuf.MessageLiteOrBuilder {
-
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 21;</code>
-         * @return Whether the field1 field is set.
-         */
-        boolean hasField1();
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 21;</code>
-         * @return The field1.
-         */
-        com.google.protobuf.UnittestLite.TestAllTypesLite getField1();
-      }
-      /**
-       * Protobuf type {@code protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator.Group2}
-       */
-      public  static final class Group2 extends
-          com.google.protobuf.GeneratedMessageLite<
-              Group2, Group2.Builder> implements
-          // @@protoc_insertion_point(message_implements:protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator.Group2)
-          Group2OrBuilder {
-        private Group2() {
-        }
-        private int bitField0_;
-        public static final int FIELD1_FIELD_NUMBER = 21;
-        private com.google.protobuf.UnittestLite.TestAllTypesLite field1_;
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 21;</code>
-         */
-        @java.lang.Override
-        public boolean hasField1() {
-          return ((bitField0_ & 0x00000001) != 0);
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 21;</code>
-         */
-        @java.lang.Override
-        public com.google.protobuf.UnittestLite.TestAllTypesLite getField1() {
-          return field1_ == null ? com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance() : field1_;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 21;</code>
-         */
-        private void setField1(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          value.getClass();
-  field1_ = value;
-          bitField0_ |= 0x00000001;
-          }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 21;</code>
-         */
-        @java.lang.SuppressWarnings({"ReferenceEquality"})
-        private void mergeField1(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          value.getClass();
-  if (field1_ != null &&
-              field1_ != com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance()) {
-            field1_ =
-              com.google.protobuf.UnittestLite.TestAllTypesLite.newBuilder(field1_).mergeFrom(value).buildPartial();
-          } else {
-            field1_ = value;
-          }
-          bitField0_ |= 0x00000001;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 21;</code>
-         */
-        private void clearField1() {  field1_ = null;
-          bitField0_ = (bitField0_ & ~0x00000001);
-        }
-
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 parseFrom(
-            java.nio.ByteBuffer data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 parseFrom(
-            java.nio.ByteBuffer data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data, extensionRegistry);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 parseFrom(
-            com.google.protobuf.ByteString data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 parseFrom(
-            com.google.protobuf.ByteString data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data, extensionRegistry);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 parseFrom(byte[] data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 parseFrom(
-            byte[] data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data, extensionRegistry);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 parseFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 parseFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input, extensionRegistry);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 parseDelimitedFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 parseDelimitedFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 parseFrom(
-            com.google.protobuf.CodedInputStream input)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input);
-        }
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 parseFrom(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input, extensionRegistry);
-        }
-
-        public static Builder newBuilder() {
-          return (Builder) DEFAULT_INSTANCE.createBuilder();
-        }
-        public static Builder newBuilder(com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 prototype) {
-          return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-        }
-
-        /**
-         * Protobuf type {@code protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator.Group2}
-         */
-        public static final class Builder extends
-            com.google.protobuf.GeneratedMessageLite.Builder<
-              com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2, Builder> implements
-            // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator.Group2)
-            com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2OrBuilder {
-          // Construct using com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2.newBuilder()
-          private Builder() {
-            super(DEFAULT_INSTANCE);
-          }
-
-
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 21;</code>
-           */
-          @java.lang.Override
-          public boolean hasField1() {
-            return instance.hasField1();
-          }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 21;</code>
-           */
-          @java.lang.Override
-          public com.google.protobuf.UnittestLite.TestAllTypesLite getField1() {
-            return instance.getField1();
-          }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 21;</code>
-           */
-          public Builder setField1(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-            copyOnWrite();
-            instance.setField1(value);
-            return this;
-            }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 21;</code>
-           */
-          public Builder setField1(
-              com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-            copyOnWrite();
-            instance.setField1(builderForValue.build());
-            return this;
-          }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 21;</code>
-           */
-          public Builder mergeField1(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-            copyOnWrite();
-            instance.mergeField1(value);
-            return this;
-          }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypesLite field1 = 21;</code>
-           */
-          public Builder clearField1() {  copyOnWrite();
-            instance.clearField1();
-            return this;
-          }
-
-          // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator.Group2)
-        }
-        @java.lang.Override
-        @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-        protected final java.lang.Object dynamicMethod(
-            com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-            java.lang.Object arg0, java.lang.Object arg1) {
-          switch (method) {
-            case NEW_MUTABLE_INSTANCE: {
-              return new com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2();
-            }
-            case NEW_BUILDER: {
-              return new Builder();
-            }
-            case BUILD_MESSAGE_INFO: {
-                java.lang.Object[] objects = new java.lang.Object[] {
-                  "bitField0_",
-                  "field1_",
-                };
-                java.lang.String info =
-                    "\u0001\u0001\u0000\u0001\u0015\u0015\u0001\u0000\u0000\u0000\u0015\u1009\u0000";
-                return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-            }
-            // fall through
-            case GET_DEFAULT_INSTANCE: {
-              return DEFAULT_INSTANCE;
-            }
-            case GET_PARSER: {
-              com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2> parser = PARSER;
-              if (parser == null) {
-                synchronized (com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2.class) {
-                  parser = PARSER;
-                  if (parser == null) {
-                    parser =
-                        new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2>(
-                            DEFAULT_INSTANCE);
-                    PARSER = parser;
-                  }
-                }
-              }
-              return parser;
-          }
-          case GET_MEMOIZED_IS_INITIALIZED: {
-            return (byte) 1;
-          }
-          case SET_MEMOIZED_IS_INITIALIZED: {
-            return null;
-          }
-          }
-          throw new UnsupportedOperationException();
-        }
-
-
-        // @@protoc_insertion_point(class_scope:protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator.Group2)
-        private static final com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 DEFAULT_INSTANCE;
-        static {
-          Group2 defaultInstance = new Group2();
-          // New instances are implicitly immutable so no need to make
-          // immutable.
-          DEFAULT_INSTANCE = defaultInstance;
-          com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-            Group2.class, defaultInstance);
-        }
-
-        public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 getDefaultInstance() {
-          return DEFAULT_INSTANCE;
-        }
-
-        private static volatile com.google.protobuf.Parser<Group2> PARSER;
-
-        public static com.google.protobuf.Parser<Group2> parser() {
-          return DEFAULT_INSTANCE.getParserForType();
-        }
-      }
-
-      public static final int FIELD1_FIELD_NUMBER = 1;
-      private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestAllTypesLite> field1_;
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite> getField1List() {
-        return field1_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       */
-      public java.util.List<? extends com.google.protobuf.UnittestLite.TestAllTypesLiteOrBuilder> 
-          getField1OrBuilderList() {
-        return field1_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       */
-      @java.lang.Override
-      public int getField1Count() {
-        return field1_.size();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite getField1(int index) {
-        return field1_.get(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       */
-      public com.google.protobuf.UnittestLite.TestAllTypesLiteOrBuilder getField1OrBuilder(
-          int index) {
-        return field1_.get(index);
-      }
-      private void ensureField1IsMutable() {
-        com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestAllTypesLite> tmp = field1_;
-        if (!tmp.isModifiable()) {
-          field1_ =
-              com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-         }
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       */
-      private void setField1(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        value.getClass();
-  ensureField1IsMutable();
-        field1_.set(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       */
-      private void addField1(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        value.getClass();
-  ensureField1IsMutable();
-        field1_.add(value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       */
-      private void addField1(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        value.getClass();
-  ensureField1IsMutable();
-        field1_.add(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       */
-      private void addAllField1(
-          java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite> values) {
-        ensureField1IsMutable();
-        com.google.protobuf.AbstractMessageLite.addAll(
-            values, field1_);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       */
-      private void clearField1() {
-        field1_ = emptyProtobufList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-       */
-      private void removeField1(int index) {
-        ensureField1IsMutable();
-        field1_.remove(index);
-      }
-
-      public static final int FIELD2_FIELD_NUMBER = 2;
-      private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestAllTypesLite> field2_;
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite> getField2List() {
-        return field2_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       */
-      public java.util.List<? extends com.google.protobuf.UnittestLite.TestAllTypesLiteOrBuilder> 
-          getField2OrBuilderList() {
-        return field2_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       */
-      @java.lang.Override
-      public int getField2Count() {
-        return field2_.size();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite getField2(int index) {
-        return field2_.get(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       */
-      public com.google.protobuf.UnittestLite.TestAllTypesLiteOrBuilder getField2OrBuilder(
-          int index) {
-        return field2_.get(index);
-      }
-      private void ensureField2IsMutable() {
-        com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestAllTypesLite> tmp = field2_;
-        if (!tmp.isModifiable()) {
-          field2_ =
-              com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-         }
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       */
-      private void setField2(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        value.getClass();
-  ensureField2IsMutable();
-        field2_.set(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       */
-      private void addField2(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        value.getClass();
-  ensureField2IsMutable();
-        field2_.add(value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       */
-      private void addField2(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        value.getClass();
-  ensureField2IsMutable();
-        field2_.add(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       */
-      private void addAllField2(
-          java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite> values) {
-        ensureField2IsMutable();
-        com.google.protobuf.AbstractMessageLite.addAll(
-            values, field2_);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       */
-      private void clearField2() {
-        field2_ = emptyProtobufList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-       */
-      private void removeField2(int index) {
-        ensureField2IsMutable();
-        field2_.remove(index);
-      }
-
-      public static final int FIELD3_FIELD_NUMBER = 3;
-      private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestAllTypesLite> field3_;
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite> getField3List() {
-        return field3_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       */
-      public java.util.List<? extends com.google.protobuf.UnittestLite.TestAllTypesLiteOrBuilder> 
-          getField3OrBuilderList() {
-        return field3_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       */
-      @java.lang.Override
-      public int getField3Count() {
-        return field3_.size();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite getField3(int index) {
-        return field3_.get(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       */
-      public com.google.protobuf.UnittestLite.TestAllTypesLiteOrBuilder getField3OrBuilder(
-          int index) {
-        return field3_.get(index);
-      }
-      private void ensureField3IsMutable() {
-        com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestAllTypesLite> tmp = field3_;
-        if (!tmp.isModifiable()) {
-          field3_ =
-              com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-         }
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       */
-      private void setField3(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        value.getClass();
-  ensureField3IsMutable();
-        field3_.set(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       */
-      private void addField3(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        value.getClass();
-  ensureField3IsMutable();
-        field3_.add(value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       */
-      private void addField3(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        value.getClass();
-  ensureField3IsMutable();
-        field3_.add(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       */
-      private void addAllField3(
-          java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite> values) {
-        ensureField3IsMutable();
-        com.google.protobuf.AbstractMessageLite.addAll(
-            values, field3_);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       */
-      private void clearField3() {
-        field3_ = emptyProtobufList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-       */
-      private void removeField3(int index) {
-        ensureField3IsMutable();
-        field3_.remove(index);
-      }
-
-      public static final int GROUP1_FIELD_NUMBER = 10;
-      private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1> group1_;
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1> getGroup1List() {
-        return group1_;
-      }
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      public java.util.List<? extends com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1OrBuilder> 
-          getGroup1OrBuilderList() {
-        return group1_;
-      }
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      @java.lang.Override
-      public int getGroup1Count() {
-        return group1_.size();
-      }
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 getGroup1(int index) {
-        return group1_.get(index);
-      }
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      public com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1OrBuilder getGroup1OrBuilder(
-          int index) {
-        return group1_.get(index);
-      }
-      private void ensureGroup1IsMutable() {
-        com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1> tmp = group1_;
-        if (!tmp.isModifiable()) {
-          group1_ =
-              com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-         }
-      }
-
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      private void setGroup1(
-          int index, com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 value) {
-        value.getClass();
-  ensureGroup1IsMutable();
-        group1_.set(index, value);
-      }
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      private void addGroup1(com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 value) {
-        value.getClass();
-  ensureGroup1IsMutable();
-        group1_.add(value);
-      }
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      private void addGroup1(
-          int index, com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 value) {
-        value.getClass();
-  ensureGroup1IsMutable();
-        group1_.add(index, value);
-      }
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      private void addAllGroup1(
-          java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1> values) {
-        ensureGroup1IsMutable();
-        com.google.protobuf.AbstractMessageLite.addAll(
-            values, group1_);
-      }
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      private void clearGroup1() {
-        group1_ = emptyProtobufList();
-      }
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      private void removeGroup1(int index) {
-        ensureGroup1IsMutable();
-        group1_.remove(index);
-      }
-
-      public static final int GROUP2_FIELD_NUMBER = 20;
-      private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2> group2_;
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2> getGroup2List() {
-        return group2_;
-      }
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      public java.util.List<? extends com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2OrBuilder> 
-          getGroup2OrBuilderList() {
-        return group2_;
-      }
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      @java.lang.Override
-      public int getGroup2Count() {
-        return group2_.size();
-      }
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 getGroup2(int index) {
-        return group2_.get(index);
-      }
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      public com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2OrBuilder getGroup2OrBuilder(
-          int index) {
-        return group2_.get(index);
-      }
-      private void ensureGroup2IsMutable() {
-        com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2> tmp = group2_;
-        if (!tmp.isModifiable()) {
-          group2_ =
-              com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-         }
-      }
-
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      private void setGroup2(
-          int index, com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 value) {
-        value.getClass();
-  ensureGroup2IsMutable();
-        group2_.set(index, value);
-      }
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      private void addGroup2(com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 value) {
-        value.getClass();
-  ensureGroup2IsMutable();
-        group2_.add(value);
-      }
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      private void addGroup2(
-          int index, com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 value) {
-        value.getClass();
-  ensureGroup2IsMutable();
-        group2_.add(index, value);
-      }
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      private void addAllGroup2(
-          java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2> values) {
-        ensureGroup2IsMutable();
-        com.google.protobuf.AbstractMessageLite.addAll(
-            values, group2_);
-      }
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      private void clearGroup2() {
-        group2_ = emptyProtobufList();
-      }
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      private void removeGroup2(int index) {
-        ensureGroup2IsMutable();
-        group2_.remove(index);
-      }
-
-      public static final int EXT1_FIELD_NUMBER = 1000;
-      private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestAllTypesLite> ext1_;
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite> getExt1List() {
-        return ext1_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       */
-      public java.util.List<? extends com.google.protobuf.UnittestLite.TestAllTypesLiteOrBuilder> 
-          getExt1OrBuilderList() {
-        return ext1_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       */
-      @java.lang.Override
-      public int getExt1Count() {
-        return ext1_.size();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite getExt1(int index) {
-        return ext1_.get(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       */
-      public com.google.protobuf.UnittestLite.TestAllTypesLiteOrBuilder getExt1OrBuilder(
-          int index) {
-        return ext1_.get(index);
-      }
-      private void ensureExt1IsMutable() {
-        com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestAllTypesLite> tmp = ext1_;
-        if (!tmp.isModifiable()) {
-          ext1_ =
-              com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-         }
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       */
-      private void setExt1(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        value.getClass();
-  ensureExt1IsMutable();
-        ext1_.set(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       */
-      private void addExt1(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        value.getClass();
-  ensureExt1IsMutable();
-        ext1_.add(value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       */
-      private void addExt1(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        value.getClass();
-  ensureExt1IsMutable();
-        ext1_.add(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       */
-      private void addAllExt1(
-          java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite> values) {
-        ensureExt1IsMutable();
-        com.google.protobuf.AbstractMessageLite.addAll(
-            values, ext1_);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       */
-      private void clearExt1() {
-        ext1_ = emptyProtobufList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-       */
-      private void removeExt1(int index) {
-        ensureExt1IsMutable();
-        ext1_.remove(index);
-      }
-
-      public static final int EXT2_FIELD_NUMBER = 1001;
-      private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestAllTypesLite> ext2_;
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite> getExt2List() {
-        return ext2_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       */
-      public java.util.List<? extends com.google.protobuf.UnittestLite.TestAllTypesLiteOrBuilder> 
-          getExt2OrBuilderList() {
-        return ext2_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       */
-      @java.lang.Override
-      public int getExt2Count() {
-        return ext2_.size();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite getExt2(int index) {
-        return ext2_.get(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       */
-      public com.google.protobuf.UnittestLite.TestAllTypesLiteOrBuilder getExt2OrBuilder(
-          int index) {
-        return ext2_.get(index);
-      }
-      private void ensureExt2IsMutable() {
-        com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestAllTypesLite> tmp = ext2_;
-        if (!tmp.isModifiable()) {
-          ext2_ =
-              com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-         }
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       */
-      private void setExt2(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        value.getClass();
-  ensureExt2IsMutable();
-        ext2_.set(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       */
-      private void addExt2(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        value.getClass();
-  ensureExt2IsMutable();
-        ext2_.add(value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       */
-      private void addExt2(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        value.getClass();
-  ensureExt2IsMutable();
-        ext2_.add(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       */
-      private void addAllExt2(
-          java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite> values) {
-        ensureExt2IsMutable();
-        com.google.protobuf.AbstractMessageLite.addAll(
-            values, ext2_);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       */
-      private void clearExt2() {
-        ext2_ = emptyProtobufList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-       */
-      private void removeExt2(int index) {
-        ensureExt2IsMutable();
-        ext2_.remove(index);
-      }
-
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator)
-          com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGeneratorOrBuilder {
-        // Construct using com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-         */
-        @java.lang.Override
-        public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite> getField1List() {
-          return java.util.Collections.unmodifiableList(
-              instance.getField1List());
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-         */
-        @java.lang.Override
-        public int getField1Count() {
-          return instance.getField1Count();
-        }/**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-         */
-        @java.lang.Override
-        public com.google.protobuf.UnittestLite.TestAllTypesLite getField1(int index) {
-          return instance.getField1(index);
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-         */
-        public Builder setField1(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          copyOnWrite();
-          instance.setField1(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-         */
-        public Builder setField1(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-          copyOnWrite();
-          instance.setField1(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-         */
-        public Builder addField1(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          copyOnWrite();
-          instance.addField1(value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-         */
-        public Builder addField1(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          copyOnWrite();
-          instance.addField1(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-         */
-        public Builder addField1(
-            com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-          copyOnWrite();
-          instance.addField1(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-         */
-        public Builder addField1(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-          copyOnWrite();
-          instance.addField1(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-         */
-        public Builder addAllField1(
-            java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite> values) {
-          copyOnWrite();
-          instance.addAllField1(values);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-         */
-        public Builder clearField1() {
-          copyOnWrite();
-          instance.clearField1();
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field1 = 1;</code>
-         */
-        public Builder removeField1(int index) {
-          copyOnWrite();
-          instance.removeField1(index);
-          return this;
-        }
-
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-         */
-        @java.lang.Override
-        public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite> getField2List() {
-          return java.util.Collections.unmodifiableList(
-              instance.getField2List());
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-         */
-        @java.lang.Override
-        public int getField2Count() {
-          return instance.getField2Count();
-        }/**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-         */
-        @java.lang.Override
-        public com.google.protobuf.UnittestLite.TestAllTypesLite getField2(int index) {
-          return instance.getField2(index);
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-         */
-        public Builder setField2(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          copyOnWrite();
-          instance.setField2(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-         */
-        public Builder setField2(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-          copyOnWrite();
-          instance.setField2(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-         */
-        public Builder addField2(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          copyOnWrite();
-          instance.addField2(value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-         */
-        public Builder addField2(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          copyOnWrite();
-          instance.addField2(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-         */
-        public Builder addField2(
-            com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-          copyOnWrite();
-          instance.addField2(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-         */
-        public Builder addField2(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-          copyOnWrite();
-          instance.addField2(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-         */
-        public Builder addAllField2(
-            java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite> values) {
-          copyOnWrite();
-          instance.addAllField2(values);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-         */
-        public Builder clearField2() {
-          copyOnWrite();
-          instance.clearField2();
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field2 = 2;</code>
-         */
-        public Builder removeField2(int index) {
-          copyOnWrite();
-          instance.removeField2(index);
-          return this;
-        }
-
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-         */
-        @java.lang.Override
-        public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite> getField3List() {
-          return java.util.Collections.unmodifiableList(
-              instance.getField3List());
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-         */
-        @java.lang.Override
-        public int getField3Count() {
-          return instance.getField3Count();
-        }/**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-         */
-        @java.lang.Override
-        public com.google.protobuf.UnittestLite.TestAllTypesLite getField3(int index) {
-          return instance.getField3(index);
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-         */
-        public Builder setField3(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          copyOnWrite();
-          instance.setField3(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-         */
-        public Builder setField3(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-          copyOnWrite();
-          instance.setField3(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-         */
-        public Builder addField3(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          copyOnWrite();
-          instance.addField3(value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-         */
-        public Builder addField3(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          copyOnWrite();
-          instance.addField3(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-         */
-        public Builder addField3(
-            com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-          copyOnWrite();
-          instance.addField3(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-         */
-        public Builder addField3(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-          copyOnWrite();
-          instance.addField3(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-         */
-        public Builder addAllField3(
-            java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite> values) {
-          copyOnWrite();
-          instance.addAllField3(values);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-         */
-        public Builder clearField3() {
-          copyOnWrite();
-          instance.clearField3();
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite field3 = 3;</code>
-         */
-        public Builder removeField3(int index) {
-          copyOnWrite();
-          instance.removeField3(index);
-          return this;
-        }
-
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        @java.lang.Override
-        public java.util.List<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1> getGroup1List() {
-          return java.util.Collections.unmodifiableList(
-              instance.getGroup1List());
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        @java.lang.Override
-        public int getGroup1Count() {
-          return instance.getGroup1Count();
-        }/**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        @java.lang.Override
-        public com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 getGroup1(int index) {
-          return instance.getGroup1(index);
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        public Builder setGroup1(
-            int index, com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 value) {
-          copyOnWrite();
-          instance.setGroup1(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        public Builder setGroup1(
-            int index, com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1.Builder builderForValue) {
-          copyOnWrite();
-          instance.setGroup1(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        public Builder addGroup1(com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 value) {
-          copyOnWrite();
-          instance.addGroup1(value);
-          return this;
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        public Builder addGroup1(
-            int index, com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1 value) {
-          copyOnWrite();
-          instance.addGroup1(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        public Builder addGroup1(
-            com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1.Builder builderForValue) {
-          copyOnWrite();
-          instance.addGroup1(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        public Builder addGroup1(
-            int index, com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1.Builder builderForValue) {
-          copyOnWrite();
-          instance.addGroup1(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        public Builder addAllGroup1(
-            java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1> values) {
-          copyOnWrite();
-          instance.addAllGroup1(values);
-          return this;
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        public Builder clearGroup1() {
-          copyOnWrite();
-          instance.clearGroup1();
-          return this;
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        public Builder removeGroup1(int index) {
-          copyOnWrite();
-          instance.removeGroup1(index);
-          return this;
-        }
-
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        @java.lang.Override
-        public java.util.List<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2> getGroup2List() {
-          return java.util.Collections.unmodifiableList(
-              instance.getGroup2List());
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        @java.lang.Override
-        public int getGroup2Count() {
-          return instance.getGroup2Count();
-        }/**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        @java.lang.Override
-        public com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 getGroup2(int index) {
-          return instance.getGroup2(index);
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        public Builder setGroup2(
-            int index, com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 value) {
-          copyOnWrite();
-          instance.setGroup2(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        public Builder setGroup2(
-            int index, com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2.Builder builderForValue) {
-          copyOnWrite();
-          instance.setGroup2(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        public Builder addGroup2(com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 value) {
-          copyOnWrite();
-          instance.addGroup2(value);
-          return this;
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        public Builder addGroup2(
-            int index, com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2 value) {
-          copyOnWrite();
-          instance.addGroup2(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        public Builder addGroup2(
-            com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2.Builder builderForValue) {
-          copyOnWrite();
-          instance.addGroup2(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        public Builder addGroup2(
-            int index, com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2.Builder builderForValue) {
-          copyOnWrite();
-          instance.addGroup2(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        public Builder addAllGroup2(
-            java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2> values) {
-          copyOnWrite();
-          instance.addAllGroup2(values);
-          return this;
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        public Builder clearGroup2() {
-          copyOnWrite();
-          instance.clearGroup2();
-          return this;
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        public Builder removeGroup2(int index) {
-          copyOnWrite();
-          instance.removeGroup2(index);
-          return this;
-        }
-
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-         */
-        @java.lang.Override
-        public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite> getExt1List() {
-          return java.util.Collections.unmodifiableList(
-              instance.getExt1List());
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-         */
-        @java.lang.Override
-        public int getExt1Count() {
-          return instance.getExt1Count();
-        }/**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-         */
-        @java.lang.Override
-        public com.google.protobuf.UnittestLite.TestAllTypesLite getExt1(int index) {
-          return instance.getExt1(index);
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-         */
-        public Builder setExt1(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          copyOnWrite();
-          instance.setExt1(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-         */
-        public Builder setExt1(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-          copyOnWrite();
-          instance.setExt1(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-         */
-        public Builder addExt1(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          copyOnWrite();
-          instance.addExt1(value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-         */
-        public Builder addExt1(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          copyOnWrite();
-          instance.addExt1(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-         */
-        public Builder addExt1(
-            com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-          copyOnWrite();
-          instance.addExt1(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-         */
-        public Builder addExt1(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-          copyOnWrite();
-          instance.addExt1(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-         */
-        public Builder addAllExt1(
-            java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite> values) {
-          copyOnWrite();
-          instance.addAllExt1(values);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-         */
-        public Builder clearExt1() {
-          copyOnWrite();
-          instance.clearExt1();
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext1 = 1000;</code>
-         */
-        public Builder removeExt1(int index) {
-          copyOnWrite();
-          instance.removeExt1(index);
-          return this;
-        }
-
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-         */
-        @java.lang.Override
-        public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite> getExt2List() {
-          return java.util.Collections.unmodifiableList(
-              instance.getExt2List());
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-         */
-        @java.lang.Override
-        public int getExt2Count() {
-          return instance.getExt2Count();
-        }/**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-         */
-        @java.lang.Override
-        public com.google.protobuf.UnittestLite.TestAllTypesLite getExt2(int index) {
-          return instance.getExt2(index);
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-         */
-        public Builder setExt2(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          copyOnWrite();
-          instance.setExt2(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-         */
-        public Builder setExt2(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-          copyOnWrite();
-          instance.setExt2(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-         */
-        public Builder addExt2(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          copyOnWrite();
-          instance.addExt2(value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-         */
-        public Builder addExt2(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          copyOnWrite();
-          instance.addExt2(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-         */
-        public Builder addExt2(
-            com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-          copyOnWrite();
-          instance.addExt2(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-         */
-        public Builder addExt2(
-            int index, com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-          copyOnWrite();
-          instance.addExt2(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-         */
-        public Builder addAllExt2(
-            java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite> values) {
-          copyOnWrite();
-          instance.addAllExt2(values);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-         */
-        public Builder clearExt2() {
-          copyOnWrite();
-          instance.clearExt2();
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypesLite ext2 = 1001;</code>
-         */
-        public Builder removeExt2(int index) {
-          copyOnWrite();
-          instance.removeExt2(index);
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "field1_",
-                com.google.protobuf.UnittestLite.TestAllTypesLite.class,
-                "field2_",
-                com.google.protobuf.UnittestLite.TestAllTypesLite.class,
-                "field3_",
-                com.google.protobuf.UnittestLite.TestAllTypesLite.class,
-                "group1_",
-                com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group1.class,
-                "group2_",
-                com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.Group2.class,
-                "ext1_",
-                com.google.protobuf.UnittestLite.TestAllTypesLite.class,
-                "ext2_",
-                com.google.protobuf.UnittestLite.TestAllTypesLite.class,
-              };
-              java.lang.String info =
-                  "\u0001\u0007\u0000\u0000\u0001\u03e9\u0007\u0000\u0007\u0000\u0001\u001b\u0002\u001b" +
-                  "\u0003\u001b\n1\u00141\u03e8\u001b\u03e9\u001b";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator> parser = PARSER;
-            if (parser == null) {
-              synchronized (com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestParsingMergeLite.RepeatedFieldsGenerator)
-      private static final com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator DEFAULT_INSTANCE;
-      static {
-        RepeatedFieldsGenerator defaultInstance = new RepeatedFieldsGenerator();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          RepeatedFieldsGenerator.class, defaultInstance);
-      }
-
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedFieldsGenerator getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<RepeatedFieldsGenerator> PARSER;
-
-      public static com.google.protobuf.Parser<RepeatedFieldsGenerator> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    public interface OptionalGroupOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestParsingMergeLite.OptionalGroup)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite optional_group_all_types = 11;</code>
-       * @return Whether the optionalGroupAllTypes field is set.
-       */
-      boolean hasOptionalGroupAllTypes();
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite optional_group_all_types = 11;</code>
-       * @return The optionalGroupAllTypes.
-       */
-      com.google.protobuf.UnittestLite.TestAllTypesLite getOptionalGroupAllTypes();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestParsingMergeLite.OptionalGroup}
-     */
-    public  static final class OptionalGroup extends
-        com.google.protobuf.GeneratedMessageLite<
-            OptionalGroup, OptionalGroup.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestParsingMergeLite.OptionalGroup)
-        OptionalGroupOrBuilder {
-      private OptionalGroup() {
-      }
-      private int bitField0_;
-      public static final int OPTIONAL_GROUP_ALL_TYPES_FIELD_NUMBER = 11;
-      private com.google.protobuf.UnittestLite.TestAllTypesLite optionalGroupAllTypes_;
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite optional_group_all_types = 11;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalGroupAllTypes() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite optional_group_all_types = 11;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite getOptionalGroupAllTypes() {
-        return optionalGroupAllTypes_ == null ? com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance() : optionalGroupAllTypes_;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite optional_group_all_types = 11;</code>
-       */
-      private void setOptionalGroupAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        value.getClass();
-  optionalGroupAllTypes_ = value;
-        bitField0_ |= 0x00000001;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite optional_group_all_types = 11;</code>
-       */
-      @java.lang.SuppressWarnings({"ReferenceEquality"})
-      private void mergeOptionalGroupAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        value.getClass();
-  if (optionalGroupAllTypes_ != null &&
-            optionalGroupAllTypes_ != com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance()) {
-          optionalGroupAllTypes_ =
-            com.google.protobuf.UnittestLite.TestAllTypesLite.newBuilder(optionalGroupAllTypes_).mergeFrom(value).buildPartial();
-        } else {
-          optionalGroupAllTypes_ = value;
-        }
-        bitField0_ |= 0x00000001;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite optional_group_all_types = 11;</code>
-       */
-      private void clearOptionalGroupAllTypes() {  optionalGroupAllTypes_ = null;
-        bitField0_ = (bitField0_ & ~0x00000001);
-      }
-
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestParsingMergeLite.OptionalGroup}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestParsingMergeLite.OptionalGroup)
-          com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroupOrBuilder {
-        // Construct using com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite optional_group_all_types = 11;</code>
-         */
-        @java.lang.Override
-        public boolean hasOptionalGroupAllTypes() {
-          return instance.hasOptionalGroupAllTypes();
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite optional_group_all_types = 11;</code>
-         */
-        @java.lang.Override
-        public com.google.protobuf.UnittestLite.TestAllTypesLite getOptionalGroupAllTypes() {
-          return instance.getOptionalGroupAllTypes();
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite optional_group_all_types = 11;</code>
-         */
-        public Builder setOptionalGroupAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          copyOnWrite();
-          instance.setOptionalGroupAllTypes(value);
-          return this;
-          }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite optional_group_all_types = 11;</code>
-         */
-        public Builder setOptionalGroupAllTypes(
-            com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-          copyOnWrite();
-          instance.setOptionalGroupAllTypes(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite optional_group_all_types = 11;</code>
-         */
-        public Builder mergeOptionalGroupAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          copyOnWrite();
-          instance.mergeOptionalGroupAllTypes(value);
-          return this;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite optional_group_all_types = 11;</code>
-         */
-        public Builder clearOptionalGroupAllTypes() {  copyOnWrite();
-          instance.clearOptionalGroupAllTypes();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestParsingMergeLite.OptionalGroup)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "optionalGroupAllTypes_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\u000b\u000b\u0001\u0000\u0000\u0000\u000b\u1009\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup> parser = PARSER;
-            if (parser == null) {
-              synchronized (com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestParsingMergeLite.OptionalGroup)
-      private static final com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup DEFAULT_INSTANCE;
-      static {
-        OptionalGroup defaultInstance = new OptionalGroup();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          OptionalGroup.class, defaultInstance);
-      }
-
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<OptionalGroup> PARSER;
-
-      public static com.google.protobuf.Parser<OptionalGroup> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    public interface RepeatedGroupOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestParsingMergeLite.RepeatedGroup)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite repeated_group_all_types = 21;</code>
-       * @return Whether the repeatedGroupAllTypes field is set.
-       */
-      boolean hasRepeatedGroupAllTypes();
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite repeated_group_all_types = 21;</code>
-       * @return The repeatedGroupAllTypes.
-       */
-      com.google.protobuf.UnittestLite.TestAllTypesLite getRepeatedGroupAllTypes();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestParsingMergeLite.RepeatedGroup}
-     */
-    public  static final class RepeatedGroup extends
-        com.google.protobuf.GeneratedMessageLite<
-            RepeatedGroup, RepeatedGroup.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestParsingMergeLite.RepeatedGroup)
-        RepeatedGroupOrBuilder {
-      private RepeatedGroup() {
-      }
-      private int bitField0_;
-      public static final int REPEATED_GROUP_ALL_TYPES_FIELD_NUMBER = 21;
-      private com.google.protobuf.UnittestLite.TestAllTypesLite repeatedGroupAllTypes_;
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite repeated_group_all_types = 21;</code>
-       */
-      @java.lang.Override
-      public boolean hasRepeatedGroupAllTypes() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite repeated_group_all_types = 21;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite getRepeatedGroupAllTypes() {
-        return repeatedGroupAllTypes_ == null ? com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance() : repeatedGroupAllTypes_;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite repeated_group_all_types = 21;</code>
-       */
-      private void setRepeatedGroupAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        value.getClass();
-  repeatedGroupAllTypes_ = value;
-        bitField0_ |= 0x00000001;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite repeated_group_all_types = 21;</code>
-       */
-      @java.lang.SuppressWarnings({"ReferenceEquality"})
-      private void mergeRepeatedGroupAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        value.getClass();
-  if (repeatedGroupAllTypes_ != null &&
-            repeatedGroupAllTypes_ != com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance()) {
-          repeatedGroupAllTypes_ =
-            com.google.protobuf.UnittestLite.TestAllTypesLite.newBuilder(repeatedGroupAllTypes_).mergeFrom(value).buildPartial();
-        } else {
-          repeatedGroupAllTypes_ = value;
-        }
-        bitField0_ |= 0x00000001;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite repeated_group_all_types = 21;</code>
-       */
-      private void clearRepeatedGroupAllTypes() {  repeatedGroupAllTypes_ = null;
-        bitField0_ = (bitField0_ & ~0x00000001);
-      }
-
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestParsingMergeLite.RepeatedGroup}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestParsingMergeLite.RepeatedGroup)
-          com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroupOrBuilder {
-        // Construct using com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite repeated_group_all_types = 21;</code>
-         */
-        @java.lang.Override
-        public boolean hasRepeatedGroupAllTypes() {
-          return instance.hasRepeatedGroupAllTypes();
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite repeated_group_all_types = 21;</code>
-         */
-        @java.lang.Override
-        public com.google.protobuf.UnittestLite.TestAllTypesLite getRepeatedGroupAllTypes() {
-          return instance.getRepeatedGroupAllTypes();
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite repeated_group_all_types = 21;</code>
-         */
-        public Builder setRepeatedGroupAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          copyOnWrite();
-          instance.setRepeatedGroupAllTypes(value);
-          return this;
-          }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite repeated_group_all_types = 21;</code>
-         */
-        public Builder setRepeatedGroupAllTypes(
-            com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-          copyOnWrite();
-          instance.setRepeatedGroupAllTypes(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite repeated_group_all_types = 21;</code>
-         */
-        public Builder mergeRepeatedGroupAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-          copyOnWrite();
-          instance.mergeRepeatedGroupAllTypes(value);
-          return this;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypesLite repeated_group_all_types = 21;</code>
-         */
-        public Builder clearRepeatedGroupAllTypes() {  copyOnWrite();
-          instance.clearRepeatedGroupAllTypes();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestParsingMergeLite.RepeatedGroup)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "repeatedGroupAllTypes_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\u0015\u0015\u0001\u0000\u0000\u0000\u0015\u1009\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup> parser = PARSER;
-            if (parser == null) {
-              synchronized (com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestParsingMergeLite.RepeatedGroup)
-      private static final com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup DEFAULT_INSTANCE;
-      static {
-        RepeatedGroup defaultInstance = new RepeatedGroup();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          RepeatedGroup.class, defaultInstance);
-      }
-
-      public static com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<RepeatedGroup> PARSER;
-
-      public static com.google.protobuf.Parser<RepeatedGroup> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int bitField0_;
-    public static final int REQUIRED_ALL_TYPES_FIELD_NUMBER = 1;
-    private com.google.protobuf.UnittestLite.TestAllTypesLite requiredAllTypes_;
-    /**
-     * <code>required .protobuf_unittest.TestAllTypesLite required_all_types = 1;</code>
-     */
-    @java.lang.Override
-    public boolean hasRequiredAllTypes() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>required .protobuf_unittest.TestAllTypesLite required_all_types = 1;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestAllTypesLite getRequiredAllTypes() {
-      return requiredAllTypes_ == null ? com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance() : requiredAllTypes_;
-    }
-    /**
-     * <code>required .protobuf_unittest.TestAllTypesLite required_all_types = 1;</code>
-     */
-    private void setRequiredAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-      value.getClass();
-  requiredAllTypes_ = value;
-      bitField0_ |= 0x00000001;
-      }
-    /**
-     * <code>required .protobuf_unittest.TestAllTypesLite required_all_types = 1;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeRequiredAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-      value.getClass();
-  if (requiredAllTypes_ != null &&
-          requiredAllTypes_ != com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance()) {
-        requiredAllTypes_ =
-          com.google.protobuf.UnittestLite.TestAllTypesLite.newBuilder(requiredAllTypes_).mergeFrom(value).buildPartial();
-      } else {
-        requiredAllTypes_ = value;
-      }
-      bitField0_ |= 0x00000001;
-    }
-    /**
-     * <code>required .protobuf_unittest.TestAllTypesLite required_all_types = 1;</code>
-     */
-    private void clearRequiredAllTypes() {  requiredAllTypes_ = null;
-      bitField0_ = (bitField0_ & ~0x00000001);
-    }
-
-    public static final int OPTIONAL_ALL_TYPES_FIELD_NUMBER = 2;
-    private com.google.protobuf.UnittestLite.TestAllTypesLite optionalAllTypes_;
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite optional_all_types = 2;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalAllTypes() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite optional_all_types = 2;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestAllTypesLite getOptionalAllTypes() {
-      return optionalAllTypes_ == null ? com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance() : optionalAllTypes_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite optional_all_types = 2;</code>
-     */
-    private void setOptionalAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-      value.getClass();
-  optionalAllTypes_ = value;
-      bitField0_ |= 0x00000002;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite optional_all_types = 2;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-      value.getClass();
-  if (optionalAllTypes_ != null &&
-          optionalAllTypes_ != com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance()) {
-        optionalAllTypes_ =
-          com.google.protobuf.UnittestLite.TestAllTypesLite.newBuilder(optionalAllTypes_).mergeFrom(value).buildPartial();
-      } else {
-        optionalAllTypes_ = value;
-      }
-      bitField0_ |= 0x00000002;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypesLite optional_all_types = 2;</code>
-     */
-    private void clearOptionalAllTypes() {  optionalAllTypes_ = null;
-      bitField0_ = (bitField0_ & ~0x00000002);
-    }
-
-    public static final int REPEATED_ALL_TYPES_FIELD_NUMBER = 3;
-    private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestAllTypesLite> repeatedAllTypes_;
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite> getRepeatedAllTypesList() {
-      return repeatedAllTypes_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     */
-    public java.util.List<? extends com.google.protobuf.UnittestLite.TestAllTypesLiteOrBuilder> 
-        getRepeatedAllTypesOrBuilderList() {
-      return repeatedAllTypes_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     */
-    @java.lang.Override
-    public int getRepeatedAllTypesCount() {
-      return repeatedAllTypes_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestAllTypesLite getRepeatedAllTypes(int index) {
-      return repeatedAllTypes_.get(index);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     */
-    public com.google.protobuf.UnittestLite.TestAllTypesLiteOrBuilder getRepeatedAllTypesOrBuilder(
-        int index) {
-      return repeatedAllTypes_.get(index);
-    }
-    private void ensureRepeatedAllTypesIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestAllTypesLite> tmp = repeatedAllTypes_;
-      if (!tmp.isModifiable()) {
-        repeatedAllTypes_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     */
-    private void setRepeatedAllTypes(
-        int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-      value.getClass();
-  ensureRepeatedAllTypesIsMutable();
-      repeatedAllTypes_.set(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     */
-    private void addRepeatedAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-      value.getClass();
-  ensureRepeatedAllTypesIsMutable();
-      repeatedAllTypes_.add(value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     */
-    private void addRepeatedAllTypes(
-        int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-      value.getClass();
-  ensureRepeatedAllTypesIsMutable();
-      repeatedAllTypes_.add(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     */
-    private void addAllRepeatedAllTypes(
-        java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite> values) {
-      ensureRepeatedAllTypesIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedAllTypes_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     */
-    private void clearRepeatedAllTypes() {
-      repeatedAllTypes_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-     */
-    private void removeRepeatedAllTypes(int index) {
-      ensureRepeatedAllTypesIsMutable();
-      repeatedAllTypes_.remove(index);
-    }
-
-    public static final int OPTIONALGROUP_FIELD_NUMBER = 10;
-    private com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup optionalGroup_;
-    /**
-     * <code>optional group OptionalGroup = 10 { ... }</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalGroup() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional group OptionalGroup = 10 { ... }</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup getOptionalGroup() {
-      return optionalGroup_ == null ? com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup.getDefaultInstance() : optionalGroup_;
-    }
-    /**
-     * <code>optional group OptionalGroup = 10 { ... }</code>
-     */
-    private void setOptionalGroup(com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup value) {
-      value.getClass();
-  optionalGroup_ = value;
-      bitField0_ |= 0x00000004;
-      }
-    /**
-     * <code>optional group OptionalGroup = 10 { ... }</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalGroup(com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup value) {
-      value.getClass();
-  if (optionalGroup_ != null &&
-          optionalGroup_ != com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup.getDefaultInstance()) {
-        optionalGroup_ =
-          com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup.newBuilder(optionalGroup_).mergeFrom(value).buildPartial();
-      } else {
-        optionalGroup_ = value;
-      }
-      bitField0_ |= 0x00000004;
-    }
-    /**
-     * <code>optional group OptionalGroup = 10 { ... }</code>
-     */
-    private void clearOptionalGroup() {  optionalGroup_ = null;
-      bitField0_ = (bitField0_ & ~0x00000004);
-    }
-
-    public static final int REPEATEDGROUP_FIELD_NUMBER = 20;
-    private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup> repeatedGroup_;
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup> getRepeatedGroupList() {
-      return repeatedGroup_;
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    public java.util.List<? extends com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroupOrBuilder> 
-        getRepeatedGroupOrBuilderList() {
-      return repeatedGroup_;
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    @java.lang.Override
-    public int getRepeatedGroupCount() {
-      return repeatedGroup_.size();
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup getRepeatedGroup(int index) {
-      return repeatedGroup_.get(index);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    public com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroupOrBuilder getRepeatedGroupOrBuilder(
-        int index) {
-      return repeatedGroup_.get(index);
-    }
-    private void ensureRepeatedGroupIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup> tmp = repeatedGroup_;
-      if (!tmp.isModifiable()) {
-        repeatedGroup_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    private void setRepeatedGroup(
-        int index, com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup value) {
-      value.getClass();
-  ensureRepeatedGroupIsMutable();
-      repeatedGroup_.set(index, value);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    private void addRepeatedGroup(com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup value) {
-      value.getClass();
-  ensureRepeatedGroupIsMutable();
-      repeatedGroup_.add(value);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    private void addRepeatedGroup(
-        int index, com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup value) {
-      value.getClass();
-  ensureRepeatedGroupIsMutable();
-      repeatedGroup_.add(index, value);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    private void addAllRepeatedGroup(
-        java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup> values) {
-      ensureRepeatedGroupIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedGroup_);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    private void clearRepeatedGroup() {
-      repeatedGroup_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    private void removeRepeatedGroup(int index) {
-      ensureRepeatedGroupIsMutable();
-      repeatedGroup_.remove(index);
-    }
-
-    public static com.google.protobuf.UnittestLite.TestParsingMergeLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestParsingMergeLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestParsingMergeLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestParsingMergeLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestParsingMergeLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestParsingMergeLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestParsingMergeLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestParsingMergeLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestParsingMergeLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestParsingMergeLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestParsingMergeLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestParsingMergeLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.TestParsingMergeLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * See the comments of the same type in unittest.proto.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestParsingMergeLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
-          com.google.protobuf.UnittestLite.TestParsingMergeLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestParsingMergeLite)
-        com.google.protobuf.UnittestLite.TestParsingMergeLiteOrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.TestParsingMergeLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>required .protobuf_unittest.TestAllTypesLite required_all_types = 1;</code>
-       */
-      @java.lang.Override
-      public boolean hasRequiredAllTypes() {
-        return instance.hasRequiredAllTypes();
-      }
-      /**
-       * <code>required .protobuf_unittest.TestAllTypesLite required_all_types = 1;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite getRequiredAllTypes() {
-        return instance.getRequiredAllTypes();
-      }
-      /**
-       * <code>required .protobuf_unittest.TestAllTypesLite required_all_types = 1;</code>
-       */
-      public Builder setRequiredAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        copyOnWrite();
-        instance.setRequiredAllTypes(value);
-        return this;
-        }
-      /**
-       * <code>required .protobuf_unittest.TestAllTypesLite required_all_types = 1;</code>
-       */
-      public Builder setRequiredAllTypes(
-          com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRequiredAllTypes(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>required .protobuf_unittest.TestAllTypesLite required_all_types = 1;</code>
-       */
-      public Builder mergeRequiredAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        copyOnWrite();
-        instance.mergeRequiredAllTypes(value);
-        return this;
-      }
-      /**
-       * <code>required .protobuf_unittest.TestAllTypesLite required_all_types = 1;</code>
-       */
-      public Builder clearRequiredAllTypes() {  copyOnWrite();
-        instance.clearRequiredAllTypes();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite optional_all_types = 2;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalAllTypes() {
-        return instance.hasOptionalAllTypes();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite optional_all_types = 2;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite getOptionalAllTypes() {
-        return instance.getOptionalAllTypes();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite optional_all_types = 2;</code>
-       */
-      public Builder setOptionalAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        copyOnWrite();
-        instance.setOptionalAllTypes(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite optional_all_types = 2;</code>
-       */
-      public Builder setOptionalAllTypes(
-          com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalAllTypes(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite optional_all_types = 2;</code>
-       */
-      public Builder mergeOptionalAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        copyOnWrite();
-        instance.mergeOptionalAllTypes(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypesLite optional_all_types = 2;</code>
-       */
-      public Builder clearOptionalAllTypes() {  copyOnWrite();
-        instance.clearOptionalAllTypes();
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite> getRepeatedAllTypesList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedAllTypesList());
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-       */
-      @java.lang.Override
-      public int getRepeatedAllTypesCount() {
-        return instance.getRepeatedAllTypesCount();
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite getRepeatedAllTypes(int index) {
-        return instance.getRepeatedAllTypes(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-       */
-      public Builder setRepeatedAllTypes(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        copyOnWrite();
-        instance.setRepeatedAllTypes(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-       */
-      public Builder setRepeatedAllTypes(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedAllTypes(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-       */
-      public Builder addRepeatedAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        copyOnWrite();
-        instance.addRepeatedAllTypes(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-       */
-      public Builder addRepeatedAllTypes(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        copyOnWrite();
-        instance.addRepeatedAllTypes(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-       */
-      public Builder addRepeatedAllTypes(
-          com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedAllTypes(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-       */
-      public Builder addRepeatedAllTypes(
-          int index, com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedAllTypes(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-       */
-      public Builder addAllRepeatedAllTypes(
-          java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestAllTypesLite> values) {
-        copyOnWrite();
-        instance.addAllRepeatedAllTypes(values);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-       */
-      public Builder clearRepeatedAllTypes() {
-        copyOnWrite();
-        instance.clearRepeatedAllTypes();
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypesLite repeated_all_types = 3;</code>
-       */
-      public Builder removeRepeatedAllTypes(int index) {
-        copyOnWrite();
-        instance.removeRepeatedAllTypes(index);
-        return this;
-      }
-
-      /**
-       * <code>optional group OptionalGroup = 10 { ... }</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalGroup() {
-        return instance.hasOptionalGroup();
-      }
-      /**
-       * <code>optional group OptionalGroup = 10 { ... }</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup getOptionalGroup() {
-        return instance.getOptionalGroup();
-      }
-      /**
-       * <code>optional group OptionalGroup = 10 { ... }</code>
-       */
-      public Builder setOptionalGroup(com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup value) {
-        copyOnWrite();
-        instance.setOptionalGroup(value);
-        return this;
-        }
-      /**
-       * <code>optional group OptionalGroup = 10 { ... }</code>
-       */
-      public Builder setOptionalGroup(
-          com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalGroup(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional group OptionalGroup = 10 { ... }</code>
-       */
-      public Builder mergeOptionalGroup(com.google.protobuf.UnittestLite.TestParsingMergeLite.OptionalGroup value) {
-        copyOnWrite();
-        instance.mergeOptionalGroup(value);
-        return this;
-      }
-      /**
-       * <code>optional group OptionalGroup = 10 { ... }</code>
-       */
-      public Builder clearOptionalGroup() {  copyOnWrite();
-        instance.clearOptionalGroup();
-        return this;
-      }
-
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup> getRepeatedGroupList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedGroupList());
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      @java.lang.Override
-      public int getRepeatedGroupCount() {
-        return instance.getRepeatedGroupCount();
-      }/**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup getRepeatedGroup(int index) {
-        return instance.getRepeatedGroup(index);
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      public Builder setRepeatedGroup(
-          int index, com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup value) {
-        copyOnWrite();
-        instance.setRepeatedGroup(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      public Builder setRepeatedGroup(
-          int index, com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedGroup(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      public Builder addRepeatedGroup(com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup value) {
-        copyOnWrite();
-        instance.addRepeatedGroup(value);
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      public Builder addRepeatedGroup(
-          int index, com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup value) {
-        copyOnWrite();
-        instance.addRepeatedGroup(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      public Builder addRepeatedGroup(
-          com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedGroup(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      public Builder addRepeatedGroup(
-          int index, com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedGroup(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      public Builder addAllRepeatedGroup(
-          java.lang.Iterable<? extends com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup> values) {
-        copyOnWrite();
-        instance.addAllRepeatedGroup(values);
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      public Builder clearRepeatedGroup() {
-        copyOnWrite();
-        instance.clearRepeatedGroup();
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      public Builder removeRepeatedGroup(int index) {
-        copyOnWrite();
-        instance.removeRepeatedGroup(index);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestParsingMergeLite)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.TestParsingMergeLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "requiredAllTypes_",
-              "optionalAllTypes_",
-              "repeatedAllTypes_",
-              com.google.protobuf.UnittestLite.TestAllTypesLite.class,
-              "optionalGroup_",
-              "repeatedGroup_",
-              com.google.protobuf.UnittestLite.TestParsingMergeLite.RepeatedGroup.class,
-            };
-            java.lang.String info =
-                "\u0001\u0005\u0000\u0001\u0001\u0014\u0005\u0000\u0002\u0001\u0001\u1509\u0000\u0002" +
-                "\u1009\u0001\u0003\u001b\n\u1011\u0002\u00141";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestParsingMergeLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.TestParsingMergeLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestParsingMergeLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestParsingMergeLite)
-    private static final com.google.protobuf.UnittestLite.TestParsingMergeLite DEFAULT_INSTANCE;
-    static {
-      TestParsingMergeLite defaultInstance = new TestParsingMergeLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestParsingMergeLite.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.TestParsingMergeLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestParsingMergeLite> PARSER;
-
-    public static com.google.protobuf.Parser<TestParsingMergeLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-    public static final int OPTIONAL_EXT_FIELD_NUMBER = 1000;
-    /**
-     * <code>extend .protobuf_unittest.TestParsingMergeLite { ... }</code>
-     */
-    public static final
-      com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-        com.google.protobuf.UnittestLite.TestParsingMergeLite,
-        com.google.protobuf.UnittestLite.TestAllTypesLite> optionalExt = com.google.protobuf.GeneratedMessageLite
-            .newSingularGeneratedExtension(
-          com.google.protobuf.UnittestLite.TestParsingMergeLite.getDefaultInstance(),
-          com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance(),
-          com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance(),
-          null,
-          1000,
-          com.google.protobuf.WireFormat.FieldType.MESSAGE,
-          com.google.protobuf.UnittestLite.TestAllTypesLite.class);
-    public static final int REPEATED_EXT_FIELD_NUMBER = 1001;
-    /**
-     * <code>extend .protobuf_unittest.TestParsingMergeLite { ... }</code>
-     */
-    public static final
-      com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-        com.google.protobuf.UnittestLite.TestParsingMergeLite,
-        java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite>> repeatedExt = com.google.protobuf.GeneratedMessageLite
-            .newRepeatedGeneratedExtension(
-          com.google.protobuf.UnittestLite.TestParsingMergeLite.getDefaultInstance(),
-          com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance(),
-          null,
-          1001,
-          com.google.protobuf.WireFormat.FieldType.MESSAGE,
-          false,
-          com.google.protobuf.UnittestLite.TestAllTypesLite.class);
-  }
-
-  public interface TestEmptyMessageLiteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestEmptyMessageLite)
-      com.google.protobuf.MessageLiteOrBuilder {
-  }
-  /**
-   * <pre>
-   * TestEmptyMessageLite is used to test unknown fields support in lite mode.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestEmptyMessageLite}
-   */
-  public  static final class TestEmptyMessageLite extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestEmptyMessageLite, TestEmptyMessageLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestEmptyMessageLite)
-      TestEmptyMessageLiteOrBuilder {
-    private TestEmptyMessageLite() {
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.TestEmptyMessageLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * TestEmptyMessageLite is used to test unknown fields support in lite mode.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestEmptyMessageLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.UnittestLite.TestEmptyMessageLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestEmptyMessageLite)
-        com.google.protobuf.UnittestLite.TestEmptyMessageLiteOrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.TestEmptyMessageLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestEmptyMessageLite)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.TestEmptyMessageLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestEmptyMessageLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.TestEmptyMessageLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestEmptyMessageLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestEmptyMessageLite)
-    private static final com.google.protobuf.UnittestLite.TestEmptyMessageLite DEFAULT_INSTANCE;
-    static {
-      TestEmptyMessageLite defaultInstance = new TestEmptyMessageLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestEmptyMessageLite.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestEmptyMessageLite> PARSER;
-
-    public static com.google.protobuf.Parser<TestEmptyMessageLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestEmptyMessageWithExtensionsLiteOrBuilder extends 
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestEmptyMessageWithExtensionsLite)
-       com.google.protobuf.GeneratedMessageLite.
-            ExtendableMessageOrBuilder<
-                TestEmptyMessageWithExtensionsLite, TestEmptyMessageWithExtensionsLite.Builder> {
-  }
-  /**
-   * <pre>
-   * Like above, but declare all field numbers as potential extensions.  No
-   * actual extensions should ever be defined for this type.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestEmptyMessageWithExtensionsLite}
-   */
-  public  static final class TestEmptyMessageWithExtensionsLite extends
-      com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
-        TestEmptyMessageWithExtensionsLite, TestEmptyMessageWithExtensionsLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestEmptyMessageWithExtensionsLite)
-      TestEmptyMessageWithExtensionsLiteOrBuilder {
-    private TestEmptyMessageWithExtensionsLite() {
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Like above, but declare all field numbers as potential extensions.  No
-     * actual extensions should ever be defined for this type.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestEmptyMessageWithExtensionsLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
-          com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestEmptyMessageWithExtensionsLite)
-        com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLiteOrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestEmptyMessageWithExtensionsLite)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestEmptyMessageWithExtensionsLite)
-    private static final com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite DEFAULT_INSTANCE;
-    static {
-      TestEmptyMessageWithExtensionsLite defaultInstance = new TestEmptyMessageWithExtensionsLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestEmptyMessageWithExtensionsLite.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.TestEmptyMessageWithExtensionsLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestEmptyMessageWithExtensionsLite> PARSER;
-
-    public static com.google.protobuf.Parser<TestEmptyMessageWithExtensionsLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface V1MessageLiteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.V1MessageLite)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>required int32 int_field = 1;</code>
-     * @return Whether the intField field is set.
-     */
-    boolean hasIntField();
-    /**
-     * <code>required int32 int_field = 1;</code>
-     * @return The intField.
-     */
-    int getIntField();
-
-    /**
-     * <code>optional .protobuf_unittest.V1EnumLite enum_field = 2 [default = V1_FIRST];</code>
-     * @return Whether the enumField field is set.
-     */
-    boolean hasEnumField();
-    /**
-     * <code>optional .protobuf_unittest.V1EnumLite enum_field = 2 [default = V1_FIRST];</code>
-     * @return The enumField.
-     */
-    com.google.protobuf.UnittestLite.V1EnumLite getEnumField();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.V1MessageLite}
-   */
-  public  static final class V1MessageLite extends
-      com.google.protobuf.GeneratedMessageLite<
-          V1MessageLite, V1MessageLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.V1MessageLite)
-      V1MessageLiteOrBuilder {
-    private V1MessageLite() {
-      enumField_ = 1;
-    }
-    private int bitField0_;
-    public static final int INT_FIELD_FIELD_NUMBER = 1;
-    private int intField_;
-    /**
-     * <code>required int32 int_field = 1;</code>
-     * @return Whether the intField field is set.
-     */
-    @java.lang.Override
-    public boolean hasIntField() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>required int32 int_field = 1;</code>
-     * @return The intField.
-     */
-    @java.lang.Override
-    public int getIntField() {
-      return intField_;
-    }
-    /**
-     * <code>required int32 int_field = 1;</code>
-     * @param value The intField to set.
-     */
-    private void setIntField(int value) {
-      bitField0_ |= 0x00000001;
-      intField_ = value;
-    }
-    /**
-     * <code>required int32 int_field = 1;</code>
-     */
-    private void clearIntField() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      intField_ = 0;
-    }
-
-    public static final int ENUM_FIELD_FIELD_NUMBER = 2;
-    private int enumField_;
-    /**
-     * <code>optional .protobuf_unittest.V1EnumLite enum_field = 2 [default = V1_FIRST];</code>
-     * @return Whether the enumField field is set.
-     */
-    @java.lang.Override
-    public boolean hasEnumField() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.V1EnumLite enum_field = 2 [default = V1_FIRST];</code>
-     * @return The enumField.
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.V1EnumLite getEnumField() {
-      com.google.protobuf.UnittestLite.V1EnumLite result = com.google.protobuf.UnittestLite.V1EnumLite.forNumber(enumField_);
-      return result == null ? com.google.protobuf.UnittestLite.V1EnumLite.V1_FIRST : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest.V1EnumLite enum_field = 2 [default = V1_FIRST];</code>
-     * @param value The enumField to set.
-     */
-    private void setEnumField(com.google.protobuf.UnittestLite.V1EnumLite value) {
-      enumField_ = value.getNumber();
-      bitField0_ |= 0x00000002;
-    }
-    /**
-     * <code>optional .protobuf_unittest.V1EnumLite enum_field = 2 [default = V1_FIRST];</code>
-     */
-    private void clearEnumField() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      enumField_ = 1;
-    }
-
-    public static com.google.protobuf.UnittestLite.V1MessageLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.V1MessageLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.V1MessageLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.V1MessageLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.V1MessageLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.V1MessageLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.V1MessageLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.V1MessageLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.V1MessageLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.V1MessageLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.V1MessageLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.V1MessageLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.V1MessageLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.V1MessageLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.UnittestLite.V1MessageLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.V1MessageLite)
-        com.google.protobuf.UnittestLite.V1MessageLiteOrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.V1MessageLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>required int32 int_field = 1;</code>
-       * @return Whether the intField field is set.
-       */
-      @java.lang.Override
-      public boolean hasIntField() {
-        return instance.hasIntField();
-      }
-      /**
-       * <code>required int32 int_field = 1;</code>
-       * @return The intField.
-       */
-      @java.lang.Override
-      public int getIntField() {
-        return instance.getIntField();
-      }
-      /**
-       * <code>required int32 int_field = 1;</code>
-       * @param value The intField to set.
-       * @return This builder for chaining.
-       */
-      public Builder setIntField(int value) {
-        copyOnWrite();
-        instance.setIntField(value);
-        return this;
-      }
-      /**
-       * <code>required int32 int_field = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearIntField() {
-        copyOnWrite();
-        instance.clearIntField();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.V1EnumLite enum_field = 2 [default = V1_FIRST];</code>
-       * @return Whether the enumField field is set.
-       */
-      @java.lang.Override
-      public boolean hasEnumField() {
-        return instance.hasEnumField();
-      }
-      /**
-       * <code>optional .protobuf_unittest.V1EnumLite enum_field = 2 [default = V1_FIRST];</code>
-       * @return The enumField.
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.V1EnumLite getEnumField() {
-        return instance.getEnumField();
-      }
-      /**
-       * <code>optional .protobuf_unittest.V1EnumLite enum_field = 2 [default = V1_FIRST];</code>
-       * @param value The enum numeric value on the wire for enumField to set.
-       * @return This builder for chaining.
-       */
-      public Builder setEnumField(com.google.protobuf.UnittestLite.V1EnumLite value) {
-        copyOnWrite();
-        instance.setEnumField(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.V1EnumLite enum_field = 2 [default = V1_FIRST];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearEnumField() {
-        copyOnWrite();
-        instance.clearEnumField();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.V1MessageLite)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.V1MessageLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "intField_",
-              "enumField_",
-              com.google.protobuf.UnittestLite.V1EnumLite.internalGetVerifier(),
-            };
-            java.lang.String info =
-                "\u0001\u0002\u0000\u0001\u0001\u0002\u0002\u0000\u0000\u0001\u0001\u1504\u0000\u0002" +
-                "\u100c\u0001";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.V1MessageLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.V1MessageLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.V1MessageLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.V1MessageLite)
-    private static final com.google.protobuf.UnittestLite.V1MessageLite DEFAULT_INSTANCE;
-    static {
-      V1MessageLite defaultInstance = new V1MessageLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        V1MessageLite.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.V1MessageLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<V1MessageLite> PARSER;
-
-    public static com.google.protobuf.Parser<V1MessageLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface V2MessageLiteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.V2MessageLite)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>required int32 int_field = 1;</code>
-     * @return Whether the intField field is set.
-     */
-    boolean hasIntField();
-    /**
-     * <code>required int32 int_field = 1;</code>
-     * @return The intField.
-     */
-    int getIntField();
-
-    /**
-     * <code>optional .protobuf_unittest.V2EnumLite enum_field = 2 [default = V2_FIRST];</code>
-     * @return Whether the enumField field is set.
-     */
-    boolean hasEnumField();
-    /**
-     * <code>optional .protobuf_unittest.V2EnumLite enum_field = 2 [default = V2_FIRST];</code>
-     * @return The enumField.
-     */
-    com.google.protobuf.UnittestLite.V2EnumLite getEnumField();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.V2MessageLite}
-   */
-  public  static final class V2MessageLite extends
-      com.google.protobuf.GeneratedMessageLite<
-          V2MessageLite, V2MessageLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.V2MessageLite)
-      V2MessageLiteOrBuilder {
-    private V2MessageLite() {
-      enumField_ = 1;
-    }
-    private int bitField0_;
-    public static final int INT_FIELD_FIELD_NUMBER = 1;
-    private int intField_;
-    /**
-     * <code>required int32 int_field = 1;</code>
-     * @return Whether the intField field is set.
-     */
-    @java.lang.Override
-    public boolean hasIntField() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>required int32 int_field = 1;</code>
-     * @return The intField.
-     */
-    @java.lang.Override
-    public int getIntField() {
-      return intField_;
-    }
-    /**
-     * <code>required int32 int_field = 1;</code>
-     * @param value The intField to set.
-     */
-    private void setIntField(int value) {
-      bitField0_ |= 0x00000001;
-      intField_ = value;
-    }
-    /**
-     * <code>required int32 int_field = 1;</code>
-     */
-    private void clearIntField() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      intField_ = 0;
-    }
-
-    public static final int ENUM_FIELD_FIELD_NUMBER = 2;
-    private int enumField_;
-    /**
-     * <code>optional .protobuf_unittest.V2EnumLite enum_field = 2 [default = V2_FIRST];</code>
-     * @return Whether the enumField field is set.
-     */
-    @java.lang.Override
-    public boolean hasEnumField() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.V2EnumLite enum_field = 2 [default = V2_FIRST];</code>
-     * @return The enumField.
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.V2EnumLite getEnumField() {
-      com.google.protobuf.UnittestLite.V2EnumLite result = com.google.protobuf.UnittestLite.V2EnumLite.forNumber(enumField_);
-      return result == null ? com.google.protobuf.UnittestLite.V2EnumLite.V2_FIRST : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest.V2EnumLite enum_field = 2 [default = V2_FIRST];</code>
-     * @param value The enumField to set.
-     */
-    private void setEnumField(com.google.protobuf.UnittestLite.V2EnumLite value) {
-      enumField_ = value.getNumber();
-      bitField0_ |= 0x00000002;
-    }
-    /**
-     * <code>optional .protobuf_unittest.V2EnumLite enum_field = 2 [default = V2_FIRST];</code>
-     */
-    private void clearEnumField() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      enumField_ = 1;
-    }
-
-    public static com.google.protobuf.UnittestLite.V2MessageLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.V2MessageLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.V2MessageLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.V2MessageLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.V2MessageLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.V2MessageLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.V2MessageLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.V2MessageLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.V2MessageLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.V2MessageLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.V2MessageLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.V2MessageLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.V2MessageLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.V2MessageLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.UnittestLite.V2MessageLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.V2MessageLite)
-        com.google.protobuf.UnittestLite.V2MessageLiteOrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.V2MessageLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>required int32 int_field = 1;</code>
-       * @return Whether the intField field is set.
-       */
-      @java.lang.Override
-      public boolean hasIntField() {
-        return instance.hasIntField();
-      }
-      /**
-       * <code>required int32 int_field = 1;</code>
-       * @return The intField.
-       */
-      @java.lang.Override
-      public int getIntField() {
-        return instance.getIntField();
-      }
-      /**
-       * <code>required int32 int_field = 1;</code>
-       * @param value The intField to set.
-       * @return This builder for chaining.
-       */
-      public Builder setIntField(int value) {
-        copyOnWrite();
-        instance.setIntField(value);
-        return this;
-      }
-      /**
-       * <code>required int32 int_field = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearIntField() {
-        copyOnWrite();
-        instance.clearIntField();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.V2EnumLite enum_field = 2 [default = V2_FIRST];</code>
-       * @return Whether the enumField field is set.
-       */
-      @java.lang.Override
-      public boolean hasEnumField() {
-        return instance.hasEnumField();
-      }
-      /**
-       * <code>optional .protobuf_unittest.V2EnumLite enum_field = 2 [default = V2_FIRST];</code>
-       * @return The enumField.
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.V2EnumLite getEnumField() {
-        return instance.getEnumField();
-      }
-      /**
-       * <code>optional .protobuf_unittest.V2EnumLite enum_field = 2 [default = V2_FIRST];</code>
-       * @param value The enum numeric value on the wire for enumField to set.
-       * @return This builder for chaining.
-       */
-      public Builder setEnumField(com.google.protobuf.UnittestLite.V2EnumLite value) {
-        copyOnWrite();
-        instance.setEnumField(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.V2EnumLite enum_field = 2 [default = V2_FIRST];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearEnumField() {
-        copyOnWrite();
-        instance.clearEnumField();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.V2MessageLite)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.V2MessageLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "intField_",
-              "enumField_",
-              com.google.protobuf.UnittestLite.V2EnumLite.internalGetVerifier(),
-            };
-            java.lang.String info =
-                "\u0001\u0002\u0000\u0001\u0001\u0002\u0002\u0000\u0000\u0001\u0001\u1504\u0000\u0002" +
-                "\u100c\u0001";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.V2MessageLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.V2MessageLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.V2MessageLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.V2MessageLite)
-    private static final com.google.protobuf.UnittestLite.V2MessageLite DEFAULT_INSTANCE;
-    static {
-      V2MessageLite defaultInstance = new V2MessageLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        V2MessageLite.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.V2MessageLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<V2MessageLite> PARSER;
-
-    public static com.google.protobuf.Parser<V2MessageLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestHugeFieldNumbersLiteOrBuilder extends 
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestHugeFieldNumbersLite)
-       com.google.protobuf.GeneratedMessageLite.
-            ExtendableMessageOrBuilder<
-                TestHugeFieldNumbersLite, TestHugeFieldNumbersLite.Builder> {
-
-    /**
-     * <code>optional int32 optional_int32 = 536870000;</code>
-     * @return Whether the optionalInt32 field is set.
-     */
-    boolean hasOptionalInt32();
-    /**
-     * <code>optional int32 optional_int32 = 536870000;</code>
-     * @return The optionalInt32.
-     */
-    int getOptionalInt32();
-
-    /**
-     * <code>optional int32 fixed_32 = 536870001;</code>
-     * @return Whether the fixed32 field is set.
-     */
-    boolean hasFixed32();
-    /**
-     * <code>optional int32 fixed_32 = 536870001;</code>
-     * @return The fixed32.
-     */
-    int getFixed32();
-
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @return A list containing the repeatedInt32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedInt32List();
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @return The count of repeatedInt32.
-     */
-    int getRepeatedInt32Count();
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt32 at the given index.
-     */
-    int getRepeatedInt32(int index);
-
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @return A list containing the packedInt32.
-     */
-    java.util.List<java.lang.Integer> getPackedInt32List();
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @return The count of packedInt32.
-     */
-    int getPackedInt32Count();
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedInt32 at the given index.
-     */
-    int getPackedInt32(int index);
-
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite optional_enum = 536870004;</code>
-     * @return Whether the optionalEnum field is set.
-     */
-    boolean hasOptionalEnum();
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite optional_enum = 536870004;</code>
-     * @return The optionalEnum.
-     */
-    com.google.protobuf.UnittestLite.ForeignEnumLite getOptionalEnum();
-
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     * @return Whether the optionalString field is set.
-     */
-    boolean hasOptionalString();
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     * @return The optionalString.
-     */
-    java.lang.String getOptionalString();
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     * @return The bytes for optionalString.
-     */
-    com.google.protobuf.ByteString
-        getOptionalStringBytes();
-
-    /**
-     * <code>optional bytes optional_bytes = 536870006;</code>
-     * @return Whether the optionalBytes field is set.
-     */
-    boolean hasOptionalBytes();
-    /**
-     * <code>optional bytes optional_bytes = 536870006;</code>
-     * @return The optionalBytes.
-     */
-    com.google.protobuf.ByteString getOptionalBytes();
-
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_message = 536870007;</code>
-     * @return Whether the optionalMessage field is set.
-     */
-    boolean hasOptionalMessage();
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_message = 536870007;</code>
-     * @return The optionalMessage.
-     */
-    com.google.protobuf.UnittestLite.ForeignMessageLite getOptionalMessage();
-
-    /**
-     * <code>optional group OptionalGroup = 536870008 { ... }</code>
-     * @return Whether the optionalgroup field is set.
-     */
-    boolean hasOptionalGroup();
-    /**
-     * <code>optional group OptionalGroup = 536870008 { ... }</code>
-     * @return The optionalgroup.
-     */
-    com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup getOptionalGroup();
-
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    int getStringStringMapCount();
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    boolean containsStringStringMap(
-        java.lang.String key);
-    /**
-     * Use {@link #getStringStringMapMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.String, java.lang.String>
-    getStringStringMap();
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    java.util.Map<java.lang.String, java.lang.String>
-    getStringStringMapMap();
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-
-    java.lang.String getStringStringMapOrDefault(
-        java.lang.String key,
-        java.lang.String defaultValue);
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-
-    java.lang.String getStringStringMapOrThrow(
-        java.lang.String key);
-
-    /**
-     * <code>uint32 oneof_uint32 = 536870011;</code>
-     * @return Whether the oneofUint32 field is set.
-     */
-    boolean hasOneofUint32();
-    /**
-     * <code>uint32 oneof_uint32 = 536870011;</code>
-     * @return The oneofUint32.
-     */
-    int getOneofUint32();
-
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_test_all_types = 536870012;</code>
-     * @return Whether the oneofTestAllTypes field is set.
-     */
-    boolean hasOneofTestAllTypes();
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_test_all_types = 536870012;</code>
-     * @return The oneofTestAllTypes.
-     */
-    com.google.protobuf.UnittestLite.TestAllTypesLite getOneofTestAllTypes();
-
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     * @return Whether the oneofString field is set.
-     */
-    boolean hasOneofString();
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     * @return The oneofString.
-     */
-    java.lang.String getOneofString();
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     * @return The bytes for oneofString.
-     */
-    com.google.protobuf.ByteString
-        getOneofStringBytes();
-
-    /**
-     * <code>bytes oneof_bytes = 536870014;</code>
-     * @return Whether the oneofBytes field is set.
-     */
-    boolean hasOneofBytes();
-    /**
-     * <code>bytes oneof_bytes = 536870014;</code>
-     * @return The oneofBytes.
-     */
-    com.google.protobuf.ByteString getOneofBytes();
-
-    public com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OneofFieldCase getOneofFieldCase();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestHugeFieldNumbersLite}
-   */
-  public  static final class TestHugeFieldNumbersLite extends
-      com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
-        TestHugeFieldNumbersLite, TestHugeFieldNumbersLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestHugeFieldNumbersLite)
-      TestHugeFieldNumbersLiteOrBuilder {
-    private TestHugeFieldNumbersLite() {
-      repeatedInt32_ = emptyIntList();
-      packedInt32_ = emptyIntList();
-      optionalEnum_ = 4;
-      optionalString_ = "";
-      optionalBytes_ = com.google.protobuf.ByteString.EMPTY;
-    }
-    public interface OptionalGroupOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestHugeFieldNumbersLite.OptionalGroup)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int32 group_a = 536870009;</code>
-       * @return Whether the groupA field is set.
-       */
-      boolean hasGroupA();
-      /**
-       * <code>optional int32 group_a = 536870009;</code>
-       * @return The groupA.
-       */
-      int getGroupA();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestHugeFieldNumbersLite.OptionalGroup}
-     */
-    public  static final class OptionalGroup extends
-        com.google.protobuf.GeneratedMessageLite<
-            OptionalGroup, OptionalGroup.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestHugeFieldNumbersLite.OptionalGroup)
-        OptionalGroupOrBuilder {
-      private OptionalGroup() {
-      }
-      private int bitField0_;
-      public static final int GROUP_A_FIELD_NUMBER = 536870009;
-      private int groupA_;
-      /**
-       * <code>optional int32 group_a = 536870009;</code>
-       * @return Whether the groupA field is set.
-       */
-      @java.lang.Override
-      public boolean hasGroupA() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int32 group_a = 536870009;</code>
-       * @return The groupA.
-       */
-      @java.lang.Override
-      public int getGroupA() {
-        return groupA_;
-      }
-      /**
-       * <code>optional int32 group_a = 536870009;</code>
-       * @param value The groupA to set.
-       */
-      private void setGroupA(int value) {
-        bitField0_ |= 0x00000001;
-        groupA_ = value;
-      }
-      /**
-       * <code>optional int32 group_a = 536870009;</code>
-       */
-      private void clearGroupA() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        groupA_ = 0;
-      }
-
-      public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestHugeFieldNumbersLite.OptionalGroup}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestHugeFieldNumbersLite.OptionalGroup)
-          com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroupOrBuilder {
-        // Construct using com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int32 group_a = 536870009;</code>
-         * @return Whether the groupA field is set.
-         */
-        @java.lang.Override
-        public boolean hasGroupA() {
-          return instance.hasGroupA();
-        }
-        /**
-         * <code>optional int32 group_a = 536870009;</code>
-         * @return The groupA.
-         */
-        @java.lang.Override
-        public int getGroupA() {
-          return instance.getGroupA();
-        }
-        /**
-         * <code>optional int32 group_a = 536870009;</code>
-         * @param value The groupA to set.
-         * @return This builder for chaining.
-         */
-        public Builder setGroupA(int value) {
-          copyOnWrite();
-          instance.setGroupA(value);
-          return this;
-        }
-        /**
-         * <code>optional int32 group_a = 536870009;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearGroupA() {
-          copyOnWrite();
-          instance.clearGroupA();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestHugeFieldNumbersLite.OptionalGroup)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "groupA_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\ufc79\uffff\u0007\ufc79\uffff\u0007\u0001\u0000\u0000\u0000" +
-                  "\ufc79\uffff\u0007\u1004\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup> parser = PARSER;
-            if (parser == null) {
-              synchronized (com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestHugeFieldNumbersLite.OptionalGroup)
-      private static final com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup DEFAULT_INSTANCE;
-      static {
-        OptionalGroup defaultInstance = new OptionalGroup();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          OptionalGroup.class, defaultInstance);
-      }
-
-      public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<OptionalGroup> PARSER;
-
-      public static com.google.protobuf.Parser<OptionalGroup> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int bitField0_;
-    private int oneofFieldCase_ = 0;
-    private java.lang.Object oneofField_;
-    public enum OneofFieldCase {
-      ONEOF_UINT32(536870011),
-      ONEOF_TEST_ALL_TYPES(536870012),
-      ONEOF_STRING(536870013),
-      ONEOF_BYTES(536870014),
-      ONEOFFIELD_NOT_SET(0);
-      private final int value;
-      private OneofFieldCase(int value) {
-        this.value = value;
-      }
-      /**
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static OneofFieldCase valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static OneofFieldCase forNumber(int value) {
-        switch (value) {
-          case 536870011: return ONEOF_UINT32;
-          case 536870012: return ONEOF_TEST_ALL_TYPES;
-          case 536870013: return ONEOF_STRING;
-          case 536870014: return ONEOF_BYTES;
-          case 0: return ONEOFFIELD_NOT_SET;
-          default: return null;
-        }
-      }
-      public int getNumber() {
-        return this.value;
-      }
-    };
-
-    @java.lang.Override
-    public OneofFieldCase
-    getOneofFieldCase() {
-      return OneofFieldCase.forNumber(
-          oneofFieldCase_);
-    }
-
-    private void clearOneofField() {
-      oneofFieldCase_ = 0;
-      oneofField_ = null;
-    }
-
-    public static final int OPTIONAL_INT32_FIELD_NUMBER = 536870000;
-    private int optionalInt32_;
-    /**
-     * <code>optional int32 optional_int32 = 536870000;</code>
-     * @return Whether the optionalInt32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalInt32() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 optional_int32 = 536870000;</code>
-     * @return The optionalInt32.
-     */
-    @java.lang.Override
-    public int getOptionalInt32() {
-      return optionalInt32_;
-    }
-    /**
-     * <code>optional int32 optional_int32 = 536870000;</code>
-     * @param value The optionalInt32 to set.
-     */
-    private void setOptionalInt32(int value) {
-      bitField0_ |= 0x00000001;
-      optionalInt32_ = value;
-    }
-    /**
-     * <code>optional int32 optional_int32 = 536870000;</code>
-     */
-    private void clearOptionalInt32() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      optionalInt32_ = 0;
-    }
-
-    public static final int FIXED_32_FIELD_NUMBER = 536870001;
-    private int fixed32_;
-    /**
-     * <code>optional int32 fixed_32 = 536870001;</code>
-     * @return Whether the fixed32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasFixed32() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional int32 fixed_32 = 536870001;</code>
-     * @return The fixed32.
-     */
-    @java.lang.Override
-    public int getFixed32() {
-      return fixed32_;
-    }
-    /**
-     * <code>optional int32 fixed_32 = 536870001;</code>
-     * @param value The fixed32 to set.
-     */
-    private void setFixed32(int value) {
-      bitField0_ |= 0x00000002;
-      fixed32_ = value;
-    }
-    /**
-     * <code>optional int32 fixed_32 = 536870001;</code>
-     */
-    private void clearFixed32() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      fixed32_ = 0;
-    }
-
-    public static final int REPEATED_INT32_FIELD_NUMBER = 536870002;
-    private com.google.protobuf.Internal.IntList repeatedInt32_;
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @return A list containing the repeatedInt32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedInt32List() {
-      return repeatedInt32_;
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @return The count of repeatedInt32.
-     */
-    @java.lang.Override
-    public int getRepeatedInt32Count() {
-      return repeatedInt32_.size();
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedInt32(int index) {
-      return repeatedInt32_.getInt(index);
-    }
-    private void ensureRepeatedInt32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedInt32_;
-      if (!tmp.isModifiable()) {
-        repeatedInt32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt32 to set.
-     */
-    private void setRepeatedInt32(
-        int index, int value) {
-      ensureRepeatedInt32IsMutable();
-      repeatedInt32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @param value The repeatedInt32 to add.
-     */
-    private void addRepeatedInt32(int value) {
-      ensureRepeatedInt32IsMutable();
-      repeatedInt32_.addInt(value);
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @param values The repeatedInt32 to add.
-     */
-    private void addAllRepeatedInt32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedInt32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedInt32_);
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     */
-    private void clearRepeatedInt32() {
-      repeatedInt32_ = emptyIntList();
-    }
-
-    public static final int PACKED_INT32_FIELD_NUMBER = 536870003;
-    private com.google.protobuf.Internal.IntList packedInt32_;
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @return A list containing the packedInt32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getPackedInt32List() {
-      return packedInt32_;
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @return The count of packedInt32.
-     */
-    @java.lang.Override
-    public int getPackedInt32Count() {
-      return packedInt32_.size();
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedInt32 at the given index.
-     */
-    @java.lang.Override
-    public int getPackedInt32(int index) {
-      return packedInt32_.getInt(index);
-    }
-    private int packedInt32MemoizedSerializedSize = -1;
-    private void ensurePackedInt32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedInt32_;
-      if (!tmp.isModifiable()) {
-        packedInt32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedInt32 to set.
-     */
-    private void setPackedInt32(
-        int index, int value) {
-      ensurePackedInt32IsMutable();
-      packedInt32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @param value The packedInt32 to add.
-     */
-    private void addPackedInt32(int value) {
-      ensurePackedInt32IsMutable();
-      packedInt32_.addInt(value);
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @param values The packedInt32 to add.
-     */
-    private void addAllPackedInt32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensurePackedInt32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedInt32_);
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     */
-    private void clearPackedInt32() {
-      packedInt32_ = emptyIntList();
-    }
-
-    public static final int OPTIONAL_ENUM_FIELD_NUMBER = 536870004;
-    private int optionalEnum_;
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite optional_enum = 536870004;</code>
-     * @return Whether the optionalEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalEnum() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite optional_enum = 536870004;</code>
-     * @return The optionalEnum.
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.ForeignEnumLite getOptionalEnum() {
-      com.google.protobuf.UnittestLite.ForeignEnumLite result = com.google.protobuf.UnittestLite.ForeignEnumLite.forNumber(optionalEnum_);
-      return result == null ? com.google.protobuf.UnittestLite.ForeignEnumLite.FOREIGN_LITE_FOO : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite optional_enum = 536870004;</code>
-     * @param value The optionalEnum to set.
-     */
-    private void setOptionalEnum(com.google.protobuf.UnittestLite.ForeignEnumLite value) {
-      optionalEnum_ = value.getNumber();
-      bitField0_ |= 0x00000004;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnumLite optional_enum = 536870004;</code>
-     */
-    private void clearOptionalEnum() {
-      bitField0_ = (bitField0_ & ~0x00000004);
-      optionalEnum_ = 4;
-    }
-
-    public static final int OPTIONAL_STRING_FIELD_NUMBER = 536870005;
-    private java.lang.String optionalString_;
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     * @return Whether the optionalString field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalString() {
-      return ((bitField0_ & 0x00000008) != 0);
-    }
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     * @return The optionalString.
-     */
-    @java.lang.Override
-    public java.lang.String getOptionalString() {
-      return optionalString_;
-    }
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     * @return The bytes for optionalString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOptionalStringBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(optionalString_);
-    }
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     * @param value The optionalString to set.
-     */
-    private void setOptionalString(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00000008;
-      optionalString_ = value;
-    }
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     */
-    private void clearOptionalString() {
-      bitField0_ = (bitField0_ & ~0x00000008);
-      optionalString_ = getDefaultInstance().getOptionalString();
-    }
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     * @param value The bytes for optionalString to set.
-     */
-    private void setOptionalStringBytes(
-        com.google.protobuf.ByteString value) {
-      optionalString_ = value.toStringUtf8();
-      bitField0_ |= 0x00000008;
-    }
-
-    public static final int OPTIONAL_BYTES_FIELD_NUMBER = 536870006;
-    private com.google.protobuf.ByteString optionalBytes_;
-    /**
-     * <code>optional bytes optional_bytes = 536870006;</code>
-     * @return Whether the optionalBytes field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalBytes() {
-      return ((bitField0_ & 0x00000010) != 0);
-    }
-    /**
-     * <code>optional bytes optional_bytes = 536870006;</code>
-     * @return The optionalBytes.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getOptionalBytes() {
-      return optionalBytes_;
-    }
-    /**
-     * <code>optional bytes optional_bytes = 536870006;</code>
-     * @param value The optionalBytes to set.
-     */
-    private void setOptionalBytes(com.google.protobuf.ByteString value) {
-      value.getClass();
-  bitField0_ |= 0x00000010;
-      optionalBytes_ = value;
-    }
-    /**
-     * <code>optional bytes optional_bytes = 536870006;</code>
-     */
-    private void clearOptionalBytes() {
-      bitField0_ = (bitField0_ & ~0x00000010);
-      optionalBytes_ = getDefaultInstance().getOptionalBytes();
-    }
-
-    public static final int OPTIONAL_MESSAGE_FIELD_NUMBER = 536870007;
-    private com.google.protobuf.UnittestLite.ForeignMessageLite optionalMessage_;
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_message = 536870007;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalMessage() {
-      return ((bitField0_ & 0x00000020) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_message = 536870007;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.ForeignMessageLite getOptionalMessage() {
-      return optionalMessage_ == null ? com.google.protobuf.UnittestLite.ForeignMessageLite.getDefaultInstance() : optionalMessage_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_message = 536870007;</code>
-     */
-    private void setOptionalMessage(com.google.protobuf.UnittestLite.ForeignMessageLite value) {
-      value.getClass();
-  optionalMessage_ = value;
-      bitField0_ |= 0x00000020;
-      }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_message = 536870007;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalMessage(com.google.protobuf.UnittestLite.ForeignMessageLite value) {
-      value.getClass();
-  if (optionalMessage_ != null &&
-          optionalMessage_ != com.google.protobuf.UnittestLite.ForeignMessageLite.getDefaultInstance()) {
-        optionalMessage_ =
-          com.google.protobuf.UnittestLite.ForeignMessageLite.newBuilder(optionalMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalMessage_ = value;
-      }
-      bitField0_ |= 0x00000020;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessageLite optional_message = 536870007;</code>
-     */
-    private void clearOptionalMessage() {  optionalMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x00000020);
-    }
-
-    public static final int OPTIONALGROUP_FIELD_NUMBER = 536870008;
-    private com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup optionalGroup_;
-    /**
-     * <code>optional group OptionalGroup = 536870008 { ... }</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalGroup() {
-      return ((bitField0_ & 0x00000040) != 0);
-    }
-    /**
-     * <code>optional group OptionalGroup = 536870008 { ... }</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup getOptionalGroup() {
-      return optionalGroup_ == null ? com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup.getDefaultInstance() : optionalGroup_;
-    }
-    /**
-     * <code>optional group OptionalGroup = 536870008 { ... }</code>
-     */
-    private void setOptionalGroup(com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup value) {
-      value.getClass();
-  optionalGroup_ = value;
-      bitField0_ |= 0x00000040;
-      }
-    /**
-     * <code>optional group OptionalGroup = 536870008 { ... }</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalGroup(com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup value) {
-      value.getClass();
-  if (optionalGroup_ != null &&
-          optionalGroup_ != com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup.getDefaultInstance()) {
-        optionalGroup_ =
-          com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup.newBuilder(optionalGroup_).mergeFrom(value).buildPartial();
-      } else {
-        optionalGroup_ = value;
-      }
-      bitField0_ |= 0x00000040;
-    }
-    /**
-     * <code>optional group OptionalGroup = 536870008 { ... }</code>
-     */
-    private void clearOptionalGroup() {  optionalGroup_ = null;
-      bitField0_ = (bitField0_ & ~0x00000040);
-    }
-
-    public static final int STRING_STRING_MAP_FIELD_NUMBER = 536870010;
-    private static final class StringStringMapDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.String, java.lang.String> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.String, java.lang.String>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.STRING,
-                  "",
-                  com.google.protobuf.WireFormat.FieldType.STRING,
-                  "");
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.String, java.lang.String> stringStringMap_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.String, java.lang.String>
-    internalGetStringStringMap() {
-      return stringStringMap_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.String, java.lang.String>
-    internalGetMutableStringStringMap() {
-      if (!stringStringMap_.isMutable()) {
-        stringStringMap_ = stringStringMap_.mutableCopy();
-      }
-      return stringStringMap_;
-    }
-    @java.lang.Override
-
-    public int getStringStringMapCount() {
-      return internalGetStringStringMap().size();
-    }
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsStringStringMap(
-        java.lang.String key) {
-      key.getClass();
-      return internalGetStringStringMap().containsKey(key);
-    }
-    /**
-     * Use {@link #getStringStringMapMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.String, java.lang.String> getStringStringMap() {
-      return getStringStringMapMap();
-    }
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.String, java.lang.String> getStringStringMapMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetStringStringMap());
-    }
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    @java.lang.Override
-
-    public java.lang.String getStringStringMapOrDefault(
-        java.lang.String key,
-        java.lang.String defaultValue) {
-      key.getClass();
-      java.util.Map<java.lang.String, java.lang.String> map =
-          internalGetStringStringMap();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    @java.lang.Override
-
-    public java.lang.String getStringStringMapOrThrow(
-        java.lang.String key) {
-      key.getClass();
-      java.util.Map<java.lang.String, java.lang.String> map =
-          internalGetStringStringMap();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    private java.util.Map<java.lang.String, java.lang.String>
-    getMutableStringStringMapMap() {
-      return internalGetMutableStringStringMap();
-    }
-
-    public static final int ONEOF_UINT32_FIELD_NUMBER = 536870011;
-    /**
-     * <code>uint32 oneof_uint32 = 536870011;</code>
-     * @return Whether the oneofUint32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofUint32() {
-      return oneofFieldCase_ == 536870011;
-    }
-    /**
-     * <code>uint32 oneof_uint32 = 536870011;</code>
-     * @return The oneofUint32.
-     */
-    @java.lang.Override
-    public int getOneofUint32() {
-      if (oneofFieldCase_ == 536870011) {
-        return (java.lang.Integer) oneofField_;
-      }
-      return 0;
-    }
-    /**
-     * <code>uint32 oneof_uint32 = 536870011;</code>
-     * @param value The oneofUint32 to set.
-     */
-    private void setOneofUint32(int value) {
-      oneofFieldCase_ = 536870011;
-      oneofField_ = value;
-    }
-    /**
-     * <code>uint32 oneof_uint32 = 536870011;</code>
-     */
-    private void clearOneofUint32() {
-      if (oneofFieldCase_ == 536870011) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static final int ONEOF_TEST_ALL_TYPES_FIELD_NUMBER = 536870012;
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_test_all_types = 536870012;</code>
-     */
-    @java.lang.Override
-    public boolean hasOneofTestAllTypes() {
-      return oneofFieldCase_ == 536870012;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_test_all_types = 536870012;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestAllTypesLite getOneofTestAllTypes() {
-      if (oneofFieldCase_ == 536870012) {
-         return (com.google.protobuf.UnittestLite.TestAllTypesLite) oneofField_;
-      }
-      return com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance();
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_test_all_types = 536870012;</code>
-     */
-    private void setOneofTestAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-      value.getClass();
-  oneofField_ = value;
-      oneofFieldCase_ = 536870012;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_test_all_types = 536870012;</code>
-     */
-    private void mergeOneofTestAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-      value.getClass();
-  if (oneofFieldCase_ == 536870012 &&
-          oneofField_ != com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance()) {
-        oneofField_ = com.google.protobuf.UnittestLite.TestAllTypesLite.newBuilder((com.google.protobuf.UnittestLite.TestAllTypesLite) oneofField_)
-            .mergeFrom(value).buildPartial();
-      } else {
-        oneofField_ = value;
-      }
-      oneofFieldCase_ = 536870012;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_test_all_types = 536870012;</code>
-     */
-    private void clearOneofTestAllTypes() {
-      if (oneofFieldCase_ == 536870012) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static final int ONEOF_STRING_FIELD_NUMBER = 536870013;
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     * @return Whether the oneofString field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofString() {
-      return oneofFieldCase_ == 536870013;
-    }
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     * @return The oneofString.
-     */
-    @java.lang.Override
-    public java.lang.String getOneofString() {
-      java.lang.String ref = "";
-      if (oneofFieldCase_ == 536870013) {
-        ref = (java.lang.String) oneofField_;
-      }
-      return ref;
-    }
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     * @return The bytes for oneofString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOneofStringBytes() {
-      java.lang.String ref = "";
-      if (oneofFieldCase_ == 536870013) {
-        ref = (java.lang.String) oneofField_;
-      }
-      return com.google.protobuf.ByteString.copyFromUtf8(ref);
-    }
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     * @param value The oneofString to set.
-     */
-    private void setOneofString(
-        java.lang.String value) {
-      value.getClass();
-  oneofFieldCase_ = 536870013;
-      oneofField_ = value;
-    }
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     */
-    private void clearOneofString() {
-      if (oneofFieldCase_ == 536870013) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     * @param value The bytes for oneofString to set.
-     */
-    private void setOneofStringBytes(
-        com.google.protobuf.ByteString value) {
-      oneofField_ = value.toStringUtf8();
-      oneofFieldCase_ = 536870013;
-    }
-
-    public static final int ONEOF_BYTES_FIELD_NUMBER = 536870014;
-    /**
-     * <code>bytes oneof_bytes = 536870014;</code>
-     * @return Whether the oneofBytes field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofBytes() {
-      return oneofFieldCase_ == 536870014;
-    }
-    /**
-     * <code>bytes oneof_bytes = 536870014;</code>
-     * @return The oneofBytes.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getOneofBytes() {
-      if (oneofFieldCase_ == 536870014) {
-        return (com.google.protobuf.ByteString) oneofField_;
-      }
-      return com.google.protobuf.ByteString.EMPTY;
-    }
-    /**
-     * <code>bytes oneof_bytes = 536870014;</code>
-     * @param value The oneofBytes to set.
-     */
-    private void setOneofBytes(com.google.protobuf.ByteString value) {
-      value.getClass();
-  oneofFieldCase_ = 536870014;
-      oneofField_ = value;
-    }
-    /**
-     * <code>bytes oneof_bytes = 536870014;</code>
-     */
-    private void clearOneofBytes() {
-      if (oneofFieldCase_ == 536870014) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestHugeFieldNumbersLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
-          com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestHugeFieldNumbersLite)
-        com.google.protobuf.UnittestLite.TestHugeFieldNumbersLiteOrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-      @java.lang.Override
-      public OneofFieldCase
-          getOneofFieldCase() {
-        return instance.getOneofFieldCase();
-      }
-
-      public Builder clearOneofField() {
-        copyOnWrite();
-        instance.clearOneofField();
-        return this;
-      }
-
-
-      /**
-       * <code>optional int32 optional_int32 = 536870000;</code>
-       * @return Whether the optionalInt32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalInt32() {
-        return instance.hasOptionalInt32();
-      }
-      /**
-       * <code>optional int32 optional_int32 = 536870000;</code>
-       * @return The optionalInt32.
-       */
-      @java.lang.Override
-      public int getOptionalInt32() {
-        return instance.getOptionalInt32();
-      }
-      /**
-       * <code>optional int32 optional_int32 = 536870000;</code>
-       * @param value The optionalInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalInt32(int value) {
-        copyOnWrite();
-        instance.setOptionalInt32(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 optional_int32 = 536870000;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalInt32() {
-        copyOnWrite();
-        instance.clearOptionalInt32();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 fixed_32 = 536870001;</code>
-       * @return Whether the fixed32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasFixed32() {
-        return instance.hasFixed32();
-      }
-      /**
-       * <code>optional int32 fixed_32 = 536870001;</code>
-       * @return The fixed32.
-       */
-      @java.lang.Override
-      public int getFixed32() {
-        return instance.getFixed32();
-      }
-      /**
-       * <code>optional int32 fixed_32 = 536870001;</code>
-       * @param value The fixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFixed32(int value) {
-        copyOnWrite();
-        instance.setFixed32(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 fixed_32 = 536870001;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFixed32() {
-        copyOnWrite();
-        instance.clearFixed32();
-        return this;
-      }
-
-      /**
-       * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-       * @return A list containing the repeatedInt32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedInt32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedInt32List());
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-       * @return The count of repeatedInt32.
-       */
-      @java.lang.Override
-      public int getRepeatedInt32Count() {
-        return instance.getRepeatedInt32Count();
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedInt32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedInt32(int index) {
-        return instance.getRepeatedInt32(index);
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-       * @param value The repeatedInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedInt32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedInt32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-       * @param value The repeatedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedInt32(int value) {
-        copyOnWrite();
-        instance.addRepeatedInt32(value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-       * @param values The repeatedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedInt32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedInt32(values);
-        return this;
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedInt32() {
-        copyOnWrite();
-        instance.clearRepeatedInt32();
-        return this;
-      }
-
-      /**
-       * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-       * @return A list containing the packedInt32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getPackedInt32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedInt32List());
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-       * @return The count of packedInt32.
-       */
-      @java.lang.Override
-      public int getPackedInt32Count() {
-        return instance.getPackedInt32Count();
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedInt32 at the given index.
-       */
-      @java.lang.Override
-      public int getPackedInt32(int index) {
-        return instance.getPackedInt32(index);
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-       * @param value The packedInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedInt32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setPackedInt32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-       * @param value The packedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedInt32(int value) {
-        copyOnWrite();
-        instance.addPackedInt32(value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-       * @param values The packedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedInt32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllPackedInt32(values);
-        return this;
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedInt32() {
-        copyOnWrite();
-        instance.clearPackedInt32();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnumLite optional_enum = 536870004;</code>
-       * @return Whether the optionalEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalEnum() {
-        return instance.hasOptionalEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnumLite optional_enum = 536870004;</code>
-       * @return The optionalEnum.
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.ForeignEnumLite getOptionalEnum() {
-        return instance.getOptionalEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnumLite optional_enum = 536870004;</code>
-       * @param value The enum numeric value on the wire for optionalEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalEnum(com.google.protobuf.UnittestLite.ForeignEnumLite value) {
-        copyOnWrite();
-        instance.setOptionalEnum(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnumLite optional_enum = 536870004;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalEnum() {
-        copyOnWrite();
-        instance.clearOptionalEnum();
-        return this;
-      }
-
-      /**
-       * <code>optional string optional_string = 536870005;</code>
-       * @return Whether the optionalString field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalString() {
-        return instance.hasOptionalString();
-      }
-      /**
-       * <code>optional string optional_string = 536870005;</code>
-       * @return The optionalString.
-       */
-      @java.lang.Override
-      public java.lang.String getOptionalString() {
-        return instance.getOptionalString();
-      }
-      /**
-       * <code>optional string optional_string = 536870005;</code>
-       * @return The bytes for optionalString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getOptionalStringBytes() {
-        return instance.getOptionalStringBytes();
-      }
-      /**
-       * <code>optional string optional_string = 536870005;</code>
-       * @param value The optionalString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setOptionalString(value);
-        return this;
-      }
-      /**
-       * <code>optional string optional_string = 536870005;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalString() {
-        copyOnWrite();
-        instance.clearOptionalString();
-        return this;
-      }
-      /**
-       * <code>optional string optional_string = 536870005;</code>
-       * @param value The bytes for optionalString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOptionalStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional bytes optional_bytes = 536870006;</code>
-       * @return Whether the optionalBytes field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalBytes() {
-        return instance.hasOptionalBytes();
-      }
-      /**
-       * <code>optional bytes optional_bytes = 536870006;</code>
-       * @return The optionalBytes.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getOptionalBytes() {
-        return instance.getOptionalBytes();
-      }
-      /**
-       * <code>optional bytes optional_bytes = 536870006;</code>
-       * @param value The optionalBytes to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalBytes(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOptionalBytes(value);
-        return this;
-      }
-      /**
-       * <code>optional bytes optional_bytes = 536870006;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalBytes() {
-        copyOnWrite();
-        instance.clearOptionalBytes();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessageLite optional_message = 536870007;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalMessage() {
-        return instance.hasOptionalMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessageLite optional_message = 536870007;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.ForeignMessageLite getOptionalMessage() {
-        return instance.getOptionalMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessageLite optional_message = 536870007;</code>
-       */
-      public Builder setOptionalMessage(com.google.protobuf.UnittestLite.ForeignMessageLite value) {
-        copyOnWrite();
-        instance.setOptionalMessage(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessageLite optional_message = 536870007;</code>
-       */
-      public Builder setOptionalMessage(
-          com.google.protobuf.UnittestLite.ForeignMessageLite.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessageLite optional_message = 536870007;</code>
-       */
-      public Builder mergeOptionalMessage(com.google.protobuf.UnittestLite.ForeignMessageLite value) {
-        copyOnWrite();
-        instance.mergeOptionalMessage(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessageLite optional_message = 536870007;</code>
-       */
-      public Builder clearOptionalMessage() {  copyOnWrite();
-        instance.clearOptionalMessage();
-        return this;
-      }
-
-      /**
-       * <code>optional group OptionalGroup = 536870008 { ... }</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalGroup() {
-        return instance.hasOptionalGroup();
-      }
-      /**
-       * <code>optional group OptionalGroup = 536870008 { ... }</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup getOptionalGroup() {
-        return instance.getOptionalGroup();
-      }
-      /**
-       * <code>optional group OptionalGroup = 536870008 { ... }</code>
-       */
-      public Builder setOptionalGroup(com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup value) {
-        copyOnWrite();
-        instance.setOptionalGroup(value);
-        return this;
-        }
-      /**
-       * <code>optional group OptionalGroup = 536870008 { ... }</code>
-       */
-      public Builder setOptionalGroup(
-          com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalGroup(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional group OptionalGroup = 536870008 { ... }</code>
-       */
-      public Builder mergeOptionalGroup(com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.OptionalGroup value) {
-        copyOnWrite();
-        instance.mergeOptionalGroup(value);
-        return this;
-      }
-      /**
-       * <code>optional group OptionalGroup = 536870008 { ... }</code>
-       */
-      public Builder clearOptionalGroup() {  copyOnWrite();
-        instance.clearOptionalGroup();
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getStringStringMapCount() {
-        return instance.getStringStringMapMap().size();
-      }
-      /**
-       * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsStringStringMap(
-          java.lang.String key) {
-        key.getClass();
-        return instance.getStringStringMapMap().containsKey(key);
-      }
-
-      public Builder clearStringStringMap() {
-        copyOnWrite();
-        instance.getMutableStringStringMapMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-       */
-
-      public Builder removeStringStringMap(
-          java.lang.String key) {
-        key.getClass();
-        copyOnWrite();
-        instance.getMutableStringStringMapMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getStringStringMapMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.String, java.lang.String> getStringStringMap() {
-        return getStringStringMapMap();
-      }
-      /**
-       * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.String, java.lang.String> getStringStringMapMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getStringStringMapMap());
-      }
-      /**
-       * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-       */
-      @java.lang.Override
-
-      public java.lang.String getStringStringMapOrDefault(
-          java.lang.String key,
-          java.lang.String defaultValue) {
-        key.getClass();
-        java.util.Map<java.lang.String, java.lang.String> map =
-            instance.getStringStringMapMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-       */
-      @java.lang.Override
-
-      public java.lang.String getStringStringMapOrThrow(
-          java.lang.String key) {
-        key.getClass();
-        java.util.Map<java.lang.String, java.lang.String> map =
-            instance.getStringStringMapMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-       */
-      public Builder putStringStringMap(
-          java.lang.String key,
-          java.lang.String value) {
-        key.getClass();
-        value.getClass();
-        copyOnWrite();
-        instance.getMutableStringStringMapMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-       */
-      public Builder putAllStringStringMap(
-          java.util.Map<java.lang.String, java.lang.String> values) {
-        copyOnWrite();
-        instance.getMutableStringStringMapMap().putAll(values);
-        return this;
-      }
-
-      /**
-       * <code>uint32 oneof_uint32 = 536870011;</code>
-       * @return Whether the oneofUint32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofUint32() {
-        return instance.hasOneofUint32();
-      }
-      /**
-       * <code>uint32 oneof_uint32 = 536870011;</code>
-       * @return The oneofUint32.
-       */
-      @java.lang.Override
-      public int getOneofUint32() {
-        return instance.getOneofUint32();
-      }
-      /**
-       * <code>uint32 oneof_uint32 = 536870011;</code>
-       * @param value The oneofUint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofUint32(int value) {
-        copyOnWrite();
-        instance.setOneofUint32(value);
-        return this;
-      }
-      /**
-       * <code>uint32 oneof_uint32 = 536870011;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofUint32() {
-        copyOnWrite();
-        instance.clearOneofUint32();
-        return this;
-      }
-
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite oneof_test_all_types = 536870012;</code>
-       */
-      @java.lang.Override
-      public boolean hasOneofTestAllTypes() {
-        return instance.hasOneofTestAllTypes();
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite oneof_test_all_types = 536870012;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite getOneofTestAllTypes() {
-        return instance.getOneofTestAllTypes();
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite oneof_test_all_types = 536870012;</code>
-       */
-      public Builder setOneofTestAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        copyOnWrite();
-        instance.setOneofTestAllTypes(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite oneof_test_all_types = 536870012;</code>
-       */
-      public Builder setOneofTestAllTypes(
-          com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOneofTestAllTypes(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite oneof_test_all_types = 536870012;</code>
-       */
-      public Builder mergeOneofTestAllTypes(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        copyOnWrite();
-        instance.mergeOneofTestAllTypes(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite oneof_test_all_types = 536870012;</code>
-       */
-      public Builder clearOneofTestAllTypes() {
-        copyOnWrite();
-        instance.clearOneofTestAllTypes();
-        return this;
-      }
-
-      /**
-       * <code>string oneof_string = 536870013;</code>
-       * @return Whether the oneofString field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofString() {
-        return instance.hasOneofString();
-      }
-      /**
-       * <code>string oneof_string = 536870013;</code>
-       * @return The oneofString.
-       */
-      @java.lang.Override
-      public java.lang.String getOneofString() {
-        return instance.getOneofString();
-      }
-      /**
-       * <code>string oneof_string = 536870013;</code>
-       * @return The bytes for oneofString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getOneofStringBytes() {
-        return instance.getOneofStringBytes();
-      }
-      /**
-       * <code>string oneof_string = 536870013;</code>
-       * @param value The oneofString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setOneofString(value);
-        return this;
-      }
-      /**
-       * <code>string oneof_string = 536870013;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofString() {
-        copyOnWrite();
-        instance.clearOneofString();
-        return this;
-      }
-      /**
-       * <code>string oneof_string = 536870013;</code>
-       * @param value The bytes for oneofString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOneofStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>bytes oneof_bytes = 536870014;</code>
-       * @return Whether the oneofBytes field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofBytes() {
-        return instance.hasOneofBytes();
-      }
-      /**
-       * <code>bytes oneof_bytes = 536870014;</code>
-       * @return The oneofBytes.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getOneofBytes() {
-        return instance.getOneofBytes();
-      }
-      /**
-       * <code>bytes oneof_bytes = 536870014;</code>
-       * @param value The oneofBytes to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofBytes(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOneofBytes(value);
-        return this;
-      }
-      /**
-       * <code>bytes oneof_bytes = 536870014;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofBytes() {
-        copyOnWrite();
-        instance.clearOneofBytes();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestHugeFieldNumbersLite)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "oneofField_",
-              "oneofFieldCase_",
-              "bitField0_",
-              "optionalInt32_",
-              "fixed32_",
-              "repeatedInt32_",
-              "packedInt32_",
-              "optionalEnum_",
-              com.google.protobuf.UnittestLite.ForeignEnumLite.internalGetVerifier(),
-              "optionalString_",
-              "optionalBytes_",
-              "optionalMessage_",
-              "optionalGroup_",
-              "stringStringMap_",
-              StringStringMapDefaultEntryHolder.defaultEntry,
-              com.google.protobuf.UnittestLite.TestAllTypesLite.class,
-            };
-            java.lang.String info =
-                "\u0001\u000e\u0001\u0001\ufc70\uffff\u0007\ufc7e\uffff\u0007\u000e\u0001\u0002\u0000" +
-                "\ufc70\uffff\u0007\u1004\u0000\ufc71\uffff\u0007\u1004\u0001\ufc72\uffff\u0007\u0016" +
-                "\ufc73\uffff\u0007\'\ufc74\uffff\u0007\u100c\u0002\ufc75\uffff\u0007\u1008\u0003" +
-                "\ufc76\uffff\u0007\u100a\u0004\ufc77\uffff\u0007\u1009\u0005\ufc78\uffff\u0007\u1011" +
-                "\u0006\ufc7a\uffff\u00072\ufc7b\uffff\u0007\u103e\u0000\ufc7c\uffff\u0007\u103c\u0000" +
-                "\ufc7d\uffff\u0007\u103b\u0000\ufc7e\uffff\u0007\u103d\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestHugeFieldNumbersLite)
-    private static final com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite DEFAULT_INSTANCE;
-    static {
-      TestHugeFieldNumbersLite defaultInstance = new TestHugeFieldNumbersLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestHugeFieldNumbersLite.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestHugeFieldNumbersLite> PARSER;
-
-    public static com.google.protobuf.Parser<TestHugeFieldNumbersLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestOneofParsingLiteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestOneofParsingLite)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>int32 oneof_int32 = 1;</code>
-     * @return Whether the oneofInt32 field is set.
-     */
-    boolean hasOneofInt32();
-    /**
-     * <code>int32 oneof_int32 = 1;</code>
-     * @return The oneofInt32.
-     */
-    int getOneofInt32();
-
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_submessage = 2;</code>
-     * @return Whether the oneofSubmessage field is set.
-     */
-    boolean hasOneofSubmessage();
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_submessage = 2;</code>
-     * @return The oneofSubmessage.
-     */
-    com.google.protobuf.UnittestLite.TestAllTypesLite getOneofSubmessage();
-
-    /**
-     * <code>string oneof_string = 3;</code>
-     * @return Whether the oneofString field is set.
-     */
-    boolean hasOneofString();
-    /**
-     * <code>string oneof_string = 3;</code>
-     * @return The oneofString.
-     */
-    java.lang.String getOneofString();
-    /**
-     * <code>string oneof_string = 3;</code>
-     * @return The bytes for oneofString.
-     */
-    com.google.protobuf.ByteString
-        getOneofStringBytes();
-
-    /**
-     * <code>bytes oneof_bytes = 4 [default = "default bytes"];</code>
-     * @return Whether the oneofBytes field is set.
-     */
-    boolean hasOneofBytes();
-    /**
-     * <code>bytes oneof_bytes = 4 [default = "default bytes"];</code>
-     * @return The oneofBytes.
-     */
-    com.google.protobuf.ByteString getOneofBytes();
-
-    /**
-     * <code>string oneof_string_cord = 5 [default = "default Cord", ctype = CORD];</code>
-     * @return Whether the oneofStringCord field is set.
-     */
-    boolean hasOneofStringCord();
-    /**
-     * <code>string oneof_string_cord = 5 [default = "default Cord", ctype = CORD];</code>
-     * @return The oneofStringCord.
-     */
-    java.lang.String getOneofStringCord();
-    /**
-     * <code>string oneof_string_cord = 5 [default = "default Cord", ctype = CORD];</code>
-     * @return The bytes for oneofStringCord.
-     */
-    com.google.protobuf.ByteString
-        getOneofStringCordBytes();
-
-    /**
-     * <code>bytes oneof_bytes_cord = 6 [ctype = CORD];</code>
-     * @return Whether the oneofBytesCord field is set.
-     */
-    boolean hasOneofBytesCord();
-    /**
-     * <code>bytes oneof_bytes_cord = 6 [ctype = CORD];</code>
-     * @return The oneofBytesCord.
-     */
-    com.google.protobuf.ByteString getOneofBytesCord();
-
-    /**
-     * <code>string oneof_string_string_piece = 7 [ctype = STRING_PIECE];</code>
-     * @return Whether the oneofStringStringPiece field is set.
-     */
-    boolean hasOneofStringStringPiece();
-    /**
-     * <code>string oneof_string_string_piece = 7 [ctype = STRING_PIECE];</code>
-     * @return The oneofStringStringPiece.
-     */
-    java.lang.String getOneofStringStringPiece();
-    /**
-     * <code>string oneof_string_string_piece = 7 [ctype = STRING_PIECE];</code>
-     * @return The bytes for oneofStringStringPiece.
-     */
-    com.google.protobuf.ByteString
-        getOneofStringStringPieceBytes();
-
-    /**
-     * <code>bytes oneof_bytes_string_piece = 8 [default = "default StringPiece", ctype = STRING_PIECE];</code>
-     * @return Whether the oneofBytesStringPiece field is set.
-     */
-    boolean hasOneofBytesStringPiece();
-    /**
-     * <code>bytes oneof_bytes_string_piece = 8 [default = "default StringPiece", ctype = STRING_PIECE];</code>
-     * @return The oneofBytesStringPiece.
-     */
-    com.google.protobuf.ByteString getOneofBytesStringPiece();
-
-    /**
-     * <code>.protobuf_unittest.V2EnumLite oneof_enum = 9;</code>
-     * @return Whether the oneofEnum field is set.
-     */
-    boolean hasOneofEnum();
-    /**
-     * <code>.protobuf_unittest.V2EnumLite oneof_enum = 9;</code>
-     * @return The oneofEnum.
-     */
-    com.google.protobuf.UnittestLite.V2EnumLite getOneofEnum();
-
-    public com.google.protobuf.UnittestLite.TestOneofParsingLite.OneofFieldCase getOneofFieldCase();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestOneofParsingLite}
-   */
-  public  static final class TestOneofParsingLite extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestOneofParsingLite, TestOneofParsingLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestOneofParsingLite)
-      TestOneofParsingLiteOrBuilder {
-    private TestOneofParsingLite() {
-    }
-    private int bitField0_;
-    private int oneofFieldCase_ = 0;
-    private java.lang.Object oneofField_;
-    public enum OneofFieldCase {
-      ONEOF_INT32(1),
-      ONEOF_SUBMESSAGE(2),
-      ONEOF_STRING(3),
-      ONEOF_BYTES(4),
-      ONEOF_STRING_CORD(5),
-      ONEOF_BYTES_CORD(6),
-      ONEOF_STRING_STRING_PIECE(7),
-      ONEOF_BYTES_STRING_PIECE(8),
-      ONEOF_ENUM(9),
-      ONEOFFIELD_NOT_SET(0);
-      private final int value;
-      private OneofFieldCase(int value) {
-        this.value = value;
-      }
-      /**
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static OneofFieldCase valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static OneofFieldCase forNumber(int value) {
-        switch (value) {
-          case 1: return ONEOF_INT32;
-          case 2: return ONEOF_SUBMESSAGE;
-          case 3: return ONEOF_STRING;
-          case 4: return ONEOF_BYTES;
-          case 5: return ONEOF_STRING_CORD;
-          case 6: return ONEOF_BYTES_CORD;
-          case 7: return ONEOF_STRING_STRING_PIECE;
-          case 8: return ONEOF_BYTES_STRING_PIECE;
-          case 9: return ONEOF_ENUM;
-          case 0: return ONEOFFIELD_NOT_SET;
-          default: return null;
-        }
-      }
-      public int getNumber() {
-        return this.value;
-      }
-    };
-
-    @java.lang.Override
-    public OneofFieldCase
-    getOneofFieldCase() {
-      return OneofFieldCase.forNumber(
-          oneofFieldCase_);
-    }
-
-    private void clearOneofField() {
-      oneofFieldCase_ = 0;
-      oneofField_ = null;
-    }
-
-    public static final int ONEOF_INT32_FIELD_NUMBER = 1;
-    /**
-     * <code>int32 oneof_int32 = 1;</code>
-     * @return Whether the oneofInt32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofInt32() {
-      return oneofFieldCase_ == 1;
-    }
-    /**
-     * <code>int32 oneof_int32 = 1;</code>
-     * @return The oneofInt32.
-     */
-    @java.lang.Override
-    public int getOneofInt32() {
-      if (oneofFieldCase_ == 1) {
-        return (java.lang.Integer) oneofField_;
-      }
-      return 0;
-    }
-    /**
-     * <code>int32 oneof_int32 = 1;</code>
-     * @param value The oneofInt32 to set.
-     */
-    private void setOneofInt32(int value) {
-      oneofFieldCase_ = 1;
-      oneofField_ = value;
-    }
-    /**
-     * <code>int32 oneof_int32 = 1;</code>
-     */
-    private void clearOneofInt32() {
-      if (oneofFieldCase_ == 1) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static final int ONEOF_SUBMESSAGE_FIELD_NUMBER = 2;
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_submessage = 2;</code>
-     */
-    @java.lang.Override
-    public boolean hasOneofSubmessage() {
-      return oneofFieldCase_ == 2;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_submessage = 2;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.TestAllTypesLite getOneofSubmessage() {
-      if (oneofFieldCase_ == 2) {
-         return (com.google.protobuf.UnittestLite.TestAllTypesLite) oneofField_;
-      }
-      return com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance();
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_submessage = 2;</code>
-     */
-    private void setOneofSubmessage(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-      value.getClass();
-  oneofField_ = value;
-      oneofFieldCase_ = 2;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_submessage = 2;</code>
-     */
-    private void mergeOneofSubmessage(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-      value.getClass();
-  if (oneofFieldCase_ == 2 &&
-          oneofField_ != com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance()) {
-        oneofField_ = com.google.protobuf.UnittestLite.TestAllTypesLite.newBuilder((com.google.protobuf.UnittestLite.TestAllTypesLite) oneofField_)
-            .mergeFrom(value).buildPartial();
-      } else {
-        oneofField_ = value;
-      }
-      oneofFieldCase_ = 2;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypesLite oneof_submessage = 2;</code>
-     */
-    private void clearOneofSubmessage() {
-      if (oneofFieldCase_ == 2) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static final int ONEOF_STRING_FIELD_NUMBER = 3;
-    /**
-     * <code>string oneof_string = 3;</code>
-     * @return Whether the oneofString field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofString() {
-      return oneofFieldCase_ == 3;
-    }
-    /**
-     * <code>string oneof_string = 3;</code>
-     * @return The oneofString.
-     */
-    @java.lang.Override
-    public java.lang.String getOneofString() {
-      java.lang.String ref = "";
-      if (oneofFieldCase_ == 3) {
-        ref = (java.lang.String) oneofField_;
-      }
-      return ref;
-    }
-    /**
-     * <code>string oneof_string = 3;</code>
-     * @return The bytes for oneofString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOneofStringBytes() {
-      java.lang.String ref = "";
-      if (oneofFieldCase_ == 3) {
-        ref = (java.lang.String) oneofField_;
-      }
-      return com.google.protobuf.ByteString.copyFromUtf8(ref);
-    }
-    /**
-     * <code>string oneof_string = 3;</code>
-     * @param value The oneofString to set.
-     */
-    private void setOneofString(
-        java.lang.String value) {
-      value.getClass();
-  oneofFieldCase_ = 3;
-      oneofField_ = value;
-    }
-    /**
-     * <code>string oneof_string = 3;</code>
-     */
-    private void clearOneofString() {
-      if (oneofFieldCase_ == 3) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-    /**
-     * <code>string oneof_string = 3;</code>
-     * @param value The bytes for oneofString to set.
-     */
-    private void setOneofStringBytes(
-        com.google.protobuf.ByteString value) {
-      oneofField_ = value.toStringUtf8();
-      oneofFieldCase_ = 3;
-    }
-
-    public static final int ONEOF_BYTES_FIELD_NUMBER = 4;
-    /**
-     * <code>bytes oneof_bytes = 4 [default = "default bytes"];</code>
-     * @return Whether the oneofBytes field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofBytes() {
-      return oneofFieldCase_ == 4;
-    }
-    /**
-     * <code>bytes oneof_bytes = 4 [default = "default bytes"];</code>
-     * @return The oneofBytes.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getOneofBytes() {
-      if (oneofFieldCase_ == 4) {
-        return (com.google.protobuf.ByteString) oneofField_;
-      }
-      return com.google.protobuf.Internal.bytesDefaultValue("default bytes");
-    }
-    /**
-     * <code>bytes oneof_bytes = 4 [default = "default bytes"];</code>
-     * @param value The oneofBytes to set.
-     */
-    private void setOneofBytes(com.google.protobuf.ByteString value) {
-      value.getClass();
-  oneofFieldCase_ = 4;
-      oneofField_ = value;
-    }
-    /**
-     * <code>bytes oneof_bytes = 4 [default = "default bytes"];</code>
-     */
-    private void clearOneofBytes() {
-      if (oneofFieldCase_ == 4) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static final int ONEOF_STRING_CORD_FIELD_NUMBER = 5;
-    /**
-     * <code>string oneof_string_cord = 5 [default = "default Cord", ctype = CORD];</code>
-     * @return Whether the oneofStringCord field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofStringCord() {
-      return oneofFieldCase_ == 5;
-    }
-    /**
-     * <code>string oneof_string_cord = 5 [default = "default Cord", ctype = CORD];</code>
-     * @return The oneofStringCord.
-     */
-    @java.lang.Override
-    public java.lang.String getOneofStringCord() {
-      java.lang.String ref = "default Cord";
-      if (oneofFieldCase_ == 5) {
-        ref = (java.lang.String) oneofField_;
-      }
-      return ref;
-    }
-    /**
-     * <code>string oneof_string_cord = 5 [default = "default Cord", ctype = CORD];</code>
-     * @return The bytes for oneofStringCord.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOneofStringCordBytes() {
-      java.lang.String ref = "default Cord";
-      if (oneofFieldCase_ == 5) {
-        ref = (java.lang.String) oneofField_;
-      }
-      return com.google.protobuf.ByteString.copyFromUtf8(ref);
-    }
-    /**
-     * <code>string oneof_string_cord = 5 [default = "default Cord", ctype = CORD];</code>
-     * @param value The oneofStringCord to set.
-     */
-    private void setOneofStringCord(
-        java.lang.String value) {
-      value.getClass();
-  oneofFieldCase_ = 5;
-      oneofField_ = value;
-    }
-    /**
-     * <code>string oneof_string_cord = 5 [default = "default Cord", ctype = CORD];</code>
-     */
-    private void clearOneofStringCord() {
-      if (oneofFieldCase_ == 5) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-    /**
-     * <code>string oneof_string_cord = 5 [default = "default Cord", ctype = CORD];</code>
-     * @param value The bytes for oneofStringCord to set.
-     */
-    private void setOneofStringCordBytes(
-        com.google.protobuf.ByteString value) {
-      oneofField_ = value.toStringUtf8();
-      oneofFieldCase_ = 5;
-    }
-
-    public static final int ONEOF_BYTES_CORD_FIELD_NUMBER = 6;
-    /**
-     * <code>bytes oneof_bytes_cord = 6 [ctype = CORD];</code>
-     * @return Whether the oneofBytesCord field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofBytesCord() {
-      return oneofFieldCase_ == 6;
-    }
-    /**
-     * <code>bytes oneof_bytes_cord = 6 [ctype = CORD];</code>
-     * @return The oneofBytesCord.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getOneofBytesCord() {
-      if (oneofFieldCase_ == 6) {
-        return (com.google.protobuf.ByteString) oneofField_;
-      }
-      return com.google.protobuf.ByteString.EMPTY;
-    }
-    /**
-     * <code>bytes oneof_bytes_cord = 6 [ctype = CORD];</code>
-     * @param value The oneofBytesCord to set.
-     */
-    private void setOneofBytesCord(com.google.protobuf.ByteString value) {
-      value.getClass();
-  oneofFieldCase_ = 6;
-      oneofField_ = value;
-    }
-    /**
-     * <code>bytes oneof_bytes_cord = 6 [ctype = CORD];</code>
-     */
-    private void clearOneofBytesCord() {
-      if (oneofFieldCase_ == 6) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static final int ONEOF_STRING_STRING_PIECE_FIELD_NUMBER = 7;
-    /**
-     * <code>string oneof_string_string_piece = 7 [ctype = STRING_PIECE];</code>
-     * @return Whether the oneofStringStringPiece field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofStringStringPiece() {
-      return oneofFieldCase_ == 7;
-    }
-    /**
-     * <code>string oneof_string_string_piece = 7 [ctype = STRING_PIECE];</code>
-     * @return The oneofStringStringPiece.
-     */
-    @java.lang.Override
-    public java.lang.String getOneofStringStringPiece() {
-      java.lang.String ref = "";
-      if (oneofFieldCase_ == 7) {
-        ref = (java.lang.String) oneofField_;
-      }
-      return ref;
-    }
-    /**
-     * <code>string oneof_string_string_piece = 7 [ctype = STRING_PIECE];</code>
-     * @return The bytes for oneofStringStringPiece.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOneofStringStringPieceBytes() {
-      java.lang.String ref = "";
-      if (oneofFieldCase_ == 7) {
-        ref = (java.lang.String) oneofField_;
-      }
-      return com.google.protobuf.ByteString.copyFromUtf8(ref);
-    }
-    /**
-     * <code>string oneof_string_string_piece = 7 [ctype = STRING_PIECE];</code>
-     * @param value The oneofStringStringPiece to set.
-     */
-    private void setOneofStringStringPiece(
-        java.lang.String value) {
-      value.getClass();
-  oneofFieldCase_ = 7;
-      oneofField_ = value;
-    }
-    /**
-     * <code>string oneof_string_string_piece = 7 [ctype = STRING_PIECE];</code>
-     */
-    private void clearOneofStringStringPiece() {
-      if (oneofFieldCase_ == 7) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-    /**
-     * <code>string oneof_string_string_piece = 7 [ctype = STRING_PIECE];</code>
-     * @param value The bytes for oneofStringStringPiece to set.
-     */
-    private void setOneofStringStringPieceBytes(
-        com.google.protobuf.ByteString value) {
-      oneofField_ = value.toStringUtf8();
-      oneofFieldCase_ = 7;
-    }
-
-    public static final int ONEOF_BYTES_STRING_PIECE_FIELD_NUMBER = 8;
-    /**
-     * <code>bytes oneof_bytes_string_piece = 8 [default = "default StringPiece", ctype = STRING_PIECE];</code>
-     * @return Whether the oneofBytesStringPiece field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofBytesStringPiece() {
-      return oneofFieldCase_ == 8;
-    }
-    /**
-     * <code>bytes oneof_bytes_string_piece = 8 [default = "default StringPiece", ctype = STRING_PIECE];</code>
-     * @return The oneofBytesStringPiece.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getOneofBytesStringPiece() {
-      if (oneofFieldCase_ == 8) {
-        return (com.google.protobuf.ByteString) oneofField_;
-      }
-      return com.google.protobuf.Internal.bytesDefaultValue("default StringPiece");
-    }
-    /**
-     * <code>bytes oneof_bytes_string_piece = 8 [default = "default StringPiece", ctype = STRING_PIECE];</code>
-     * @param value The oneofBytesStringPiece to set.
-     */
-    private void setOneofBytesStringPiece(com.google.protobuf.ByteString value) {
-      value.getClass();
-  oneofFieldCase_ = 8;
-      oneofField_ = value;
-    }
-    /**
-     * <code>bytes oneof_bytes_string_piece = 8 [default = "default StringPiece", ctype = STRING_PIECE];</code>
-     */
-    private void clearOneofBytesStringPiece() {
-      if (oneofFieldCase_ == 8) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static final int ONEOF_ENUM_FIELD_NUMBER = 9;
-    /**
-     * <code>.protobuf_unittest.V2EnumLite oneof_enum = 9;</code>
-     * @return Whether the oneofEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofEnum() {
-      return oneofFieldCase_ == 9;
-    }
-    /**
-     * <code>.protobuf_unittest.V2EnumLite oneof_enum = 9;</code>
-     * @return The oneofEnum.
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.V2EnumLite getOneofEnum() {
-      if (oneofFieldCase_ == 9) {
-        com.google.protobuf.UnittestLite.V2EnumLite result = com.google.protobuf.UnittestLite.V2EnumLite.forNumber((java.lang.Integer) oneofField_);
-        return result == null ? com.google.protobuf.UnittestLite.V2EnumLite.V2_FIRST : result;
-      }
-      return com.google.protobuf.UnittestLite.V2EnumLite.V2_FIRST;
-    }
-    /**
-     * <code>.protobuf_unittest.V2EnumLite oneof_enum = 9;</code>
-     * @param value The oneofEnum to set.
-     */
-    private void setOneofEnum(com.google.protobuf.UnittestLite.V2EnumLite value) {
-      oneofField_ = value.getNumber();
-      oneofFieldCase_ = 9;
-    }
-    /**
-     * <code>.protobuf_unittest.V2EnumLite oneof_enum = 9;</code>
-     */
-    private void clearOneofEnum() {
-      if (oneofFieldCase_ == 9) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static com.google.protobuf.UnittestLite.TestOneofParsingLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestOneofParsingLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestOneofParsingLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestOneofParsingLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestOneofParsingLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.TestOneofParsingLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestOneofParsingLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestOneofParsingLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestOneofParsingLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestOneofParsingLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.TestOneofParsingLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.TestOneofParsingLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.TestOneofParsingLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestOneofParsingLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.UnittestLite.TestOneofParsingLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestOneofParsingLite)
-        com.google.protobuf.UnittestLite.TestOneofParsingLiteOrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.TestOneofParsingLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-      @java.lang.Override
-      public OneofFieldCase
-          getOneofFieldCase() {
-        return instance.getOneofFieldCase();
-      }
-
-      public Builder clearOneofField() {
-        copyOnWrite();
-        instance.clearOneofField();
-        return this;
-      }
-
-
-      /**
-       * <code>int32 oneof_int32 = 1;</code>
-       * @return Whether the oneofInt32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofInt32() {
-        return instance.hasOneofInt32();
-      }
-      /**
-       * <code>int32 oneof_int32 = 1;</code>
-       * @return The oneofInt32.
-       */
-      @java.lang.Override
-      public int getOneofInt32() {
-        return instance.getOneofInt32();
-      }
-      /**
-       * <code>int32 oneof_int32 = 1;</code>
-       * @param value The oneofInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofInt32(int value) {
-        copyOnWrite();
-        instance.setOneofInt32(value);
-        return this;
-      }
-      /**
-       * <code>int32 oneof_int32 = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofInt32() {
-        copyOnWrite();
-        instance.clearOneofInt32();
-        return this;
-      }
-
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite oneof_submessage = 2;</code>
-       */
-      @java.lang.Override
-      public boolean hasOneofSubmessage() {
-        return instance.hasOneofSubmessage();
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite oneof_submessage = 2;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.TestAllTypesLite getOneofSubmessage() {
-        return instance.getOneofSubmessage();
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite oneof_submessage = 2;</code>
-       */
-      public Builder setOneofSubmessage(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        copyOnWrite();
-        instance.setOneofSubmessage(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite oneof_submessage = 2;</code>
-       */
-      public Builder setOneofSubmessage(
-          com.google.protobuf.UnittestLite.TestAllTypesLite.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOneofSubmessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite oneof_submessage = 2;</code>
-       */
-      public Builder mergeOneofSubmessage(com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        copyOnWrite();
-        instance.mergeOneofSubmessage(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypesLite oneof_submessage = 2;</code>
-       */
-      public Builder clearOneofSubmessage() {
-        copyOnWrite();
-        instance.clearOneofSubmessage();
-        return this;
-      }
-
-      /**
-       * <code>string oneof_string = 3;</code>
-       * @return Whether the oneofString field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofString() {
-        return instance.hasOneofString();
-      }
-      /**
-       * <code>string oneof_string = 3;</code>
-       * @return The oneofString.
-       */
-      @java.lang.Override
-      public java.lang.String getOneofString() {
-        return instance.getOneofString();
-      }
-      /**
-       * <code>string oneof_string = 3;</code>
-       * @return The bytes for oneofString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getOneofStringBytes() {
-        return instance.getOneofStringBytes();
-      }
-      /**
-       * <code>string oneof_string = 3;</code>
-       * @param value The oneofString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setOneofString(value);
-        return this;
-      }
-      /**
-       * <code>string oneof_string = 3;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofString() {
-        copyOnWrite();
-        instance.clearOneofString();
-        return this;
-      }
-      /**
-       * <code>string oneof_string = 3;</code>
-       * @param value The bytes for oneofString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOneofStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>bytes oneof_bytes = 4 [default = "default bytes"];</code>
-       * @return Whether the oneofBytes field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofBytes() {
-        return instance.hasOneofBytes();
-      }
-      /**
-       * <code>bytes oneof_bytes = 4 [default = "default bytes"];</code>
-       * @return The oneofBytes.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getOneofBytes() {
-        return instance.getOneofBytes();
-      }
-      /**
-       * <code>bytes oneof_bytes = 4 [default = "default bytes"];</code>
-       * @param value The oneofBytes to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofBytes(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOneofBytes(value);
-        return this;
-      }
-      /**
-       * <code>bytes oneof_bytes = 4 [default = "default bytes"];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofBytes() {
-        copyOnWrite();
-        instance.clearOneofBytes();
-        return this;
-      }
-
-      /**
-       * <code>string oneof_string_cord = 5 [default = "default Cord", ctype = CORD];</code>
-       * @return Whether the oneofStringCord field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofStringCord() {
-        return instance.hasOneofStringCord();
-      }
-      /**
-       * <code>string oneof_string_cord = 5 [default = "default Cord", ctype = CORD];</code>
-       * @return The oneofStringCord.
-       */
-      @java.lang.Override
-      public java.lang.String getOneofStringCord() {
-        return instance.getOneofStringCord();
-      }
-      /**
-       * <code>string oneof_string_cord = 5 [default = "default Cord", ctype = CORD];</code>
-       * @return The bytes for oneofStringCord.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getOneofStringCordBytes() {
-        return instance.getOneofStringCordBytes();
-      }
-      /**
-       * <code>string oneof_string_cord = 5 [default = "default Cord", ctype = CORD];</code>
-       * @param value The oneofStringCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofStringCord(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setOneofStringCord(value);
-        return this;
-      }
-      /**
-       * <code>string oneof_string_cord = 5 [default = "default Cord", ctype = CORD];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofStringCord() {
-        copyOnWrite();
-        instance.clearOneofStringCord();
-        return this;
-      }
-      /**
-       * <code>string oneof_string_cord = 5 [default = "default Cord", ctype = CORD];</code>
-       * @param value The bytes for oneofStringCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofStringCordBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOneofStringCordBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>bytes oneof_bytes_cord = 6 [ctype = CORD];</code>
-       * @return Whether the oneofBytesCord field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofBytesCord() {
-        return instance.hasOneofBytesCord();
-      }
-      /**
-       * <code>bytes oneof_bytes_cord = 6 [ctype = CORD];</code>
-       * @return The oneofBytesCord.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getOneofBytesCord() {
-        return instance.getOneofBytesCord();
-      }
-      /**
-       * <code>bytes oneof_bytes_cord = 6 [ctype = CORD];</code>
-       * @param value The oneofBytesCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofBytesCord(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOneofBytesCord(value);
-        return this;
-      }
-      /**
-       * <code>bytes oneof_bytes_cord = 6 [ctype = CORD];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofBytesCord() {
-        copyOnWrite();
-        instance.clearOneofBytesCord();
-        return this;
-      }
-
-      /**
-       * <code>string oneof_string_string_piece = 7 [ctype = STRING_PIECE];</code>
-       * @return Whether the oneofStringStringPiece field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofStringStringPiece() {
-        return instance.hasOneofStringStringPiece();
-      }
-      /**
-       * <code>string oneof_string_string_piece = 7 [ctype = STRING_PIECE];</code>
-       * @return The oneofStringStringPiece.
-       */
-      @java.lang.Override
-      public java.lang.String getOneofStringStringPiece() {
-        return instance.getOneofStringStringPiece();
-      }
-      /**
-       * <code>string oneof_string_string_piece = 7 [ctype = STRING_PIECE];</code>
-       * @return The bytes for oneofStringStringPiece.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getOneofStringStringPieceBytes() {
-        return instance.getOneofStringStringPieceBytes();
-      }
-      /**
-       * <code>string oneof_string_string_piece = 7 [ctype = STRING_PIECE];</code>
-       * @param value The oneofStringStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofStringStringPiece(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setOneofStringStringPiece(value);
-        return this;
-      }
-      /**
-       * <code>string oneof_string_string_piece = 7 [ctype = STRING_PIECE];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofStringStringPiece() {
-        copyOnWrite();
-        instance.clearOneofStringStringPiece();
-        return this;
-      }
-      /**
-       * <code>string oneof_string_string_piece = 7 [ctype = STRING_PIECE];</code>
-       * @param value The bytes for oneofStringStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofStringStringPieceBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOneofStringStringPieceBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>bytes oneof_bytes_string_piece = 8 [default = "default StringPiece", ctype = STRING_PIECE];</code>
-       * @return Whether the oneofBytesStringPiece field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofBytesStringPiece() {
-        return instance.hasOneofBytesStringPiece();
-      }
-      /**
-       * <code>bytes oneof_bytes_string_piece = 8 [default = "default StringPiece", ctype = STRING_PIECE];</code>
-       * @return The oneofBytesStringPiece.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getOneofBytesStringPiece() {
-        return instance.getOneofBytesStringPiece();
-      }
-      /**
-       * <code>bytes oneof_bytes_string_piece = 8 [default = "default StringPiece", ctype = STRING_PIECE];</code>
-       * @param value The oneofBytesStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofBytesStringPiece(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOneofBytesStringPiece(value);
-        return this;
-      }
-      /**
-       * <code>bytes oneof_bytes_string_piece = 8 [default = "default StringPiece", ctype = STRING_PIECE];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofBytesStringPiece() {
-        copyOnWrite();
-        instance.clearOneofBytesStringPiece();
-        return this;
-      }
-
-      /**
-       * <code>.protobuf_unittest.V2EnumLite oneof_enum = 9;</code>
-       * @return Whether the oneofEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofEnum() {
-        return instance.hasOneofEnum();
-      }
-      /**
-       * <code>.protobuf_unittest.V2EnumLite oneof_enum = 9;</code>
-       * @return The oneofEnum.
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.V2EnumLite getOneofEnum() {
-        return instance.getOneofEnum();
-      }
-      /**
-       * <code>.protobuf_unittest.V2EnumLite oneof_enum = 9;</code>
-       * @param value The oneofEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofEnum(com.google.protobuf.UnittestLite.V2EnumLite value) {
-        copyOnWrite();
-        instance.setOneofEnum(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.V2EnumLite oneof_enum = 9;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofEnum() {
-        copyOnWrite();
-        instance.clearOneofEnum();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestOneofParsingLite)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.TestOneofParsingLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "oneofField_",
-              "oneofFieldCase_",
-              "bitField0_",
-              com.google.protobuf.UnittestLite.TestAllTypesLite.class,
-              com.google.protobuf.UnittestLite.V2EnumLite.internalGetVerifier(),
-            };
-            java.lang.String info =
-                "\u0001\t\u0001\u0001\u0001\t\t\u0000\u0000\u0000\u0001\u1037\u0000\u0002\u103c\u0000" +
-                "\u0003\u103b\u0000\u0004\u103d\u0000\u0005\u103b\u0000\u0006\u103d\u0000\u0007\u103b" +
-                "\u0000\b\u103d\u0000\t\u103f\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.TestOneofParsingLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.TestOneofParsingLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.TestOneofParsingLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestOneofParsingLite)
-    private static final com.google.protobuf.UnittestLite.TestOneofParsingLite DEFAULT_INSTANCE;
-    static {
-      TestOneofParsingLite defaultInstance = new TestOneofParsingLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestOneofParsingLite.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.TestOneofParsingLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestOneofParsingLite> PARSER;
-
-    public static com.google.protobuf.Parser<TestOneofParsingLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface PackedInt32OrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.PackedInt32)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-     * @return A list containing the repeatedInt32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedInt32List();
-    /**
-     * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-     * @return The count of repeatedInt32.
-     */
-    int getRepeatedInt32Count();
-    /**
-     * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt32 at the given index.
-     */
-    int getRepeatedInt32(int index);
-  }
-  /**
-   * <pre>
-   * The following four messages are set up to test for wire compatibility between
-   * packed and non-packed repeated fields. We use the field number 2048, because
-   * that is large enough to require a 3-byte varint for the tag.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.PackedInt32}
-   */
-  public  static final class PackedInt32 extends
-      com.google.protobuf.GeneratedMessageLite<
-          PackedInt32, PackedInt32.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.PackedInt32)
-      PackedInt32OrBuilder {
-    private PackedInt32() {
-      repeatedInt32_ = emptyIntList();
-    }
-    public static final int REPEATED_INT32_FIELD_NUMBER = 2048;
-    private com.google.protobuf.Internal.IntList repeatedInt32_;
-    /**
-     * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-     * @return A list containing the repeatedInt32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedInt32List() {
-      return repeatedInt32_;
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-     * @return The count of repeatedInt32.
-     */
-    @java.lang.Override
-    public int getRepeatedInt32Count() {
-      return repeatedInt32_.size();
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedInt32(int index) {
-      return repeatedInt32_.getInt(index);
-    }
-    private int repeatedInt32MemoizedSerializedSize = -1;
-    private void ensureRepeatedInt32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedInt32_;
-      if (!tmp.isModifiable()) {
-        repeatedInt32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt32 to set.
-     */
-    private void setRepeatedInt32(
-        int index, int value) {
-      ensureRepeatedInt32IsMutable();
-      repeatedInt32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-     * @param value The repeatedInt32 to add.
-     */
-    private void addRepeatedInt32(int value) {
-      ensureRepeatedInt32IsMutable();
-      repeatedInt32_.addInt(value);
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-     * @param values The repeatedInt32 to add.
-     */
-    private void addAllRepeatedInt32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedInt32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedInt32_);
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-     */
-    private void clearRepeatedInt32() {
-      repeatedInt32_ = emptyIntList();
-    }
-
-    public static com.google.protobuf.UnittestLite.PackedInt32 parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.PackedInt32 parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.PackedInt32 parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.PackedInt32 parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.PackedInt32 parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.PackedInt32 parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.PackedInt32 parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.PackedInt32 parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.PackedInt32 parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.PackedInt32 parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.PackedInt32 parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.PackedInt32 parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.PackedInt32 prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * The following four messages are set up to test for wire compatibility between
-     * packed and non-packed repeated fields. We use the field number 2048, because
-     * that is large enough to require a 3-byte varint for the tag.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.PackedInt32}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.UnittestLite.PackedInt32, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.PackedInt32)
-        com.google.protobuf.UnittestLite.PackedInt32OrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.PackedInt32.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-       * @return A list containing the repeatedInt32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedInt32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedInt32List());
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-       * @return The count of repeatedInt32.
-       */
-      @java.lang.Override
-      public int getRepeatedInt32Count() {
-        return instance.getRepeatedInt32Count();
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedInt32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedInt32(int index) {
-        return instance.getRepeatedInt32(index);
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-       * @param value The repeatedInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedInt32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedInt32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-       * @param value The repeatedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedInt32(int value) {
-        copyOnWrite();
-        instance.addRepeatedInt32(value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-       * @param values The repeatedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedInt32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedInt32(values);
-        return this;
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 2048 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedInt32() {
-        copyOnWrite();
-        instance.clearRepeatedInt32();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.PackedInt32)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.PackedInt32();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "repeatedInt32_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0000\u0800\u0800\u0001\u0000\u0001\u0000\u0800\'";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.PackedInt32> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.PackedInt32.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.PackedInt32>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.PackedInt32)
-    private static final com.google.protobuf.UnittestLite.PackedInt32 DEFAULT_INSTANCE;
-    static {
-      PackedInt32 defaultInstance = new PackedInt32();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        PackedInt32.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.PackedInt32 getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<PackedInt32> PARSER;
-
-    public static com.google.protobuf.Parser<PackedInt32> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface NonPackedInt32OrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.NonPackedInt32)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>repeated int32 repeated_int32 = 2048;</code>
-     * @return A list containing the repeatedInt32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedInt32List();
-    /**
-     * <code>repeated int32 repeated_int32 = 2048;</code>
-     * @return The count of repeatedInt32.
-     */
-    int getRepeatedInt32Count();
-    /**
-     * <code>repeated int32 repeated_int32 = 2048;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt32 at the given index.
-     */
-    int getRepeatedInt32(int index);
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.NonPackedInt32}
-   */
-  public  static final class NonPackedInt32 extends
-      com.google.protobuf.GeneratedMessageLite<
-          NonPackedInt32, NonPackedInt32.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.NonPackedInt32)
-      NonPackedInt32OrBuilder {
-    private NonPackedInt32() {
-      repeatedInt32_ = emptyIntList();
-    }
-    public static final int REPEATED_INT32_FIELD_NUMBER = 2048;
-    private com.google.protobuf.Internal.IntList repeatedInt32_;
-    /**
-     * <code>repeated int32 repeated_int32 = 2048;</code>
-     * @return A list containing the repeatedInt32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedInt32List() {
-      return repeatedInt32_;
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 2048;</code>
-     * @return The count of repeatedInt32.
-     */
-    @java.lang.Override
-    public int getRepeatedInt32Count() {
-      return repeatedInt32_.size();
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 2048;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedInt32(int index) {
-      return repeatedInt32_.getInt(index);
-    }
-    private void ensureRepeatedInt32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedInt32_;
-      if (!tmp.isModifiable()) {
-        repeatedInt32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 2048;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt32 to set.
-     */
-    private void setRepeatedInt32(
-        int index, int value) {
-      ensureRepeatedInt32IsMutable();
-      repeatedInt32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 2048;</code>
-     * @param value The repeatedInt32 to add.
-     */
-    private void addRepeatedInt32(int value) {
-      ensureRepeatedInt32IsMutable();
-      repeatedInt32_.addInt(value);
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 2048;</code>
-     * @param values The repeatedInt32 to add.
-     */
-    private void addAllRepeatedInt32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedInt32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedInt32_);
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 2048;</code>
-     */
-    private void clearRepeatedInt32() {
-      repeatedInt32_ = emptyIntList();
-    }
-
-    public static com.google.protobuf.UnittestLite.NonPackedInt32 parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedInt32 parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedInt32 parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedInt32 parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedInt32 parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedInt32 parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedInt32 parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedInt32 parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedInt32 parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedInt32 parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedInt32 parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedInt32 parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.NonPackedInt32 prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.NonPackedInt32}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.UnittestLite.NonPackedInt32, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.NonPackedInt32)
-        com.google.protobuf.UnittestLite.NonPackedInt32OrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.NonPackedInt32.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>repeated int32 repeated_int32 = 2048;</code>
-       * @return A list containing the repeatedInt32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedInt32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedInt32List());
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 2048;</code>
-       * @return The count of repeatedInt32.
-       */
-      @java.lang.Override
-      public int getRepeatedInt32Count() {
-        return instance.getRepeatedInt32Count();
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 2048;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedInt32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedInt32(int index) {
-        return instance.getRepeatedInt32(index);
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 2048;</code>
-       * @param value The repeatedInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedInt32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedInt32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 2048;</code>
-       * @param value The repeatedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedInt32(int value) {
-        copyOnWrite();
-        instance.addRepeatedInt32(value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 2048;</code>
-       * @param values The repeatedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedInt32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedInt32(values);
-        return this;
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 2048;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedInt32() {
-        copyOnWrite();
-        instance.clearRepeatedInt32();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.NonPackedInt32)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.NonPackedInt32();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "repeatedInt32_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0000\u0800\u0800\u0001\u0000\u0001\u0000\u0800\u0016";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.NonPackedInt32> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.NonPackedInt32.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.NonPackedInt32>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.NonPackedInt32)
-    private static final com.google.protobuf.UnittestLite.NonPackedInt32 DEFAULT_INSTANCE;
-    static {
-      NonPackedInt32 defaultInstance = new NonPackedInt32();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        NonPackedInt32.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.NonPackedInt32 getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<NonPackedInt32> PARSER;
-
-    public static com.google.protobuf.Parser<NonPackedInt32> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface PackedFixed32OrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.PackedFixed32)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-     * @return A list containing the repeatedFixed32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedFixed32List();
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-     * @return The count of repeatedFixed32.
-     */
-    int getRepeatedFixed32Count();
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed32 at the given index.
-     */
-    int getRepeatedFixed32(int index);
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.PackedFixed32}
-   */
-  public  static final class PackedFixed32 extends
-      com.google.protobuf.GeneratedMessageLite<
-          PackedFixed32, PackedFixed32.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.PackedFixed32)
-      PackedFixed32OrBuilder {
-    private PackedFixed32() {
-      repeatedFixed32_ = emptyIntList();
-    }
-    public static final int REPEATED_FIXED32_FIELD_NUMBER = 2048;
-    private com.google.protobuf.Internal.IntList repeatedFixed32_;
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-     * @return A list containing the repeatedFixed32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedFixed32List() {
-      return repeatedFixed32_;
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-     * @return The count of repeatedFixed32.
-     */
-    @java.lang.Override
-    public int getRepeatedFixed32Count() {
-      return repeatedFixed32_.size();
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedFixed32(int index) {
-      return repeatedFixed32_.getInt(index);
-    }
-    private int repeatedFixed32MemoizedSerializedSize = -1;
-    private void ensureRepeatedFixed32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedFixed32_;
-      if (!tmp.isModifiable()) {
-        repeatedFixed32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed32 to set.
-     */
-    private void setRepeatedFixed32(
-        int index, int value) {
-      ensureRepeatedFixed32IsMutable();
-      repeatedFixed32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-     * @param value The repeatedFixed32 to add.
-     */
-    private void addRepeatedFixed32(int value) {
-      ensureRepeatedFixed32IsMutable();
-      repeatedFixed32_.addInt(value);
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-     * @param values The repeatedFixed32 to add.
-     */
-    private void addAllRepeatedFixed32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedFixed32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedFixed32_);
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-     */
-    private void clearRepeatedFixed32() {
-      repeatedFixed32_ = emptyIntList();
-    }
-
-    public static com.google.protobuf.UnittestLite.PackedFixed32 parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.PackedFixed32 parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.PackedFixed32 parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.PackedFixed32 parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.PackedFixed32 parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.PackedFixed32 parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.PackedFixed32 parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.PackedFixed32 parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.PackedFixed32 parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.PackedFixed32 parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.PackedFixed32 parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.PackedFixed32 parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.PackedFixed32 prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.PackedFixed32}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.UnittestLite.PackedFixed32, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.PackedFixed32)
-        com.google.protobuf.UnittestLite.PackedFixed32OrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.PackedFixed32.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-       * @return A list containing the repeatedFixed32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedFixed32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedFixed32List());
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-       * @return The count of repeatedFixed32.
-       */
-      @java.lang.Override
-      public int getRepeatedFixed32Count() {
-        return instance.getRepeatedFixed32Count();
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedFixed32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedFixed32(int index) {
-        return instance.getRepeatedFixed32(index);
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-       * @param value The repeatedFixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedFixed32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedFixed32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-       * @param value The repeatedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedFixed32(int value) {
-        copyOnWrite();
-        instance.addRepeatedFixed32(value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-       * @param values The repeatedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedFixed32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedFixed32(values);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 2048 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedFixed32() {
-        copyOnWrite();
-        instance.clearRepeatedFixed32();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.PackedFixed32)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.PackedFixed32();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "repeatedFixed32_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0000\u0800\u0800\u0001\u0000\u0001\u0000\u0800)";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.PackedFixed32> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.PackedFixed32.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.PackedFixed32>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.PackedFixed32)
-    private static final com.google.protobuf.UnittestLite.PackedFixed32 DEFAULT_INSTANCE;
-    static {
-      PackedFixed32 defaultInstance = new PackedFixed32();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        PackedFixed32.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.PackedFixed32 getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<PackedFixed32> PARSER;
-
-    public static com.google.protobuf.Parser<PackedFixed32> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface NonPackedFixed32OrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.NonPackedFixed32)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-     * @return A list containing the repeatedFixed32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedFixed32List();
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-     * @return The count of repeatedFixed32.
-     */
-    int getRepeatedFixed32Count();
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed32 at the given index.
-     */
-    int getRepeatedFixed32(int index);
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.NonPackedFixed32}
-   */
-  public  static final class NonPackedFixed32 extends
-      com.google.protobuf.GeneratedMessageLite<
-          NonPackedFixed32, NonPackedFixed32.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.NonPackedFixed32)
-      NonPackedFixed32OrBuilder {
-    private NonPackedFixed32() {
-      repeatedFixed32_ = emptyIntList();
-    }
-    public static final int REPEATED_FIXED32_FIELD_NUMBER = 2048;
-    private com.google.protobuf.Internal.IntList repeatedFixed32_;
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-     * @return A list containing the repeatedFixed32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedFixed32List() {
-      return repeatedFixed32_;
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-     * @return The count of repeatedFixed32.
-     */
-    @java.lang.Override
-    public int getRepeatedFixed32Count() {
-      return repeatedFixed32_.size();
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedFixed32(int index) {
-      return repeatedFixed32_.getInt(index);
-    }
-    private void ensureRepeatedFixed32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedFixed32_;
-      if (!tmp.isModifiable()) {
-        repeatedFixed32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed32 to set.
-     */
-    private void setRepeatedFixed32(
-        int index, int value) {
-      ensureRepeatedFixed32IsMutable();
-      repeatedFixed32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-     * @param value The repeatedFixed32 to add.
-     */
-    private void addRepeatedFixed32(int value) {
-      ensureRepeatedFixed32IsMutable();
-      repeatedFixed32_.addInt(value);
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-     * @param values The repeatedFixed32 to add.
-     */
-    private void addAllRepeatedFixed32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedFixed32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedFixed32_);
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-     */
-    private void clearRepeatedFixed32() {
-      repeatedFixed32_ = emptyIntList();
-    }
-
-    public static com.google.protobuf.UnittestLite.NonPackedFixed32 parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedFixed32 parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedFixed32 parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedFixed32 parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedFixed32 parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedFixed32 parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedFixed32 parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedFixed32 parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedFixed32 parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedFixed32 parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedFixed32 parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.NonPackedFixed32 parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.NonPackedFixed32 prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.NonPackedFixed32}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.UnittestLite.NonPackedFixed32, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.NonPackedFixed32)
-        com.google.protobuf.UnittestLite.NonPackedFixed32OrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.NonPackedFixed32.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-       * @return A list containing the repeatedFixed32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedFixed32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedFixed32List());
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-       * @return The count of repeatedFixed32.
-       */
-      @java.lang.Override
-      public int getRepeatedFixed32Count() {
-        return instance.getRepeatedFixed32Count();
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedFixed32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedFixed32(int index) {
-        return instance.getRepeatedFixed32(index);
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-       * @param value The repeatedFixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedFixed32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedFixed32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-       * @param value The repeatedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedFixed32(int value) {
-        copyOnWrite();
-        instance.addRepeatedFixed32(value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-       * @param values The repeatedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedFixed32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedFixed32(values);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 2048;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedFixed32() {
-        copyOnWrite();
-        instance.clearRepeatedFixed32();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.NonPackedFixed32)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.NonPackedFixed32();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "repeatedFixed32_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0000\u0800\u0800\u0001\u0000\u0001\u0000\u0800\u0018";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.NonPackedFixed32> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.NonPackedFixed32.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.NonPackedFixed32>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.NonPackedFixed32)
-    private static final com.google.protobuf.UnittestLite.NonPackedFixed32 DEFAULT_INSTANCE;
-    static {
-      NonPackedFixed32 defaultInstance = new NonPackedFixed32();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        NonPackedFixed32.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.NonPackedFixed32 getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<NonPackedFixed32> PARSER;
-
-    public static com.google.protobuf.Parser<NonPackedFixed32> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface DupEnumOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.DupEnum)
-      com.google.protobuf.MessageLiteOrBuilder {
-  }
-  /**
-   * <pre>
-   * Test an enum that has multiple values with the same number.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.DupEnum}
-   */
-  public  static final class DupEnum extends
-      com.google.protobuf.GeneratedMessageLite<
-          DupEnum, DupEnum.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.DupEnum)
-      DupEnumOrBuilder {
-    private DupEnum() {
-    }
-    /**
-     * Protobuf enum {@code protobuf_unittest.DupEnum.TestEnumWithDupValueLite}
-     */
-    public enum TestEnumWithDupValueLite
-        implements com.google.protobuf.Internal.EnumLite {
-      /**
-       * <code>FOO1 = 1;</code>
-       */
-      FOO1(1),
-      /**
-       * <code>BAR1 = 2;</code>
-       */
-      BAR1(2),
-      /**
-       * <code>BAZ = 3;</code>
-       */
-      BAZ(3),
-      ;
-
-      /**
-       * <code>FOO2 = 1;</code>
-       */
-      public static final TestEnumWithDupValueLite FOO2 = FOO1;
-      /**
-       * <code>BAR2 = 2;</code>
-       */
-      public static final TestEnumWithDupValueLite BAR2 = BAR1;
-      /**
-       * <code>FOO1 = 1;</code>
-       */
-      public static final int FOO1_VALUE = 1;
-      /**
-       * <code>BAR1 = 2;</code>
-       */
-      public static final int BAR1_VALUE = 2;
-      /**
-       * <code>BAZ = 3;</code>
-       */
-      public static final int BAZ_VALUE = 3;
-      /**
-       * <code>FOO2 = 1;</code>
-       */
-      public static final int FOO2_VALUE = 1;
-      /**
-       * <code>BAR2 = 2;</code>
-       */
-      public static final int BAR2_VALUE = 2;
-
-
-      @java.lang.Override
-      public final int getNumber() {
-        return value;
-      }
-
-      /**
-       * @param value The number of the enum to look for.
-       * @return The enum associated with the given number.
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static TestEnumWithDupValueLite valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static TestEnumWithDupValueLite forNumber(int value) {
-        switch (value) {
-          case 1: return FOO1;
-          case 2: return BAR1;
-          case 3: return BAZ;
-          default: return null;
-        }
-      }
-
-      public static com.google.protobuf.Internal.EnumLiteMap<TestEnumWithDupValueLite>
-          internalGetValueMap() {
-        return internalValueMap;
-      }
-      private static final com.google.protobuf.Internal.EnumLiteMap<
-          TestEnumWithDupValueLite> internalValueMap =
-            new com.google.protobuf.Internal.EnumLiteMap<TestEnumWithDupValueLite>() {
-              @java.lang.Override
-              public TestEnumWithDupValueLite findValueByNumber(int number) {
-                return TestEnumWithDupValueLite.forNumber(number);
-              }
-            };
-
-      public static com.google.protobuf.Internal.EnumVerifier 
-          internalGetVerifier() {
-        return TestEnumWithDupValueLiteVerifier.INSTANCE;
-      }
-
-      private static final class TestEnumWithDupValueLiteVerifier implements 
-           com.google.protobuf.Internal.EnumVerifier { 
-              static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new TestEnumWithDupValueLiteVerifier();
-              @java.lang.Override
-              public boolean isInRange(int number) {
-                return TestEnumWithDupValueLite.forNumber(number) != null;
-              }
-            };
-
-      private final int value;
-
-      private TestEnumWithDupValueLite(int value) {
-        this.value = value;
-      }
-
-      // @@protoc_insertion_point(enum_scope:protobuf_unittest.DupEnum.TestEnumWithDupValueLite)
-    }
-
-    public static com.google.protobuf.UnittestLite.DupEnum parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.DupEnum parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.DupEnum parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.DupEnum parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.DupEnum parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.DupEnum parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.DupEnum parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.DupEnum parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.DupEnum parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.DupEnum parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.DupEnum parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.DupEnum parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.DupEnum prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Test an enum that has multiple values with the same number.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.DupEnum}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.UnittestLite.DupEnum, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.DupEnum)
-        com.google.protobuf.UnittestLite.DupEnumOrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.DupEnum.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.DupEnum)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.DupEnum();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.DupEnum> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.DupEnum.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.DupEnum>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.DupEnum)
-    private static final com.google.protobuf.UnittestLite.DupEnum DEFAULT_INSTANCE;
-    static {
-      DupEnum defaultInstance = new DupEnum();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        DupEnum.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.DupEnum getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<DupEnum> PARSER;
-
-    public static com.google.protobuf.Parser<DupEnum> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface RecursiveMessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.RecursiveMessage)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional .protobuf_unittest.RecursiveMessage recurse = 1;</code>
-     * @return Whether the recurse field is set.
-     */
-    boolean hasRecurse();
-    /**
-     * <code>optional .protobuf_unittest.RecursiveMessage recurse = 1;</code>
-     * @return The recurse.
-     */
-    com.google.protobuf.UnittestLite.RecursiveMessage getRecurse();
-
-    /**
-     * <code>optional bytes payload = 2;</code>
-     * @return Whether the payload field is set.
-     */
-    boolean hasPayload();
-    /**
-     * <code>optional bytes payload = 2;</code>
-     * @return The payload.
-     */
-    com.google.protobuf.ByteString getPayload();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.RecursiveMessage}
-   */
-  public  static final class RecursiveMessage extends
-      com.google.protobuf.GeneratedMessageLite<
-          RecursiveMessage, RecursiveMessage.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.RecursiveMessage)
-      RecursiveMessageOrBuilder {
-    private RecursiveMessage() {
-      payload_ = com.google.protobuf.ByteString.EMPTY;
-    }
-    private int bitField0_;
-    public static final int RECURSE_FIELD_NUMBER = 1;
-    private com.google.protobuf.UnittestLite.RecursiveMessage recurse_;
-    /**
-     * <code>optional .protobuf_unittest.RecursiveMessage recurse = 1;</code>
-     */
-    @java.lang.Override
-    public boolean hasRecurse() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.RecursiveMessage recurse = 1;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.UnittestLite.RecursiveMessage getRecurse() {
-      return recurse_ == null ? com.google.protobuf.UnittestLite.RecursiveMessage.getDefaultInstance() : recurse_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.RecursiveMessage recurse = 1;</code>
-     */
-    private void setRecurse(com.google.protobuf.UnittestLite.RecursiveMessage value) {
-      value.getClass();
-  recurse_ = value;
-      bitField0_ |= 0x00000001;
-      }
-    /**
-     * <code>optional .protobuf_unittest.RecursiveMessage recurse = 1;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeRecurse(com.google.protobuf.UnittestLite.RecursiveMessage value) {
-      value.getClass();
-  if (recurse_ != null &&
-          recurse_ != com.google.protobuf.UnittestLite.RecursiveMessage.getDefaultInstance()) {
-        recurse_ =
-          com.google.protobuf.UnittestLite.RecursiveMessage.newBuilder(recurse_).mergeFrom(value).buildPartial();
-      } else {
-        recurse_ = value;
-      }
-      bitField0_ |= 0x00000001;
-    }
-    /**
-     * <code>optional .protobuf_unittest.RecursiveMessage recurse = 1;</code>
-     */
-    private void clearRecurse() {  recurse_ = null;
-      bitField0_ = (bitField0_ & ~0x00000001);
-    }
-
-    public static final int PAYLOAD_FIELD_NUMBER = 2;
-    private com.google.protobuf.ByteString payload_;
-    /**
-     * <code>optional bytes payload = 2;</code>
-     * @return Whether the payload field is set.
-     */
-    @java.lang.Override
-    public boolean hasPayload() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional bytes payload = 2;</code>
-     * @return The payload.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getPayload() {
-      return payload_;
-    }
-    /**
-     * <code>optional bytes payload = 2;</code>
-     * @param value The payload to set.
-     */
-    private void setPayload(com.google.protobuf.ByteString value) {
-      value.getClass();
-  bitField0_ |= 0x00000002;
-      payload_ = value;
-    }
-    /**
-     * <code>optional bytes payload = 2;</code>
-     */
-    private void clearPayload() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      payload_ = getDefaultInstance().getPayload();
-    }
-
-    public static com.google.protobuf.UnittestLite.RecursiveMessage parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.RecursiveMessage parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.RecursiveMessage parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.RecursiveMessage parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.RecursiveMessage parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.UnittestLite.RecursiveMessage parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.RecursiveMessage parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.RecursiveMessage parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.RecursiveMessage parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.RecursiveMessage parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.UnittestLite.RecursiveMessage parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.UnittestLite.RecursiveMessage parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.UnittestLite.RecursiveMessage prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.RecursiveMessage}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.UnittestLite.RecursiveMessage, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.RecursiveMessage)
-        com.google.protobuf.UnittestLite.RecursiveMessageOrBuilder {
-      // Construct using com.google.protobuf.UnittestLite.RecursiveMessage.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional .protobuf_unittest.RecursiveMessage recurse = 1;</code>
-       */
-      @java.lang.Override
-      public boolean hasRecurse() {
-        return instance.hasRecurse();
-      }
-      /**
-       * <code>optional .protobuf_unittest.RecursiveMessage recurse = 1;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.UnittestLite.RecursiveMessage getRecurse() {
-        return instance.getRecurse();
-      }
-      /**
-       * <code>optional .protobuf_unittest.RecursiveMessage recurse = 1;</code>
-       */
-      public Builder setRecurse(com.google.protobuf.UnittestLite.RecursiveMessage value) {
-        copyOnWrite();
-        instance.setRecurse(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.RecursiveMessage recurse = 1;</code>
-       */
-      public Builder setRecurse(
-          com.google.protobuf.UnittestLite.RecursiveMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRecurse(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.RecursiveMessage recurse = 1;</code>
-       */
-      public Builder mergeRecurse(com.google.protobuf.UnittestLite.RecursiveMessage value) {
-        copyOnWrite();
-        instance.mergeRecurse(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.RecursiveMessage recurse = 1;</code>
-       */
-      public Builder clearRecurse() {  copyOnWrite();
-        instance.clearRecurse();
-        return this;
-      }
-
-      /**
-       * <code>optional bytes payload = 2;</code>
-       * @return Whether the payload field is set.
-       */
-      @java.lang.Override
-      public boolean hasPayload() {
-        return instance.hasPayload();
-      }
-      /**
-       * <code>optional bytes payload = 2;</code>
-       * @return The payload.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getPayload() {
-        return instance.getPayload();
-      }
-      /**
-       * <code>optional bytes payload = 2;</code>
-       * @param value The payload to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPayload(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setPayload(value);
-        return this;
-      }
-      /**
-       * <code>optional bytes payload = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPayload() {
-        copyOnWrite();
-        instance.clearPayload();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.RecursiveMessage)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.UnittestLite.RecursiveMessage();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "recurse_",
-              "payload_",
-            };
-            java.lang.String info =
-                "\u0001\u0002\u0000\u0001\u0001\u0002\u0002\u0000\u0000\u0000\u0001\u1009\u0000\u0002" +
-                "\u100a\u0001";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.UnittestLite.RecursiveMessage> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.UnittestLite.RecursiveMessage.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.UnittestLite.RecursiveMessage>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.RecursiveMessage)
-    private static final com.google.protobuf.UnittestLite.RecursiveMessage DEFAULT_INSTANCE;
-    static {
-      RecursiveMessage defaultInstance = new RecursiveMessage();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        RecursiveMessage.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.UnittestLite.RecursiveMessage getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<RecursiveMessage> PARSER;
-
-    public static com.google.protobuf.Parser<RecursiveMessage> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public static final int OPTIONAL_INT32_EXTENSION_LITE_FIELD_NUMBER = 1;
-  /**
-   * <pre>
-   * Singular
-   * </pre>
-   *
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Integer> optionalInt32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        0,
-        null,
-        null,
-        1,
-        com.google.protobuf.WireFormat.FieldType.INT32,
-        java.lang.Integer.class);
-  public static final int OPTIONAL_INT64_EXTENSION_LITE_FIELD_NUMBER = 2;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Long> optionalInt64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        0L,
-        null,
-        null,
-        2,
-        com.google.protobuf.WireFormat.FieldType.INT64,
-        java.lang.Long.class);
-  public static final int OPTIONAL_UINT32_EXTENSION_LITE_FIELD_NUMBER = 3;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Integer> optionalUint32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        0,
-        null,
-        null,
-        3,
-        com.google.protobuf.WireFormat.FieldType.UINT32,
-        java.lang.Integer.class);
-  public static final int OPTIONAL_UINT64_EXTENSION_LITE_FIELD_NUMBER = 4;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Long> optionalUint64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        0L,
-        null,
-        null,
-        4,
-        com.google.protobuf.WireFormat.FieldType.UINT64,
-        java.lang.Long.class);
-  public static final int OPTIONAL_SINT32_EXTENSION_LITE_FIELD_NUMBER = 5;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Integer> optionalSint32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        0,
-        null,
-        null,
-        5,
-        com.google.protobuf.WireFormat.FieldType.SINT32,
-        java.lang.Integer.class);
-  public static final int OPTIONAL_SINT64_EXTENSION_LITE_FIELD_NUMBER = 6;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Long> optionalSint64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        0L,
-        null,
-        null,
-        6,
-        com.google.protobuf.WireFormat.FieldType.SINT64,
-        java.lang.Long.class);
-  public static final int OPTIONAL_FIXED32_EXTENSION_LITE_FIELD_NUMBER = 7;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Integer> optionalFixed32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        0,
-        null,
-        null,
-        7,
-        com.google.protobuf.WireFormat.FieldType.FIXED32,
-        java.lang.Integer.class);
-  public static final int OPTIONAL_FIXED64_EXTENSION_LITE_FIELD_NUMBER = 8;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Long> optionalFixed64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        0L,
-        null,
-        null,
-        8,
-        com.google.protobuf.WireFormat.FieldType.FIXED64,
-        java.lang.Long.class);
-  public static final int OPTIONAL_SFIXED32_EXTENSION_LITE_FIELD_NUMBER = 9;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Integer> optionalSfixed32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        0,
-        null,
-        null,
-        9,
-        com.google.protobuf.WireFormat.FieldType.SFIXED32,
-        java.lang.Integer.class);
-  public static final int OPTIONAL_SFIXED64_EXTENSION_LITE_FIELD_NUMBER = 10;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Long> optionalSfixed64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        0L,
-        null,
-        null,
-        10,
-        com.google.protobuf.WireFormat.FieldType.SFIXED64,
-        java.lang.Long.class);
-  public static final int OPTIONAL_FLOAT_EXTENSION_LITE_FIELD_NUMBER = 11;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Float> optionalFloatExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        0F,
-        null,
-        null,
-        11,
-        com.google.protobuf.WireFormat.FieldType.FLOAT,
-        java.lang.Float.class);
-  public static final int OPTIONAL_DOUBLE_EXTENSION_LITE_FIELD_NUMBER = 12;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Double> optionalDoubleExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        0D,
-        null,
-        null,
-        12,
-        com.google.protobuf.WireFormat.FieldType.DOUBLE,
-        java.lang.Double.class);
-  public static final int OPTIONAL_BOOL_EXTENSION_LITE_FIELD_NUMBER = 13;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Boolean> optionalBoolExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        false,
-        null,
-        null,
-        13,
-        com.google.protobuf.WireFormat.FieldType.BOOL,
-        java.lang.Boolean.class);
-  public static final int OPTIONAL_STRING_EXTENSION_LITE_FIELD_NUMBER = 14;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.String> optionalStringExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        "",
-        null,
-        null,
-        14,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        java.lang.String.class);
-  public static final int OPTIONAL_BYTES_EXTENSION_LITE_FIELD_NUMBER = 15;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      com.google.protobuf.ByteString> optionalBytesExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.ByteString.EMPTY,
-        null,
-        null,
-        15,
-        com.google.protobuf.WireFormat.FieldType.BYTES,
-        com.google.protobuf.ByteString.class);
-  public static final int OPTIONALGROUP_EXTENSION_LITE_FIELD_NUMBER = 16;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      com.google.protobuf.UnittestLite.OptionalGroup_extension_lite> optionalGroupExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.OptionalGroup_extension_lite.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.OptionalGroup_extension_lite.getDefaultInstance(),
-        null,
-        16,
-        com.google.protobuf.WireFormat.FieldType.GROUP,
-        com.google.protobuf.UnittestLite.OptionalGroup_extension_lite.class);
-  public static final int OPTIONAL_NESTED_MESSAGE_EXTENSION_LITE_FIELD_NUMBER = 18;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage> optionalNestedMessageExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.getDefaultInstance(),
-        null,
-        18,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.class);
-  public static final int OPTIONAL_FOREIGN_MESSAGE_EXTENSION_LITE_FIELD_NUMBER = 19;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      com.google.protobuf.UnittestLite.ForeignMessageLite> optionalForeignMessageExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.ForeignMessageLite.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.ForeignMessageLite.getDefaultInstance(),
-        null,
-        19,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        com.google.protobuf.UnittestLite.ForeignMessageLite.class);
-  public static final int OPTIONAL_IMPORT_MESSAGE_EXTENSION_LITE_FIELD_NUMBER = 20;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      com.google.protobuf.UnittestImportLite.ImportMessageLite> optionalImportMessageExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.UnittestImportLite.ImportMessageLite.getDefaultInstance(),
-        com.google.protobuf.UnittestImportLite.ImportMessageLite.getDefaultInstance(),
-        null,
-        20,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        com.google.protobuf.UnittestImportLite.ImportMessageLite.class);
-  public static final int OPTIONAL_NESTED_ENUM_EXTENSION_LITE_FIELD_NUMBER = 21;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum> optionalNestedEnumExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum.FOO,
-        null,
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum.internalGetValueMap(),
-        21,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum.class);
-  public static final int OPTIONAL_FOREIGN_ENUM_EXTENSION_LITE_FIELD_NUMBER = 22;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      com.google.protobuf.UnittestLite.ForeignEnumLite> optionalForeignEnumExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.ForeignEnumLite.FOREIGN_LITE_FOO,
-        null,
-        com.google.protobuf.UnittestLite.ForeignEnumLite.internalGetValueMap(),
-        22,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        com.google.protobuf.UnittestLite.ForeignEnumLite.class);
-  public static final int OPTIONAL_IMPORT_ENUM_EXTENSION_LITE_FIELD_NUMBER = 23;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      com.google.protobuf.UnittestImportLite.ImportEnumLite> optionalImportEnumExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.UnittestImportLite.ImportEnumLite.IMPORT_LITE_FOO,
-        null,
-        com.google.protobuf.UnittestImportLite.ImportEnumLite.internalGetValueMap(),
-        23,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        com.google.protobuf.UnittestImportLite.ImportEnumLite.class);
-  public static final int OPTIONAL_STRING_PIECE_EXTENSION_LITE_FIELD_NUMBER = 24;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.String> optionalStringPieceExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        "",
-        null,
-        null,
-        24,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        java.lang.String.class);
-  public static final int OPTIONAL_CORD_EXTENSION_LITE_FIELD_NUMBER = 25;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.String> optionalCordExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        "",
-        null,
-        null,
-        25,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        java.lang.String.class);
-  public static final int OPTIONAL_PUBLIC_IMPORT_MESSAGE_EXTENSION_LITE_FIELD_NUMBER = 26;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite> optionalPublicImportMessageExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite.getDefaultInstance(),
-        com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite.getDefaultInstance(),
-        null,
-        26,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite.class);
-  public static final int OPTIONAL_LAZY_MESSAGE_EXTENSION_LITE_FIELD_NUMBER = 27;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage> optionalLazyMessageExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.getDefaultInstance(),
-        null,
-        27,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.class);
-  public static final int REPEATED_INT32_EXTENSION_LITE_FIELD_NUMBER = 31;
-  /**
-   * <pre>
-   * Repeated
-   * </pre>
-   *
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<java.lang.Integer>> repeatedInt32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        31,
-        com.google.protobuf.WireFormat.FieldType.INT32,
-        false,
-        java.lang.Integer.class);
-  public static final int REPEATED_INT64_EXTENSION_LITE_FIELD_NUMBER = 32;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<java.lang.Long>> repeatedInt64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        32,
-        com.google.protobuf.WireFormat.FieldType.INT64,
-        false,
-        java.lang.Long.class);
-  public static final int REPEATED_UINT32_EXTENSION_LITE_FIELD_NUMBER = 33;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<java.lang.Integer>> repeatedUint32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        33,
-        com.google.protobuf.WireFormat.FieldType.UINT32,
-        false,
-        java.lang.Integer.class);
-  public static final int REPEATED_UINT64_EXTENSION_LITE_FIELD_NUMBER = 34;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<java.lang.Long>> repeatedUint64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        34,
-        com.google.protobuf.WireFormat.FieldType.UINT64,
-        false,
-        java.lang.Long.class);
-  public static final int REPEATED_SINT32_EXTENSION_LITE_FIELD_NUMBER = 35;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<java.lang.Integer>> repeatedSint32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        35,
-        com.google.protobuf.WireFormat.FieldType.SINT32,
-        false,
-        java.lang.Integer.class);
-  public static final int REPEATED_SINT64_EXTENSION_LITE_FIELD_NUMBER = 36;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<java.lang.Long>> repeatedSint64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        36,
-        com.google.protobuf.WireFormat.FieldType.SINT64,
-        false,
-        java.lang.Long.class);
-  public static final int REPEATED_FIXED32_EXTENSION_LITE_FIELD_NUMBER = 37;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<java.lang.Integer>> repeatedFixed32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        37,
-        com.google.protobuf.WireFormat.FieldType.FIXED32,
-        false,
-        java.lang.Integer.class);
-  public static final int REPEATED_FIXED64_EXTENSION_LITE_FIELD_NUMBER = 38;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<java.lang.Long>> repeatedFixed64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        38,
-        com.google.protobuf.WireFormat.FieldType.FIXED64,
-        false,
-        java.lang.Long.class);
-  public static final int REPEATED_SFIXED32_EXTENSION_LITE_FIELD_NUMBER = 39;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<java.lang.Integer>> repeatedSfixed32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        39,
-        com.google.protobuf.WireFormat.FieldType.SFIXED32,
-        false,
-        java.lang.Integer.class);
-  public static final int REPEATED_SFIXED64_EXTENSION_LITE_FIELD_NUMBER = 40;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<java.lang.Long>> repeatedSfixed64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        40,
-        com.google.protobuf.WireFormat.FieldType.SFIXED64,
-        false,
-        java.lang.Long.class);
-  public static final int REPEATED_FLOAT_EXTENSION_LITE_FIELD_NUMBER = 41;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<java.lang.Float>> repeatedFloatExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        41,
-        com.google.protobuf.WireFormat.FieldType.FLOAT,
-        false,
-        java.lang.Float.class);
-  public static final int REPEATED_DOUBLE_EXTENSION_LITE_FIELD_NUMBER = 42;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<java.lang.Double>> repeatedDoubleExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        42,
-        com.google.protobuf.WireFormat.FieldType.DOUBLE,
-        false,
-        java.lang.Double.class);
-  public static final int REPEATED_BOOL_EXTENSION_LITE_FIELD_NUMBER = 43;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<java.lang.Boolean>> repeatedBoolExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        43,
-        com.google.protobuf.WireFormat.FieldType.BOOL,
-        false,
-        java.lang.Boolean.class);
-  public static final int REPEATED_STRING_EXTENSION_LITE_FIELD_NUMBER = 44;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<java.lang.String>> repeatedStringExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        44,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        false,
-        java.lang.String.class);
-  public static final int REPEATED_BYTES_EXTENSION_LITE_FIELD_NUMBER = 45;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<com.google.protobuf.ByteString>> repeatedBytesExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        45,
-        com.google.protobuf.WireFormat.FieldType.BYTES,
-        false,
-        com.google.protobuf.ByteString.class);
-  public static final int REPEATEDGROUP_EXTENSION_LITE_FIELD_NUMBER = 46;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite>> repeatedGroupExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite.getDefaultInstance(),
-        null,
-        46,
-        com.google.protobuf.WireFormat.FieldType.GROUP,
-        false,
-        com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite.class);
-  public static final int REPEATED_NESTED_MESSAGE_EXTENSION_LITE_FIELD_NUMBER = 48;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage>> repeatedNestedMessageExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.getDefaultInstance(),
-        null,
-        48,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        false,
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.class);
-  public static final int REPEATED_FOREIGN_MESSAGE_EXTENSION_LITE_FIELD_NUMBER = 49;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<com.google.protobuf.UnittestLite.ForeignMessageLite>> repeatedForeignMessageExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.ForeignMessageLite.getDefaultInstance(),
-        null,
-        49,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        false,
-        com.google.protobuf.UnittestLite.ForeignMessageLite.class);
-  public static final int REPEATED_IMPORT_MESSAGE_EXTENSION_LITE_FIELD_NUMBER = 50;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<com.google.protobuf.UnittestImportLite.ImportMessageLite>> repeatedImportMessageExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.UnittestImportLite.ImportMessageLite.getDefaultInstance(),
-        null,
-        50,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        false,
-        com.google.protobuf.UnittestImportLite.ImportMessageLite.class);
-  public static final int REPEATED_NESTED_ENUM_EXTENSION_LITE_FIELD_NUMBER = 51;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum>> repeatedNestedEnumExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum.internalGetValueMap(),
-        51,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        false,
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum.class);
-  public static final int REPEATED_FOREIGN_ENUM_EXTENSION_LITE_FIELD_NUMBER = 52;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<com.google.protobuf.UnittestLite.ForeignEnumLite>> repeatedForeignEnumExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        com.google.protobuf.UnittestLite.ForeignEnumLite.internalGetValueMap(),
-        52,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        false,
-        com.google.protobuf.UnittestLite.ForeignEnumLite.class);
-  public static final int REPEATED_IMPORT_ENUM_EXTENSION_LITE_FIELD_NUMBER = 53;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<com.google.protobuf.UnittestImportLite.ImportEnumLite>> repeatedImportEnumExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        com.google.protobuf.UnittestImportLite.ImportEnumLite.internalGetValueMap(),
-        53,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        false,
-        com.google.protobuf.UnittestImportLite.ImportEnumLite.class);
-  public static final int REPEATED_STRING_PIECE_EXTENSION_LITE_FIELD_NUMBER = 54;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<java.lang.String>> repeatedStringPieceExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        54,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        false,
-        java.lang.String.class);
-  public static final int REPEATED_CORD_EXTENSION_LITE_FIELD_NUMBER = 55;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<java.lang.String>> repeatedCordExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        55,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        false,
-        java.lang.String.class);
-  public static final int REPEATED_LAZY_MESSAGE_EXTENSION_LITE_FIELD_NUMBER = 57;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.util.List<com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage>> repeatedLazyMessageExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.getDefaultInstance(),
-        null,
-        57,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        false,
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.class);
-  public static final int DEFAULT_INT32_EXTENSION_LITE_FIELD_NUMBER = 61;
-  /**
-   * <pre>
-   * Singular with defaults
-   * </pre>
-   *
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Integer> defaultInt32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        41,
-        null,
-        null,
-        61,
-        com.google.protobuf.WireFormat.FieldType.INT32,
-        java.lang.Integer.class);
-  public static final int DEFAULT_INT64_EXTENSION_LITE_FIELD_NUMBER = 62;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Long> defaultInt64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        42L,
-        null,
-        null,
-        62,
-        com.google.protobuf.WireFormat.FieldType.INT64,
-        java.lang.Long.class);
-  public static final int DEFAULT_UINT32_EXTENSION_LITE_FIELD_NUMBER = 63;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Integer> defaultUint32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        43,
-        null,
-        null,
-        63,
-        com.google.protobuf.WireFormat.FieldType.UINT32,
-        java.lang.Integer.class);
-  public static final int DEFAULT_UINT64_EXTENSION_LITE_FIELD_NUMBER = 64;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Long> defaultUint64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        44L,
-        null,
-        null,
-        64,
-        com.google.protobuf.WireFormat.FieldType.UINT64,
-        java.lang.Long.class);
-  public static final int DEFAULT_SINT32_EXTENSION_LITE_FIELD_NUMBER = 65;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Integer> defaultSint32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        -45,
-        null,
-        null,
-        65,
-        com.google.protobuf.WireFormat.FieldType.SINT32,
-        java.lang.Integer.class);
-  public static final int DEFAULT_SINT64_EXTENSION_LITE_FIELD_NUMBER = 66;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Long> defaultSint64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        46L,
-        null,
-        null,
-        66,
-        com.google.protobuf.WireFormat.FieldType.SINT64,
-        java.lang.Long.class);
-  public static final int DEFAULT_FIXED32_EXTENSION_LITE_FIELD_NUMBER = 67;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Integer> defaultFixed32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        47,
-        null,
-        null,
-        67,
-        com.google.protobuf.WireFormat.FieldType.FIXED32,
-        java.lang.Integer.class);
-  public static final int DEFAULT_FIXED64_EXTENSION_LITE_FIELD_NUMBER = 68;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Long> defaultFixed64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        48L,
-        null,
-        null,
-        68,
-        com.google.protobuf.WireFormat.FieldType.FIXED64,
-        java.lang.Long.class);
-  public static final int DEFAULT_SFIXED32_EXTENSION_LITE_FIELD_NUMBER = 69;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Integer> defaultSfixed32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        49,
-        null,
-        null,
-        69,
-        com.google.protobuf.WireFormat.FieldType.SFIXED32,
-        java.lang.Integer.class);
-  public static final int DEFAULT_SFIXED64_EXTENSION_LITE_FIELD_NUMBER = 70;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Long> defaultSfixed64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        -50L,
-        null,
-        null,
-        70,
-        com.google.protobuf.WireFormat.FieldType.SFIXED64,
-        java.lang.Long.class);
-  public static final int DEFAULT_FLOAT_EXTENSION_LITE_FIELD_NUMBER = 71;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Float> defaultFloatExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        51.5F,
-        null,
-        null,
-        71,
-        com.google.protobuf.WireFormat.FieldType.FLOAT,
-        java.lang.Float.class);
-  public static final int DEFAULT_DOUBLE_EXTENSION_LITE_FIELD_NUMBER = 72;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Double> defaultDoubleExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        52000D,
-        null,
-        null,
-        72,
-        com.google.protobuf.WireFormat.FieldType.DOUBLE,
-        java.lang.Double.class);
-  public static final int DEFAULT_BOOL_EXTENSION_LITE_FIELD_NUMBER = 73;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Boolean> defaultBoolExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        true,
-        null,
-        null,
-        73,
-        com.google.protobuf.WireFormat.FieldType.BOOL,
-        java.lang.Boolean.class);
-  public static final int DEFAULT_STRING_EXTENSION_LITE_FIELD_NUMBER = 74;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.String> defaultStringExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        "hello",
-        null,
-        null,
-        74,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        java.lang.String.class);
-  public static final int DEFAULT_BYTES_EXTENSION_LITE_FIELD_NUMBER = 75;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      com.google.protobuf.ByteString> defaultBytesExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.Internal.bytesDefaultValue("world"),
-        null,
-        null,
-        75,
-        com.google.protobuf.WireFormat.FieldType.BYTES,
-        com.google.protobuf.ByteString.class);
-  public static final int DEFAULT_NESTED_ENUM_EXTENSION_LITE_FIELD_NUMBER = 81;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum> defaultNestedEnumExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum.BAR,
-        null,
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum.internalGetValueMap(),
-        81,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum.class);
-  public static final int DEFAULT_FOREIGN_ENUM_EXTENSION_LITE_FIELD_NUMBER = 82;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      com.google.protobuf.UnittestLite.ForeignEnumLite> defaultForeignEnumExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.ForeignEnumLite.FOREIGN_LITE_BAR,
-        null,
-        com.google.protobuf.UnittestLite.ForeignEnumLite.internalGetValueMap(),
-        82,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        com.google.protobuf.UnittestLite.ForeignEnumLite.class);
-  public static final int DEFAULT_IMPORT_ENUM_EXTENSION_LITE_FIELD_NUMBER = 83;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      com.google.protobuf.UnittestImportLite.ImportEnumLite> defaultImportEnumExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.UnittestImportLite.ImportEnumLite.IMPORT_LITE_BAR,
-        null,
-        com.google.protobuf.UnittestImportLite.ImportEnumLite.internalGetValueMap(),
-        83,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        com.google.protobuf.UnittestImportLite.ImportEnumLite.class);
-  public static final int DEFAULT_STRING_PIECE_EXTENSION_LITE_FIELD_NUMBER = 84;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.String> defaultStringPieceExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        "abc",
-        null,
-        null,
-        84,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        java.lang.String.class);
-  public static final int DEFAULT_CORD_EXTENSION_LITE_FIELD_NUMBER = 85;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.String> defaultCordExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        "123",
-        null,
-        null,
-        85,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        java.lang.String.class);
-  public static final int ONEOF_UINT32_EXTENSION_LITE_FIELD_NUMBER = 111;
-  /**
-   * <pre>
-   * For oneof test
-   * </pre>
-   *
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.Integer> oneofUint32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        0,
-        null,
-        null,
-        111,
-        com.google.protobuf.WireFormat.FieldType.UINT32,
-        java.lang.Integer.class);
-  public static final int ONEOF_NESTED_MESSAGE_EXTENSION_LITE_FIELD_NUMBER = 112;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage> oneofNestedMessageExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.getDefaultInstance(),
-        null,
-        112,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage.class);
-  public static final int ONEOF_STRING_EXTENSION_LITE_FIELD_NUMBER = 113;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      java.lang.String> oneofStringExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        "",
-        null,
-        null,
-        113,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        java.lang.String.class);
-  public static final int ONEOF_BYTES_EXTENSION_LITE_FIELD_NUMBER = 114;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestAllExtensionsLite,
-      com.google.protobuf.ByteString> oneofBytesExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestAllExtensionsLite.getDefaultInstance(),
-        com.google.protobuf.ByteString.EMPTY,
-        null,
-        null,
-        114,
-        com.google.protobuf.WireFormat.FieldType.BYTES,
-        com.google.protobuf.ByteString.class);
-  public static final int PACKED_INT32_EXTENSION_LITE_FIELD_NUMBER = 90;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestPackedExtensionsLite,
-      java.util.List<java.lang.Integer>> packedInt32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestPackedExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        90,
-        com.google.protobuf.WireFormat.FieldType.INT32,
-        true,
-        java.lang.Integer.class);
-  public static final int PACKED_INT64_EXTENSION_LITE_FIELD_NUMBER = 91;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestPackedExtensionsLite,
-      java.util.List<java.lang.Long>> packedInt64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestPackedExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        91,
-        com.google.protobuf.WireFormat.FieldType.INT64,
-        true,
-        java.lang.Long.class);
-  public static final int PACKED_UINT32_EXTENSION_LITE_FIELD_NUMBER = 92;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestPackedExtensionsLite,
-      java.util.List<java.lang.Integer>> packedUint32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestPackedExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        92,
-        com.google.protobuf.WireFormat.FieldType.UINT32,
-        true,
-        java.lang.Integer.class);
-  public static final int PACKED_UINT64_EXTENSION_LITE_FIELD_NUMBER = 93;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestPackedExtensionsLite,
-      java.util.List<java.lang.Long>> packedUint64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestPackedExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        93,
-        com.google.protobuf.WireFormat.FieldType.UINT64,
-        true,
-        java.lang.Long.class);
-  public static final int PACKED_SINT32_EXTENSION_LITE_FIELD_NUMBER = 94;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestPackedExtensionsLite,
-      java.util.List<java.lang.Integer>> packedSint32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestPackedExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        94,
-        com.google.protobuf.WireFormat.FieldType.SINT32,
-        true,
-        java.lang.Integer.class);
-  public static final int PACKED_SINT64_EXTENSION_LITE_FIELD_NUMBER = 95;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestPackedExtensionsLite,
-      java.util.List<java.lang.Long>> packedSint64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestPackedExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        95,
-        com.google.protobuf.WireFormat.FieldType.SINT64,
-        true,
-        java.lang.Long.class);
-  public static final int PACKED_FIXED32_EXTENSION_LITE_FIELD_NUMBER = 96;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestPackedExtensionsLite,
-      java.util.List<java.lang.Integer>> packedFixed32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestPackedExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        96,
-        com.google.protobuf.WireFormat.FieldType.FIXED32,
-        true,
-        java.lang.Integer.class);
-  public static final int PACKED_FIXED64_EXTENSION_LITE_FIELD_NUMBER = 97;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestPackedExtensionsLite,
-      java.util.List<java.lang.Long>> packedFixed64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestPackedExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        97,
-        com.google.protobuf.WireFormat.FieldType.FIXED64,
-        true,
-        java.lang.Long.class);
-  public static final int PACKED_SFIXED32_EXTENSION_LITE_FIELD_NUMBER = 98;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestPackedExtensionsLite,
-      java.util.List<java.lang.Integer>> packedSfixed32ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestPackedExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        98,
-        com.google.protobuf.WireFormat.FieldType.SFIXED32,
-        true,
-        java.lang.Integer.class);
-  public static final int PACKED_SFIXED64_EXTENSION_LITE_FIELD_NUMBER = 99;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestPackedExtensionsLite,
-      java.util.List<java.lang.Long>> packedSfixed64ExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestPackedExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        99,
-        com.google.protobuf.WireFormat.FieldType.SFIXED64,
-        true,
-        java.lang.Long.class);
-  public static final int PACKED_FLOAT_EXTENSION_LITE_FIELD_NUMBER = 100;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestPackedExtensionsLite,
-      java.util.List<java.lang.Float>> packedFloatExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestPackedExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        100,
-        com.google.protobuf.WireFormat.FieldType.FLOAT,
-        true,
-        java.lang.Float.class);
-  public static final int PACKED_DOUBLE_EXTENSION_LITE_FIELD_NUMBER = 101;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestPackedExtensionsLite,
-      java.util.List<java.lang.Double>> packedDoubleExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestPackedExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        101,
-        com.google.protobuf.WireFormat.FieldType.DOUBLE,
-        true,
-        java.lang.Double.class);
-  public static final int PACKED_BOOL_EXTENSION_LITE_FIELD_NUMBER = 102;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestPackedExtensionsLite,
-      java.util.List<java.lang.Boolean>> packedBoolExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestPackedExtensionsLite.getDefaultInstance(),
-        null,
-        null,
-        102,
-        com.google.protobuf.WireFormat.FieldType.BOOL,
-        true,
-        java.lang.Boolean.class);
-  public static final int PACKED_ENUM_EXTENSION_LITE_FIELD_NUMBER = 103;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensionsLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestPackedExtensionsLite,
-      java.util.List<com.google.protobuf.UnittestLite.ForeignEnumLite>> packedEnumExtensionLite = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestPackedExtensionsLite.getDefaultInstance(),
-        null,
-        com.google.protobuf.UnittestLite.ForeignEnumLite.internalGetValueMap(),
-        103,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        true,
-        com.google.protobuf.UnittestLite.ForeignEnumLite.class);
-  public static final int TEST_ALL_TYPES_LITE_FIELD_NUMBER = 536860000;
-  /**
-   * <code>extend .protobuf_unittest.TestHugeFieldNumbersLite { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite,
-      com.google.protobuf.UnittestLite.TestAllTypesLite> testAllTypesLite = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        com.google.protobuf.UnittestLite.TestHugeFieldNumbersLite.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance(),
-        com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance(),
-        null,
-        536860000,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        com.google.protobuf.UnittestLite.TestAllTypesLite.class);
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/UnittestLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/UnittestLiteKt.kt
deleted file mode 100644
index e69de29..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/UnittestLiteKt.kt
+++ /dev/null
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/V1MessageLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/V1MessageLiteKt.kt
deleted file mode 100644
index ac356c5..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/V1MessageLiteKt.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun v1MessageLite(block: com.google.protobuf.V1MessageLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.V1MessageLite =
-  com.google.protobuf.V1MessageLiteKt.Dsl._create(com.google.protobuf.UnittestLite.V1MessageLite.newBuilder()).apply { block() }._build()
-object V1MessageLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.V1MessageLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.V1MessageLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.V1MessageLite = _builder.build()
-
-    /**
-     * <code>required int32 int_field = 1;</code>
-     */
-    var intField: kotlin.Int
-      @JvmName("getIntField")
-      get() = _builder.getIntField()
-      @JvmName("setIntField")
-      set(value) {
-        _builder.setIntField(value)
-      }
-    /**
-     * <code>required int32 int_field = 1;</code>
-     */
-    fun clearIntField() {
-      _builder.clearIntField()
-    }
-    /**
-     * <code>required int32 int_field = 1;</code>
-     * @return Whether the intField field is set.
-     */
-    fun hasIntField(): kotlin.Boolean {
-      return _builder.hasIntField()
-    }
-
-    /**
-     * <code>optional .protobuf_unittest.V1EnumLite enum_field = 2 [default = V1_FIRST];</code>
-     */
-    var enumField: com.google.protobuf.UnittestLite.V1EnumLite
-      @JvmName("getEnumField")
-      get() = _builder.getEnumField()
-      @JvmName("setEnumField")
-      set(value) {
-        _builder.setEnumField(value)
-      }
-    /**
-     * <code>optional .protobuf_unittest.V1EnumLite enum_field = 2 [default = V1_FIRST];</code>
-     */
-    fun clearEnumField() {
-      _builder.clearEnumField()
-    }
-    /**
-     * <code>optional .protobuf_unittest.V1EnumLite enum_field = 2 [default = V1_FIRST];</code>
-     * @return Whether the enumField field is set.
-     */
-    fun hasEnumField(): kotlin.Boolean {
-      return _builder.hasEnumField()
-    }
-  }
-}
-inline fun com.google.protobuf.UnittestLite.V1MessageLite.copy(block: com.google.protobuf.V1MessageLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.V1MessageLite =
-  com.google.protobuf.V1MessageLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/V2MessageLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/V2MessageLiteKt.kt
deleted file mode 100644
index f8ffc97..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/V2MessageLiteKt.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_lite.proto
-
-package com.google.protobuf;
-
-@kotlin.jvm.JvmSynthetic
-inline fun v2MessageLite(block: com.google.protobuf.V2MessageLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.V2MessageLite =
-  com.google.protobuf.V2MessageLiteKt.Dsl._create(com.google.protobuf.UnittestLite.V2MessageLite.newBuilder()).apply { block() }._build()
-object V2MessageLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: com.google.protobuf.UnittestLite.V2MessageLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: com.google.protobuf.UnittestLite.V2MessageLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): com.google.protobuf.UnittestLite.V2MessageLite = _builder.build()
-
-    /**
-     * <code>required int32 int_field = 1;</code>
-     */
-    var intField: kotlin.Int
-      @JvmName("getIntField")
-      get() = _builder.getIntField()
-      @JvmName("setIntField")
-      set(value) {
-        _builder.setIntField(value)
-      }
-    /**
-     * <code>required int32 int_field = 1;</code>
-     */
-    fun clearIntField() {
-      _builder.clearIntField()
-    }
-    /**
-     * <code>required int32 int_field = 1;</code>
-     * @return Whether the intField field is set.
-     */
-    fun hasIntField(): kotlin.Boolean {
-      return _builder.hasIntField()
-    }
-
-    /**
-     * <code>optional .protobuf_unittest.V2EnumLite enum_field = 2 [default = V2_FIRST];</code>
-     */
-    var enumField: com.google.protobuf.UnittestLite.V2EnumLite
-      @JvmName("getEnumField")
-      get() = _builder.getEnumField()
-      @JvmName("setEnumField")
-      set(value) {
-        _builder.setEnumField(value)
-      }
-    /**
-     * <code>optional .protobuf_unittest.V2EnumLite enum_field = 2 [default = V2_FIRST];</code>
-     */
-    fun clearEnumField() {
-      _builder.clearEnumField()
-    }
-    /**
-     * <code>optional .protobuf_unittest.V2EnumLite enum_field = 2 [default = V2_FIRST];</code>
-     * @return Whether the enumField field is set.
-     */
-    fun hasEnumField(): kotlin.Boolean {
-      return _builder.hasEnumField()
-    }
-  }
-}
-inline fun com.google.protobuf.UnittestLite.V2MessageLite.copy(block: com.google.protobuf.V2MessageLiteKt.Dsl.() -> Unit): com.google.protobuf.UnittestLite.V2MessageLite =
-  com.google.protobuf.V2MessageLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/test/UnittestImport.java b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/test/UnittestImport.java
deleted file mode 100644
index a3a7748..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/test/UnittestImport.java
+++ /dev/null
@@ -1,472 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/unittest_import.proto
-
-package com.google.protobuf.test;
-
-public final class UnittestImport {
-  private UnittestImport() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-  /**
-   * Protobuf enum {@code protobuf_unittest_import.ImportEnum}
-   */
-  public enum ImportEnum
-      implements com.google.protobuf.Internal.EnumLite {
-    /**
-     * <code>IMPORT_FOO = 7;</code>
-     */
-    IMPORT_FOO(7),
-    /**
-     * <code>IMPORT_BAR = 8;</code>
-     */
-    IMPORT_BAR(8),
-    /**
-     * <code>IMPORT_BAZ = 9;</code>
-     */
-    IMPORT_BAZ(9),
-    ;
-
-    /**
-     * <code>IMPORT_FOO = 7;</code>
-     */
-    public static final int IMPORT_FOO_VALUE = 7;
-    /**
-     * <code>IMPORT_BAR = 8;</code>
-     */
-    public static final int IMPORT_BAR_VALUE = 8;
-    /**
-     * <code>IMPORT_BAZ = 9;</code>
-     */
-    public static final int IMPORT_BAZ_VALUE = 9;
-
-
-    @java.lang.Override
-    public final int getNumber() {
-      return value;
-    }
-
-    /**
-     * @param value The number of the enum to look for.
-     * @return The enum associated with the given number.
-     * @deprecated Use {@link #forNumber(int)} instead.
-     */
-    @java.lang.Deprecated
-    public static ImportEnum valueOf(int value) {
-      return forNumber(value);
-    }
-
-    public static ImportEnum forNumber(int value) {
-      switch (value) {
-        case 7: return IMPORT_FOO;
-        case 8: return IMPORT_BAR;
-        case 9: return IMPORT_BAZ;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<ImportEnum>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        ImportEnum> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<ImportEnum>() {
-            @java.lang.Override
-            public ImportEnum findValueByNumber(int number) {
-              return ImportEnum.forNumber(number);
-            }
-          };
-
-    public static com.google.protobuf.Internal.EnumVerifier 
-        internalGetVerifier() {
-      return ImportEnumVerifier.INSTANCE;
-    }
-
-    private static final class ImportEnumVerifier implements 
-         com.google.protobuf.Internal.EnumVerifier { 
-            static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new ImportEnumVerifier();
-            @java.lang.Override
-            public boolean isInRange(int number) {
-              return ImportEnum.forNumber(number) != null;
-            }
-          };
-
-    private final int value;
-
-    private ImportEnum(int value) {
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:protobuf_unittest_import.ImportEnum)
-  }
-
-  /**
-   * <pre>
-   * To use an enum in a map, it must has the first value as 0.
-   * </pre>
-   *
-   * Protobuf enum {@code protobuf_unittest_import.ImportEnumForMap}
-   */
-  public enum ImportEnumForMap
-      implements com.google.protobuf.Internal.EnumLite {
-    /**
-     * <code>UNKNOWN = 0;</code>
-     */
-    UNKNOWN(0),
-    /**
-     * <code>FOO = 1;</code>
-     */
-    FOO(1),
-    /**
-     * <code>BAR = 2;</code>
-     */
-    BAR(2),
-    ;
-
-    /**
-     * <code>UNKNOWN = 0;</code>
-     */
-    public static final int UNKNOWN_VALUE = 0;
-    /**
-     * <code>FOO = 1;</code>
-     */
-    public static final int FOO_VALUE = 1;
-    /**
-     * <code>BAR = 2;</code>
-     */
-    public static final int BAR_VALUE = 2;
-
-
-    @java.lang.Override
-    public final int getNumber() {
-      return value;
-    }
-
-    /**
-     * @param value The number of the enum to look for.
-     * @return The enum associated with the given number.
-     * @deprecated Use {@link #forNumber(int)} instead.
-     */
-    @java.lang.Deprecated
-    public static ImportEnumForMap valueOf(int value) {
-      return forNumber(value);
-    }
-
-    public static ImportEnumForMap forNumber(int value) {
-      switch (value) {
-        case 0: return UNKNOWN;
-        case 1: return FOO;
-        case 2: return BAR;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<ImportEnumForMap>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        ImportEnumForMap> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<ImportEnumForMap>() {
-            @java.lang.Override
-            public ImportEnumForMap findValueByNumber(int number) {
-              return ImportEnumForMap.forNumber(number);
-            }
-          };
-
-    public static com.google.protobuf.Internal.EnumVerifier 
-        internalGetVerifier() {
-      return ImportEnumForMapVerifier.INSTANCE;
-    }
-
-    private static final class ImportEnumForMapVerifier implements 
-         com.google.protobuf.Internal.EnumVerifier { 
-            static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new ImportEnumForMapVerifier();
-            @java.lang.Override
-            public boolean isInRange(int number) {
-              return ImportEnumForMap.forNumber(number) != null;
-            }
-          };
-
-    private final int value;
-
-    private ImportEnumForMap(int value) {
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:protobuf_unittest_import.ImportEnumForMap)
-  }
-
-  public interface ImportMessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest_import.ImportMessage)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional int32 d = 1;</code>
-     * @return Whether the d field is set.
-     */
-    boolean hasD();
-    /**
-     * <code>optional int32 d = 1;</code>
-     * @return The d.
-     */
-    int getD();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest_import.ImportMessage}
-   */
-  public  static final class ImportMessage extends
-      com.google.protobuf.GeneratedMessageLite<
-          ImportMessage, ImportMessage.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest_import.ImportMessage)
-      ImportMessageOrBuilder {
-    private ImportMessage() {
-    }
-    private int bitField0_;
-    public static final int D_FIELD_NUMBER = 1;
-    private int d_;
-    /**
-     * <code>optional int32 d = 1;</code>
-     * @return Whether the d field is set.
-     */
-    @java.lang.Override
-    public boolean hasD() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 d = 1;</code>
-     * @return The d.
-     */
-    @java.lang.Override
-    public int getD() {
-      return d_;
-    }
-    /**
-     * <code>optional int32 d = 1;</code>
-     * @param value The d to set.
-     */
-    private void setD(int value) {
-      bitField0_ |= 0x00000001;
-      d_ = value;
-    }
-    /**
-     * <code>optional int32 d = 1;</code>
-     */
-    private void clearD() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      d_ = 0;
-    }
-
-    public static com.google.protobuf.test.UnittestImport.ImportMessage parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.test.UnittestImport.ImportMessage parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.test.UnittestImport.ImportMessage parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.test.UnittestImport.ImportMessage parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.test.UnittestImport.ImportMessage parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.test.UnittestImport.ImportMessage parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.test.UnittestImport.ImportMessage parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.test.UnittestImport.ImportMessage parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.test.UnittestImport.ImportMessage parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.test.UnittestImport.ImportMessage parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.test.UnittestImport.ImportMessage parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.test.UnittestImport.ImportMessage parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.test.UnittestImport.ImportMessage prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest_import.ImportMessage}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.test.UnittestImport.ImportMessage, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest_import.ImportMessage)
-        com.google.protobuf.test.UnittestImport.ImportMessageOrBuilder {
-      // Construct using com.google.protobuf.test.UnittestImport.ImportMessage.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int32 d = 1;</code>
-       * @return Whether the d field is set.
-       */
-      @java.lang.Override
-      public boolean hasD() {
-        return instance.hasD();
-      }
-      /**
-       * <code>optional int32 d = 1;</code>
-       * @return The d.
-       */
-      @java.lang.Override
-      public int getD() {
-        return instance.getD();
-      }
-      /**
-       * <code>optional int32 d = 1;</code>
-       * @param value The d to set.
-       * @return This builder for chaining.
-       */
-      public Builder setD(int value) {
-        copyOnWrite();
-        instance.setD(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 d = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearD() {
-        copyOnWrite();
-        instance.clearD();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest_import.ImportMessage)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.test.UnittestImport.ImportMessage();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "d_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1004\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.test.UnittestImport.ImportMessage> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.test.UnittestImport.ImportMessage.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.test.UnittestImport.ImportMessage>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest_import.ImportMessage)
-    private static final com.google.protobuf.test.UnittestImport.ImportMessage DEFAULT_INSTANCE;
-    static {
-      ImportMessage defaultInstance = new ImportMessage();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        ImportMessage.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.test.UnittestImport.ImportMessage getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<ImportMessage> PARSER;
-
-    public static com.google.protobuf.Parser<ImportMessage> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/test/UnittestImportPublic.java b/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/test/UnittestImportPublic.java
deleted file mode 100644
index eee1699..0000000
--- a/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/test/UnittestImportPublic.java
+++ /dev/null
@@ -1,282 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/unittest_import_public.proto
-
-package com.google.protobuf.test;
-
-public final class UnittestImportPublic {
-  private UnittestImportPublic() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-  public interface PublicImportMessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest_import.PublicImportMessage)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional int32 e = 1;</code>
-     * @return Whether the e field is set.
-     */
-    boolean hasE();
-    /**
-     * <code>optional int32 e = 1;</code>
-     * @return The e.
-     */
-    int getE();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest_import.PublicImportMessage}
-   */
-  public  static final class PublicImportMessage extends
-      com.google.protobuf.GeneratedMessageLite<
-          PublicImportMessage, PublicImportMessage.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest_import.PublicImportMessage)
-      PublicImportMessageOrBuilder {
-    private PublicImportMessage() {
-    }
-    private int bitField0_;
-    public static final int E_FIELD_NUMBER = 1;
-    private int e_;
-    /**
-     * <code>optional int32 e = 1;</code>
-     * @return Whether the e field is set.
-     */
-    @java.lang.Override
-    public boolean hasE() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 e = 1;</code>
-     * @return The e.
-     */
-    @java.lang.Override
-    public int getE() {
-      return e_;
-    }
-    /**
-     * <code>optional int32 e = 1;</code>
-     * @param value The e to set.
-     */
-    private void setE(int value) {
-      bitField0_ |= 0x00000001;
-      e_ = value;
-    }
-    /**
-     * <code>optional int32 e = 1;</code>
-     */
-    private void clearE() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      e_ = 0;
-    }
-
-    public static com.google.protobuf.test.UnittestImportPublic.PublicImportMessage parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.test.UnittestImportPublic.PublicImportMessage parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.test.UnittestImportPublic.PublicImportMessage parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.test.UnittestImportPublic.PublicImportMessage parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.test.UnittestImportPublic.PublicImportMessage parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static com.google.protobuf.test.UnittestImportPublic.PublicImportMessage parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static com.google.protobuf.test.UnittestImportPublic.PublicImportMessage parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.test.UnittestImportPublic.PublicImportMessage parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.test.UnittestImportPublic.PublicImportMessage parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.test.UnittestImportPublic.PublicImportMessage parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static com.google.protobuf.test.UnittestImportPublic.PublicImportMessage parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static com.google.protobuf.test.UnittestImportPublic.PublicImportMessage parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(com.google.protobuf.test.UnittestImportPublic.PublicImportMessage prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest_import.PublicImportMessage}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          com.google.protobuf.test.UnittestImportPublic.PublicImportMessage, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest_import.PublicImportMessage)
-        com.google.protobuf.test.UnittestImportPublic.PublicImportMessageOrBuilder {
-      // Construct using com.google.protobuf.test.UnittestImportPublic.PublicImportMessage.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int32 e = 1;</code>
-       * @return Whether the e field is set.
-       */
-      @java.lang.Override
-      public boolean hasE() {
-        return instance.hasE();
-      }
-      /**
-       * <code>optional int32 e = 1;</code>
-       * @return The e.
-       */
-      @java.lang.Override
-      public int getE() {
-        return instance.getE();
-      }
-      /**
-       * <code>optional int32 e = 1;</code>
-       * @param value The e to set.
-       * @return This builder for chaining.
-       */
-      public Builder setE(int value) {
-        copyOnWrite();
-        instance.setE(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 e = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearE() {
-        copyOnWrite();
-        instance.clearE();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest_import.PublicImportMessage)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new com.google.protobuf.test.UnittestImportPublic.PublicImportMessage();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "e_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1004\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<com.google.protobuf.test.UnittestImportPublic.PublicImportMessage> parser = PARSER;
-          if (parser == null) {
-            synchronized (com.google.protobuf.test.UnittestImportPublic.PublicImportMessage.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<com.google.protobuf.test.UnittestImportPublic.PublicImportMessage>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest_import.PublicImportMessage)
-    private static final com.google.protobuf.test.UnittestImportPublic.PublicImportMessage DEFAULT_INSTANCE;
-    static {
-      PublicImportMessage defaultInstance = new PublicImportMessage();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        PublicImportMessage.class, defaultInstance);
-    }
-
-    public static com.google.protobuf.test.UnittestImportPublic.PublicImportMessage getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<PublicImportMessage> PARSER;
-
-    public static com.google.protobuf.Parser<PublicImportMessage> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/evil_names_proto2/EvilNamesProto2Kt.kt b/java/kotlin-lite/target/generated-test-sources/evil_names_proto2/EvilNamesProto2Kt.kt
deleted file mode 100644
index b83f366..0000000
--- a/java/kotlin-lite/target/generated-test-sources/evil_names_proto2/EvilNamesProto2Kt.kt
+++ /dev/null
@@ -1,816 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: com/google/protobuf/evil_names_proto2.proto
-
-package evil_names_proto2;
-
-@kotlin.jvm.JvmSynthetic
-inline fun evilNamesProto2(block: evil_names_proto2.EvilNamesProto2Kt.Dsl.() -> Unit): evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2 =
-  evil_names_proto2.EvilNamesProto2Kt.Dsl._create(evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2.newBuilder()).apply { block() }._build()
-object EvilNamesProto2Kt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2 = _builder.build()
-
-    /**
-     * <code>optional bool initialized = 1;</code>
-     */
-    var initialized: kotlin.Boolean
-      @JvmName("getInitialized")
-      get() = _builder.getInitialized()
-      @JvmName("setInitialized")
-      set(value) {
-        _builder.setInitialized(value)
-      }
-    /**
-     * <code>optional bool initialized = 1;</code>
-     */
-    fun clearInitialized() {
-      _builder.clearInitialized()
-    }
-    /**
-     * <code>optional bool initialized = 1;</code>
-     * @return Whether the initialized field is set.
-     */
-    fun hasInitialized(): kotlin.Boolean {
-      return _builder.hasInitialized()
-    }
-
-    /**
-     * <code>optional bool has_foo = 2;</code>
-     */
-    var hasFoo: kotlin.Boolean
-      @JvmName("getHasFoo")
-      get() = _builder.getHasFoo()
-      @JvmName("setHasFoo")
-      set(value) {
-        _builder.setHasFoo(value)
-      }
-    /**
-     * <code>optional bool has_foo = 2;</code>
-     */
-    fun clearHasFoo() {
-      _builder.clearHasFoo()
-    }
-    /**
-     * <code>optional bool has_foo = 2;</code>
-     * @return Whether the hasFoo field is set.
-     */
-    fun hasHasFoo(): kotlin.Boolean {
-      return _builder.hasHasFoo()
-    }
-
-    /**
-     * <code>optional string Bar = 3;</code>
-     */
-    var bar: kotlin.String
-      @JvmName("getBar")
-      get() = _builder.getBar()
-      @JvmName("setBar")
-      set(value) {
-        _builder.setBar(value)
-      }
-    /**
-     * <code>optional string Bar = 3;</code>
-     */
-    fun clearBar() {
-      _builder.clearBar()
-    }
-    /**
-     * <code>optional string Bar = 3;</code>
-     * @return Whether the bar field is set.
-     */
-    fun hasBar(): kotlin.Boolean {
-      return _builder.hasBar()
-    }
-
-    /**
-     * <code>optional bool is_initialized = 4;</code>
-     */
-    var isInitialized: kotlin.Boolean
-      @JvmName("getIsInitialized")
-      get() = _builder.getIsInitialized()
-      @JvmName("setIsInitialized")
-      set(value) {
-        _builder.setIsInitialized(value)
-      }
-    /**
-     * <code>optional bool is_initialized = 4;</code>
-     */
-    fun clearIsInitialized() {
-      _builder.clearIsInitialized()
-    }
-    /**
-     * <code>optional bool is_initialized = 4;</code>
-     * @return Whether the isInitialized field is set.
-     */
-    fun hasIsInitialized(): kotlin.Boolean {
-      return _builder.hasIsInitialized()
-    }
-
-    /**
-     * <code>string fooBar = 5;</code>
-     */
-    var fooBar: kotlin.String
-      @JvmName("getFooBar")
-      get() = _builder.getFooBar()
-      @JvmName("setFooBar")
-      set(value) {
-        _builder.setFooBar(value)
-      }
-    /**
-     * <code>string fooBar = 5;</code>
-     */
-    fun clearFooBar() {
-      _builder.clearFooBar()
-    }
-    /**
-     * <code>string fooBar = 5;</code>
-     * @return Whether the fooBar field is set.
-     */
-    fun hasFooBar(): kotlin.Boolean {
-      return _builder.hasFooBar()
-    }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class ALLCAPSProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @return A list containing the aLLCAPS.
-     */
-    val aLLCAPS: com.google.protobuf.kotlin.DslList<kotlin.String, ALLCAPSProxy>
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getALLCAPSList()
-      )
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param value The aLLCAPS to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addALLCAPS")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, ALLCAPSProxy>.add(value: kotlin.String) {
-      _builder.addALLCAPS(value)
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param value The aLLCAPS to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignALLCAPS")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, ALLCAPSProxy>.plusAssign(value: kotlin.String) {
-      add(value)
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param values The aLLCAPS to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllALLCAPS")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, ALLCAPSProxy>.addAll(values: kotlin.collections.Iterable<kotlin.String>) {
-      _builder.addAllALLCAPS(values)
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param values The aLLCAPS to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllALLCAPS")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, ALLCAPSProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.String>) {
-      addAll(values)
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param index The index to set the value at.
-     * @param value The aLLCAPS to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setALLCAPS")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.String, ALLCAPSProxy>.set(index: kotlin.Int, value: kotlin.String) {
-      _builder.setALLCAPS(index, value)
-    }/**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearALLCAPS")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, ALLCAPSProxy>.clear() {
-      _builder.clearALLCAPS()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class ALLCAPSMAPProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-     val aLLCAPSMAP: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Boolean, ALLCAPSMAPProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getALLCAPSMAPMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getALLCAPSMAPMap()
-      )
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    @JvmName("putALLCAPSMAP")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Boolean, ALLCAPSMAPProxy>
-      .put(key: kotlin.Int, value: kotlin.Boolean) {
-         _builder.putALLCAPSMAP(key, value)
-       }
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setALLCAPSMAP")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Boolean, ALLCAPSMAPProxy>
-      .set(key: kotlin.Int, value: kotlin.Boolean) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeALLCAPSMAP")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Boolean, ALLCAPSMAPProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeALLCAPSMAP(key)
-       }
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllALLCAPSMAP")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Boolean, ALLCAPSMAPProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Boolean>) {
-         _builder.putAllALLCAPSMAP(map)
-       }
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearALLCAPSMAP")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Boolean, ALLCAPSMAPProxy>
-      .clear() {
-         _builder.clearALLCAPSMAP()
-       }
-
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_1foo = 9;</code>
-     */
-    var hasUnderbarPrecedingNumeric1Foo: kotlin.Boolean
-      @JvmName("getHasUnderbarPrecedingNumeric1Foo")
-      get() = _builder.getHasUnderbarPrecedingNumeric1Foo()
-      @JvmName("setHasUnderbarPrecedingNumeric1Foo")
-      set(value) {
-        _builder.setHasUnderbarPrecedingNumeric1Foo(value)
-      }
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_1foo = 9;</code>
-     */
-    fun clearHasUnderbarPrecedingNumeric1Foo() {
-      _builder.clearHasUnderbarPrecedingNumeric1Foo()
-    }
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_1foo = 9;</code>
-     * @return Whether the hasUnderbarPrecedingNumeric1foo field is set.
-     */
-    fun hasHasUnderbarPrecedingNumeric1Foo(): kotlin.Boolean {
-      return _builder.hasHasUnderbarPrecedingNumeric1Foo()
-    }
-
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_42bar = 13;</code>
-     */
-    var hasUnderbarPrecedingNumeric42Bar: kotlin.Boolean
-      @JvmName("getHasUnderbarPrecedingNumeric42Bar")
-      get() = _builder.getHasUnderbarPrecedingNumeric42Bar()
-      @JvmName("setHasUnderbarPrecedingNumeric42Bar")
-      set(value) {
-        _builder.setHasUnderbarPrecedingNumeric42Bar(value)
-      }
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_42bar = 13;</code>
-     */
-    fun clearHasUnderbarPrecedingNumeric42Bar() {
-      _builder.clearHasUnderbarPrecedingNumeric42Bar()
-    }
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_42bar = 13;</code>
-     * @return Whether the hasUnderbarPrecedingNumeric42bar field is set.
-     */
-    fun hasHasUnderbarPrecedingNumeric42Bar(): kotlin.Boolean {
-      return _builder.hasHasUnderbarPrecedingNumeric42Bar()
-    }
-
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_123foo42bar_baz = 14;</code>
-     */
-    var hasUnderbarPrecedingNumeric123Foo42BarBaz: kotlin.Boolean
-      @JvmName("getHasUnderbarPrecedingNumeric123Foo42BarBaz")
-      get() = _builder.getHasUnderbarPrecedingNumeric123Foo42BarBaz()
-      @JvmName("setHasUnderbarPrecedingNumeric123Foo42BarBaz")
-      set(value) {
-        _builder.setHasUnderbarPrecedingNumeric123Foo42BarBaz(value)
-      }
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_123foo42bar_baz = 14;</code>
-     */
-    fun clearHasUnderbarPrecedingNumeric123Foo42BarBaz() {
-      _builder.clearHasUnderbarPrecedingNumeric123Foo42BarBaz()
-    }
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_123foo42bar_baz = 14;</code>
-     * @return Whether the hasUnderbarPrecedingNumeric123foo42barBaz field is set.
-     */
-    fun hasHasUnderbarPrecedingNumeric123Foo42BarBaz(): kotlin.Boolean {
-      return _builder.hasHasUnderbarPrecedingNumeric123Foo42BarBaz()
-    }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class ExtensionProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @return A list containing the extension.
-     */
-    val extension: com.google.protobuf.kotlin.DslList<kotlin.String, ExtensionProxy>
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getExtensionList()
-      )
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param value The extension to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addExtension")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, ExtensionProxy>.add(value: kotlin.String) {
-      _builder.addExtension(value)
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param value The extension to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignExtension")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, ExtensionProxy>.plusAssign(value: kotlin.String) {
-      add(value)
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param values The extension to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllExtension")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, ExtensionProxy>.addAll(values: kotlin.collections.Iterable<kotlin.String>) {
-      _builder.addAllExtension(values)
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param values The extension to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllExtension")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, ExtensionProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.String>) {
-      addAll(values)
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param index The index to set the value at.
-     * @param value The extension to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setExtension")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.String, ExtensionProxy>.set(index: kotlin.Int, value: kotlin.String) {
-      _builder.setExtension(index, value)
-    }/**
-     * <code>repeated string extension = 12;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearExtension")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, ExtensionProxy>.clear() {
-      _builder.clearExtension()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class Class_Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated int32 class = 15;</code>
-     */
-     val class_: com.google.protobuf.kotlin.DslList<kotlin.Int, Class_Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getClass_List()
-      )
-    /**
-     * <code>repeated int32 class = 15;</code>
-     * @param value The class to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addClass_")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, Class_Proxy>.add(value: kotlin.Int) {
-      _builder.addClass_(value)
-    }/**
-     * <code>repeated int32 class = 15;</code>
-     * @param value The class to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignClass_")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, Class_Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated int32 class = 15;</code>
-     * @param values The class to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllClass_")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, Class_Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllClass_(values)
-    }/**
-     * <code>repeated int32 class = 15;</code>
-     * @param values The class to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllClass_")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, Class_Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated int32 class = 15;</code>
-     * @param index The index to set the value at.
-     * @param value The class to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setClass_")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, Class_Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setClass_(index, value)
-    }/**
-     * <code>repeated int32 class = 15;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearClass_")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, Class_Proxy>.clear() {
-      _builder.clearClass_()
-    }
-    /**
-     * <code>optional double int = 16;</code>
-     */
-    var int: kotlin.Double
-      @JvmName("getInt")
-      get() = _builder.getInt()
-      @JvmName("setInt")
-      set(value) {
-        _builder.setInt(value)
-      }
-    /**
-     * <code>optional double int = 16;</code>
-     */
-    fun clearInt() {
-      _builder.clearInt()
-    }
-    /**
-     * <code>optional double int = 16;</code>
-     * @return Whether the int field is set.
-     */
-    fun hasInt(): kotlin.Boolean {
-      return _builder.hasInt()
-    }
-
-    /**
-     * <code>optional bool long = 17;</code>
-     */
-    var long: kotlin.Boolean
-      @JvmName("getLong")
-      get() = _builder.getLong()
-      @JvmName("setLong")
-      set(value) {
-        _builder.setLong(value)
-      }
-    /**
-     * <code>optional bool long = 17;</code>
-     */
-    fun clearLong() {
-      _builder.clearLong()
-    }
-    /**
-     * <code>optional bool long = 17;</code>
-     * @return Whether the long field is set.
-     */
-    fun hasLong(): kotlin.Boolean {
-      return _builder.hasLong()
-    }
-
-    /**
-     * <code>optional int64 boolean = 18;</code>
-     */
-    var boolean: kotlin.Long
-      @JvmName("getBoolean")
-      get() = _builder.getBoolean()
-      @JvmName("setBoolean")
-      set(value) {
-        _builder.setBoolean(value)
-      }
-    /**
-     * <code>optional int64 boolean = 18;</code>
-     */
-    fun clearBoolean() {
-      _builder.clearBoolean()
-    }
-    /**
-     * <code>optional int64 boolean = 18;</code>
-     * @return Whether the boolean field is set.
-     */
-    fun hasBoolean(): kotlin.Boolean {
-      return _builder.hasBoolean()
-    }
-
-    /**
-     * <code>optional string sealed = 19;</code>
-     */
-    var sealed: kotlin.String
-      @JvmName("getSealed")
-      get() = _builder.getSealed()
-      @JvmName("setSealed")
-      set(value) {
-        _builder.setSealed(value)
-      }
-    /**
-     * <code>optional string sealed = 19;</code>
-     */
-    fun clearSealed() {
-      _builder.clearSealed()
-    }
-    /**
-     * <code>optional string sealed = 19;</code>
-     * @return Whether the sealed field is set.
-     */
-    fun hasSealed(): kotlin.Boolean {
-      return _builder.hasSealed()
-    }
-
-    /**
-     * <code>optional float interface = 20;</code>
-     */
-    var interface_: kotlin.Float
-      @JvmName("getInterface_")
-      get() = _builder.getInterface()
-      @JvmName("setInterface_")
-      set(value) {
-        _builder.setInterface(value)
-      }
-    /**
-     * <code>optional float interface = 20;</code>
-     */
-    fun clearInterface_() {
-      _builder.clearInterface()
-    }
-    /**
-     * <code>optional float interface = 20;</code>
-     * @return Whether the interface field is set.
-     */
-    fun hasInterface_(): kotlin.Boolean {
-      return _builder.hasInterface()
-    }
-
-    /**
-     * <code>optional int32 in = 21;</code>
-     */
-    var in_: kotlin.Int
-      @JvmName("getIn_")
-      get() = _builder.getIn()
-      @JvmName("setIn_")
-      set(value) {
-        _builder.setIn(value)
-      }
-    /**
-     * <code>optional int32 in = 21;</code>
-     */
-    fun clearIn_() {
-      _builder.clearIn()
-    }
-    /**
-     * <code>optional int32 in = 21;</code>
-     * @return Whether the in field is set.
-     */
-    fun hasIn_(): kotlin.Boolean {
-      return _builder.hasIn()
-    }
-
-    /**
-     * <code>optional string object = 22;</code>
-     */
-    var object_: kotlin.String
-      @JvmName("getObject_")
-      get() = _builder.getObject()
-      @JvmName("setObject_")
-      set(value) {
-        _builder.setObject(value)
-      }
-    /**
-     * <code>optional string object = 22;</code>
-     */
-    fun clearObject_() {
-      _builder.clearObject()
-    }
-    /**
-     * <code>optional string object = 22;</code>
-     * @return Whether the object field is set.
-     */
-    fun hasObject_(): kotlin.Boolean {
-      return _builder.hasObject()
-    }
-
-    /**
-     * <code>optional string cached_size = 23;</code>
-     */
-    var cachedSize_: kotlin.String
-      @JvmName("getCachedSize_")
-      get() = _builder.getCachedSize_()
-      @JvmName("setCachedSize_")
-      set(value) {
-        _builder.setCachedSize_(value)
-      }
-    /**
-     * <code>optional string cached_size = 23;</code>
-     */
-    fun clearCachedSize_() {
-      _builder.clearCachedSize_()
-    }
-    /**
-     * <code>optional string cached_size = 23;</code>
-     * @return Whether the cachedSize field is set.
-     */
-    fun hasCachedSize_(): kotlin.Boolean {
-      return _builder.hasCachedSize_()
-    }
-
-    /**
-     * <code>optional bool serialized_size = 24;</code>
-     */
-    var serializedSize_: kotlin.Boolean
-      @JvmName("getSerializedSize_")
-      get() = _builder.getSerializedSize_()
-      @JvmName("setSerializedSize_")
-      set(value) {
-        _builder.setSerializedSize_(value)
-      }
-    /**
-     * <code>optional bool serialized_size = 24;</code>
-     */
-    fun clearSerializedSize_() {
-      _builder.clearSerializedSize_()
-    }
-    /**
-     * <code>optional bool serialized_size = 24;</code>
-     * @return Whether the serializedSize field is set.
-     */
-    fun hasSerializedSize_(): kotlin.Boolean {
-      return _builder.hasSerializedSize_()
-    }
-
-    /**
-     * <code>optional string by = 25;</code>
-     */
-    var by: kotlin.String
-      @JvmName("getBy")
-      get() = _builder.getBy()
-      @JvmName("setBy")
-      set(value) {
-        _builder.setBy(value)
-      }
-    /**
-     * <code>optional string by = 25;</code>
-     */
-    fun clearBy() {
-      _builder.clearBy()
-    }
-    /**
-     * <code>optional string by = 25;</code>
-     * @return Whether the by field is set.
-     */
-    fun hasBy(): kotlin.Boolean {
-      return _builder.hasBy()
-    }
-    val camelCaseCase: evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2.CamelCaseCase
-      @JvmName("getCamelCaseCase")
-      get() = _builder.getCamelCaseCase()
-
-    fun clearCamelCase() {
-      _builder.clearCamelCase()
-    }
-    @Suppress("UNCHECKED_CAST")
-    @kotlin.jvm.JvmSynthetic
-    operator fun <T> get(extension: com.google.protobuf.ExtensionLite<evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2, T>): T {
-      return if (extension.isRepeated) {
-        get(extension as com.google.protobuf.ExtensionLite<evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2, List<*>>) as T
-      } else {
-        _builder.getExtension(extension)
-      }
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    @kotlin.jvm.JvmName("-getRepeatedExtension")
-    operator fun <E> get(
-      extension: com.google.protobuf.ExtensionLite<evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2, List<E>>
-    ): com.google.protobuf.kotlin.ExtensionList<E, evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2> {
-      return com.google.protobuf.kotlin.ExtensionList(extension, _builder.getExtension(extension))
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    operator fun contains(extension: com.google.protobuf.ExtensionLite<evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2, *>): Boolean {
-      return _builder.hasExtension(extension)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun clear(extension: com.google.protobuf.ExtensionLite<evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2, *>) {
-      _builder.clearExtension(extension)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun <T> setExtension(extension: com.google.protobuf.ExtensionLite<evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2, T>, value: T) {
-      _builder.setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <T : Comparable<T>> set(
-      extension: com.google.protobuf.ExtensionLite<evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2, T>,
-      value: T
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun set(
-      extension: com.google.protobuf.ExtensionLite<evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2, com.google.protobuf.ByteString>,
-      value: com.google.protobuf.ByteString
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <T : com.google.protobuf.MessageLite> set(
-      extension: com.google.protobuf.ExtensionLite<evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2, T>,
-      value: T
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun <E> com.google.protobuf.kotlin.ExtensionList<E, evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2>.add(value: E) {
-      _builder.addExtension(this.extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2>.plusAssign(value: E) {
-      add(value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun <E> com.google.protobuf.kotlin.ExtensionList<E, evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2>.addAll(values: Iterable<E>) {
-      for (value in values) {
-        add(value)
-      }
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2>.plusAssign(values: Iterable<E>) {
-      addAll(values)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2>.set(index: Int, value: E) {
-      _builder.setExtension(this.extension, index, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline fun com.google.protobuf.kotlin.ExtensionList<*, evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2>.clear() {
-      clear(extension)
-    }
-
-  }
-}
-inline fun evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2.copy(block: evil_names_proto2.EvilNamesProto2Kt.Dsl.() -> Unit): evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2 =
-  evil_names_proto2.EvilNamesProto2Kt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/evil_names_proto2/EvilNamesProto2OuterClass.java b/java/kotlin-lite/target/generated-test-sources/evil_names_proto2/EvilNamesProto2OuterClass.java
deleted file mode 100644
index bb9f25e..0000000
--- a/java/kotlin-lite/target/generated-test-sources/evil_names_proto2/EvilNamesProto2OuterClass.java
+++ /dev/null
@@ -1,4940 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: com/google/protobuf/evil_names_proto2.proto
-
-package evil_names_proto2;
-
-public final class EvilNamesProto2OuterClass {
-  private EvilNamesProto2OuterClass() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-  public interface EvilNamesProto2OrBuilder extends 
-      // @@protoc_insertion_point(interface_extends:evil_names_proto2.EvilNamesProto2)
-       com.google.protobuf.GeneratedMessageLite.
-            ExtendableMessageOrBuilder<
-                EvilNamesProto2, EvilNamesProto2.Builder> {
-
-    /**
-     * <code>optional bool initialized = 1;</code>
-     * @return Whether the initialized field is set.
-     */
-    boolean hasInitialized();
-    /**
-     * <code>optional bool initialized = 1;</code>
-     * @return The initialized.
-     */
-    boolean getInitialized();
-
-    /**
-     * <code>optional bool has_foo = 2;</code>
-     * @return Whether the hasFoo field is set.
-     */
-    boolean hasHasFoo();
-    /**
-     * <code>optional bool has_foo = 2;</code>
-     * @return The hasFoo.
-     */
-    boolean getHasFoo();
-
-    /**
-     * <code>optional string Bar = 3;</code>
-     * @return Whether the bar field is set.
-     */
-    boolean hasBar();
-    /**
-     * <code>optional string Bar = 3;</code>
-     * @return The bar.
-     */
-    java.lang.String getBar();
-    /**
-     * <code>optional string Bar = 3;</code>
-     * @return The bytes for bar.
-     */
-    com.google.protobuf.ByteString
-        getBarBytes();
-
-    /**
-     * <code>optional bool is_initialized = 4;</code>
-     * @return Whether the isInitialized field is set.
-     */
-    boolean hasIsInitialized();
-    /**
-     * <code>optional bool is_initialized = 4;</code>
-     * @return The isInitialized.
-     */
-    boolean getIsInitialized();
-
-    /**
-     * <code>string fooBar = 5;</code>
-     * @return Whether the fooBar field is set.
-     */
-    boolean hasFooBar();
-    /**
-     * <code>string fooBar = 5;</code>
-     * @return The fooBar.
-     */
-    java.lang.String getFooBar();
-    /**
-     * <code>string fooBar = 5;</code>
-     * @return The bytes for fooBar.
-     */
-    com.google.protobuf.ByteString
-        getFooBarBytes();
-
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @return A list containing the aLLCAPS.
-     */
-    java.util.List<java.lang.String>
-        getALLCAPSList();
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @return The count of aLLCAPS.
-     */
-    int getALLCAPSCount();
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param index The index of the element to return.
-     * @return The aLLCAPS at the given index.
-     */
-    java.lang.String getALLCAPS(int index);
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param index The index of the element to return.
-     * @return The aLLCAPS at the given index.
-     */
-    com.google.protobuf.ByteString
-        getALLCAPSBytes(int index);
-
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    int getALLCAPSMAPCount();
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    boolean containsALLCAPSMAP(
-        int key);
-    /**
-     * Use {@link #getALLCAPSMAPMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Boolean>
-    getALLCAPSMAP();
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Boolean>
-    getALLCAPSMAPMap();
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-
-    boolean getALLCAPSMAPOrDefault(
-        int key,
-        boolean defaultValue);
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-
-    boolean getALLCAPSMAPOrThrow(
-        int key);
-
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_1foo = 9;</code>
-     * @return Whether the hasUnderbarPrecedingNumeric1foo field is set.
-     */
-    boolean hasHasUnderbarPrecedingNumeric1Foo();
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_1foo = 9;</code>
-     * @return The hasUnderbarPrecedingNumeric1foo.
-     */
-    boolean getHasUnderbarPrecedingNumeric1Foo();
-
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_42bar = 13;</code>
-     * @return Whether the hasUnderbarPrecedingNumeric42bar field is set.
-     */
-    boolean hasHasUnderbarPrecedingNumeric42Bar();
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_42bar = 13;</code>
-     * @return The hasUnderbarPrecedingNumeric42bar.
-     */
-    boolean getHasUnderbarPrecedingNumeric42Bar();
-
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_123foo42bar_baz = 14;</code>
-     * @return Whether the hasUnderbarPrecedingNumeric123foo42barBaz field is set.
-     */
-    boolean hasHasUnderbarPrecedingNumeric123Foo42BarBaz();
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_123foo42bar_baz = 14;</code>
-     * @return The hasUnderbarPrecedingNumeric123foo42barBaz.
-     */
-    boolean getHasUnderbarPrecedingNumeric123Foo42BarBaz();
-
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @return A list containing the extension.
-     */
-    java.util.List<java.lang.String>
-        getExtensionList();
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @return The count of extension.
-     */
-    int getExtensionCount();
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param index The index of the element to return.
-     * @return The extension at the given index.
-     */
-    java.lang.String getExtension(int index);
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param index The index of the element to return.
-     * @return The extension at the given index.
-     */
-    com.google.protobuf.ByteString
-        getExtensionBytes(int index);
-
-    /**
-     * <code>repeated int32 class = 15;</code>
-     * @return A list containing the class.
-     */
-    java.util.List<java.lang.Integer> getClass_List();
-    /**
-     * <code>repeated int32 class = 15;</code>
-     * @return The count of class.
-     */
-    int getClass_Count();
-    /**
-     * <code>repeated int32 class = 15;</code>
-     * @param index The index of the element to return.
-     * @return The class at the given index.
-     */
-    int getClass_(int index);
-
-    /**
-     * <code>optional double int = 16;</code>
-     * @return Whether the int field is set.
-     */
-    boolean hasInt();
-    /**
-     * <code>optional double int = 16;</code>
-     * @return The int.
-     */
-    double getInt();
-
-    /**
-     * <code>optional bool long = 17;</code>
-     * @return Whether the long field is set.
-     */
-    boolean hasLong();
-    /**
-     * <code>optional bool long = 17;</code>
-     * @return The long.
-     */
-    boolean getLong();
-
-    /**
-     * <code>optional int64 boolean = 18;</code>
-     * @return Whether the boolean field is set.
-     */
-    boolean hasBoolean();
-    /**
-     * <code>optional int64 boolean = 18;</code>
-     * @return The boolean.
-     */
-    long getBoolean();
-
-    /**
-     * <code>optional string sealed = 19;</code>
-     * @return Whether the sealed field is set.
-     */
-    boolean hasSealed();
-    /**
-     * <code>optional string sealed = 19;</code>
-     * @return The sealed.
-     */
-    java.lang.String getSealed();
-    /**
-     * <code>optional string sealed = 19;</code>
-     * @return The bytes for sealed.
-     */
-    com.google.protobuf.ByteString
-        getSealedBytes();
-
-    /**
-     * <code>optional float interface = 20;</code>
-     * @return Whether the interface field is set.
-     */
-    boolean hasInterface();
-    /**
-     * <code>optional float interface = 20;</code>
-     * @return The interface.
-     */
-    float getInterface();
-
-    /**
-     * <code>optional int32 in = 21;</code>
-     * @return Whether the in field is set.
-     */
-    boolean hasIn();
-    /**
-     * <code>optional int32 in = 21;</code>
-     * @return The in.
-     */
-    int getIn();
-
-    /**
-     * <code>optional string object = 22;</code>
-     * @return Whether the object field is set.
-     */
-    boolean hasObject();
-    /**
-     * <code>optional string object = 22;</code>
-     * @return The object.
-     */
-    java.lang.String getObject();
-    /**
-     * <code>optional string object = 22;</code>
-     * @return The bytes for object.
-     */
-    com.google.protobuf.ByteString
-        getObjectBytes();
-
-    /**
-     * <code>optional string cached_size = 23;</code>
-     * @return Whether the cachedSize field is set.
-     */
-    boolean hasCachedSize_();
-    /**
-     * <code>optional string cached_size = 23;</code>
-     * @return The cachedSize.
-     */
-    java.lang.String getCachedSize_();
-    /**
-     * <code>optional string cached_size = 23;</code>
-     * @return The bytes for cachedSize.
-     */
-    com.google.protobuf.ByteString
-        getCachedSize_Bytes();
-
-    /**
-     * <code>optional bool serialized_size = 24;</code>
-     * @return Whether the serializedSize field is set.
-     */
-    boolean hasSerializedSize_();
-    /**
-     * <code>optional bool serialized_size = 24;</code>
-     * @return The serializedSize.
-     */
-    boolean getSerializedSize_();
-
-    /**
-     * <code>optional string by = 25;</code>
-     * @return Whether the by field is set.
-     */
-    boolean hasBy();
-    /**
-     * <code>optional string by = 25;</code>
-     * @return The by.
-     */
-    java.lang.String getBy();
-    /**
-     * <code>optional string by = 25;</code>
-     * @return The bytes for by.
-     */
-    com.google.protobuf.ByteString
-        getByBytes();
-
-    public evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2.CamelCaseCase getCamelCaseCase();
-  }
-  /**
-   * Protobuf type {@code evil_names_proto2.EvilNamesProto2}
-   */
-  public  static final class EvilNamesProto2 extends
-      com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
-        EvilNamesProto2, EvilNamesProto2.Builder> implements
-      // @@protoc_insertion_point(message_implements:evil_names_proto2.EvilNamesProto2)
-      EvilNamesProto2OrBuilder {
-    private EvilNamesProto2() {
-      bar_ = "";
-      aLLCAPS_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      extension_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      class__ = emptyIntList();
-      sealed_ = "";
-      object_ = "";
-      cachedSize__ = "";
-      by_ = "";
-    }
-    private int bitField0_;
-    private int camelCaseCase_ = 0;
-    private java.lang.Object camelCase_;
-    public enum CamelCaseCase {
-      FOOBAR(5),
-      CAMELCASE_NOT_SET(0);
-      private final int value;
-      private CamelCaseCase(int value) {
-        this.value = value;
-      }
-      /**
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static CamelCaseCase valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static CamelCaseCase forNumber(int value) {
-        switch (value) {
-          case 5: return FOOBAR;
-          case 0: return CAMELCASE_NOT_SET;
-          default: return null;
-        }
-      }
-      public int getNumber() {
-        return this.value;
-      }
-    };
-
-    @java.lang.Override
-    public CamelCaseCase
-    getCamelCaseCase() {
-      return CamelCaseCase.forNumber(
-          camelCaseCase_);
-    }
-
-    private void clearCamelCase() {
-      camelCaseCase_ = 0;
-      camelCase_ = null;
-    }
-
-    public static final int INITIALIZED_FIELD_NUMBER = 1;
-    private boolean initialized_;
-    /**
-     * <code>optional bool initialized = 1;</code>
-     * @return Whether the initialized field is set.
-     */
-    @java.lang.Override
-    public boolean hasInitialized() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional bool initialized = 1;</code>
-     * @return The initialized.
-     */
-    @java.lang.Override
-    public boolean getInitialized() {
-      return initialized_;
-    }
-    /**
-     * <code>optional bool initialized = 1;</code>
-     * @param value The initialized to set.
-     */
-    private void setInitialized(boolean value) {
-      bitField0_ |= 0x00000001;
-      initialized_ = value;
-    }
-    /**
-     * <code>optional bool initialized = 1;</code>
-     */
-    private void clearInitialized() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      initialized_ = false;
-    }
-
-    public static final int HAS_FOO_FIELD_NUMBER = 2;
-    private boolean hasFoo_;
-    /**
-     * <code>optional bool has_foo = 2;</code>
-     * @return Whether the hasFoo field is set.
-     */
-    @java.lang.Override
-    public boolean hasHasFoo() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional bool has_foo = 2;</code>
-     * @return The hasFoo.
-     */
-    @java.lang.Override
-    public boolean getHasFoo() {
-      return hasFoo_;
-    }
-    /**
-     * <code>optional bool has_foo = 2;</code>
-     * @param value The hasFoo to set.
-     */
-    private void setHasFoo(boolean value) {
-      bitField0_ |= 0x00000002;
-      hasFoo_ = value;
-    }
-    /**
-     * <code>optional bool has_foo = 2;</code>
-     */
-    private void clearHasFoo() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      hasFoo_ = false;
-    }
-
-    public static final int BAR_FIELD_NUMBER = 3;
-    private java.lang.String bar_;
-    /**
-     * <code>optional string Bar = 3;</code>
-     * @return Whether the bar field is set.
-     */
-    @java.lang.Override
-    public boolean hasBar() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional string Bar = 3;</code>
-     * @return The bar.
-     */
-    @java.lang.Override
-    public java.lang.String getBar() {
-      return bar_;
-    }
-    /**
-     * <code>optional string Bar = 3;</code>
-     * @return The bytes for bar.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getBarBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(bar_);
-    }
-    /**
-     * <code>optional string Bar = 3;</code>
-     * @param value The bar to set.
-     */
-    private void setBar(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00000004;
-      bar_ = value;
-    }
-    /**
-     * <code>optional string Bar = 3;</code>
-     */
-    private void clearBar() {
-      bitField0_ = (bitField0_ & ~0x00000004);
-      bar_ = getDefaultInstance().getBar();
-    }
-    /**
-     * <code>optional string Bar = 3;</code>
-     * @param value The bytes for bar to set.
-     */
-    private void setBarBytes(
-        com.google.protobuf.ByteString value) {
-      bar_ = value.toStringUtf8();
-      bitField0_ |= 0x00000004;
-    }
-
-    public static final int IS_INITIALIZED_FIELD_NUMBER = 4;
-    private boolean isInitialized_;
-    /**
-     * <code>optional bool is_initialized = 4;</code>
-     * @return Whether the isInitialized field is set.
-     */
-    @java.lang.Override
-    public boolean hasIsInitialized() {
-      return ((bitField0_ & 0x00000008) != 0);
-    }
-    /**
-     * <code>optional bool is_initialized = 4;</code>
-     * @return The isInitialized.
-     */
-    @java.lang.Override
-    public boolean getIsInitialized() {
-      return isInitialized_;
-    }
-    /**
-     * <code>optional bool is_initialized = 4;</code>
-     * @param value The isInitialized to set.
-     */
-    private void setIsInitialized(boolean value) {
-      bitField0_ |= 0x00000008;
-      isInitialized_ = value;
-    }
-    /**
-     * <code>optional bool is_initialized = 4;</code>
-     */
-    private void clearIsInitialized() {
-      bitField0_ = (bitField0_ & ~0x00000008);
-      isInitialized_ = false;
-    }
-
-    public static final int FOOBAR_FIELD_NUMBER = 5;
-    /**
-     * <code>string fooBar = 5;</code>
-     * @return Whether the fooBar field is set.
-     */
-    @java.lang.Override
-    public boolean hasFooBar() {
-      return camelCaseCase_ == 5;
-    }
-    /**
-     * <code>string fooBar = 5;</code>
-     * @return The fooBar.
-     */
-    @java.lang.Override
-    public java.lang.String getFooBar() {
-      java.lang.String ref = "";
-      if (camelCaseCase_ == 5) {
-        ref = (java.lang.String) camelCase_;
-      }
-      return ref;
-    }
-    /**
-     * <code>string fooBar = 5;</code>
-     * @return The bytes for fooBar.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getFooBarBytes() {
-      java.lang.String ref = "";
-      if (camelCaseCase_ == 5) {
-        ref = (java.lang.String) camelCase_;
-      }
-      return com.google.protobuf.ByteString.copyFromUtf8(ref);
-    }
-    /**
-     * <code>string fooBar = 5;</code>
-     * @param value The fooBar to set.
-     */
-    private void setFooBar(
-        java.lang.String value) {
-      value.getClass();
-  camelCaseCase_ = 5;
-      camelCase_ = value;
-    }
-    /**
-     * <code>string fooBar = 5;</code>
-     */
-    private void clearFooBar() {
-      if (camelCaseCase_ == 5) {
-        camelCaseCase_ = 0;
-        camelCase_ = null;
-      }
-    }
-    /**
-     * <code>string fooBar = 5;</code>
-     * @param value The bytes for fooBar to set.
-     */
-    private void setFooBarBytes(
-        com.google.protobuf.ByteString value) {
-      camelCase_ = value.toStringUtf8();
-      camelCaseCase_ = 5;
-    }
-
-    public static final int ALL_CAPS_FIELD_NUMBER = 7;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> aLLCAPS_;
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @return A list containing the aLLCAPS.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getALLCAPSList() {
-      return aLLCAPS_;
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @return The count of aLLCAPS.
-     */
-    @java.lang.Override
-    public int getALLCAPSCount() {
-      return aLLCAPS_.size();
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param index The index of the element to return.
-     * @return The aLLCAPS at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getALLCAPS(int index) {
-      return aLLCAPS_.get(index);
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the aLLCAPS at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getALLCAPSBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          aLLCAPS_.get(index));
-    }
-    private void ensureALLCAPSIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          aLLCAPS_;  if (!tmp.isModifiable()) {
-        aLLCAPS_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param index The index to set the value at.
-     * @param value The aLLCAPS to set.
-     */
-    private void setALLCAPS(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureALLCAPSIsMutable();
-      aLLCAPS_.set(index, value);
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param value The aLLCAPS to add.
-     */
-    private void addALLCAPS(
-        java.lang.String value) {
-      value.getClass();
-  ensureALLCAPSIsMutable();
-      aLLCAPS_.add(value);
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param values The aLLCAPS to add.
-     */
-    private void addAllALLCAPS(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureALLCAPSIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, aLLCAPS_);
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     */
-    private void clearALLCAPS() {
-      aLLCAPS_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param value The bytes of the aLLCAPS to add.
-     */
-    private void addALLCAPSBytes(
-        com.google.protobuf.ByteString value) {
-      ensureALLCAPSIsMutable();
-      aLLCAPS_.add(value.toStringUtf8());
-    }
-
-    public static final int ALL_CAPS_MAP_FIELD_NUMBER = 8;
-    private static final class ALLCAPSMAPDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Boolean> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Boolean>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.BOOL,
-                  false);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Boolean> aLLCAPSMAP_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Boolean>
-    internalGetALLCAPSMAP() {
-      return aLLCAPSMAP_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Boolean>
-    internalGetMutableALLCAPSMAP() {
-      if (!aLLCAPSMAP_.isMutable()) {
-        aLLCAPSMAP_ = aLLCAPSMAP_.mutableCopy();
-      }
-      return aLLCAPSMAP_;
-    }
-    @java.lang.Override
-
-    public int getALLCAPSMAPCount() {
-      return internalGetALLCAPSMAP().size();
-    }
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsALLCAPSMAP(
-        int key) {
-      
-      return internalGetALLCAPSMAP().containsKey(key);
-    }
-    /**
-     * Use {@link #getALLCAPSMAPMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Boolean> getALLCAPSMAP() {
-      return getALLCAPSMAPMap();
-    }
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Boolean> getALLCAPSMAPMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetALLCAPSMAP());
-    }
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    @java.lang.Override
-
-    public boolean getALLCAPSMAPOrDefault(
-        int key,
-        boolean defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Boolean> map =
-          internalGetALLCAPSMAP();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    @java.lang.Override
-
-    public boolean getALLCAPSMAPOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Boolean> map =
-          internalGetALLCAPSMAP();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Boolean>
-    getMutableALLCAPSMAPMap() {
-      return internalGetMutableALLCAPSMAP();
-    }
-
-    public static final int HAS_UNDERBAR_PRECEDING_NUMERIC_1FOO_FIELD_NUMBER = 9;
-    private boolean hasUnderbarPrecedingNumeric1Foo_;
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_1foo = 9;</code>
-     * @return Whether the hasUnderbarPrecedingNumeric1foo field is set.
-     */
-    @java.lang.Override
-    public boolean hasHasUnderbarPrecedingNumeric1Foo() {
-      return ((bitField0_ & 0x00000020) != 0);
-    }
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_1foo = 9;</code>
-     * @return The hasUnderbarPrecedingNumeric1foo.
-     */
-    @java.lang.Override
-    public boolean getHasUnderbarPrecedingNumeric1Foo() {
-      return hasUnderbarPrecedingNumeric1Foo_;
-    }
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_1foo = 9;</code>
-     * @param value The hasUnderbarPrecedingNumeric1foo to set.
-     */
-    private void setHasUnderbarPrecedingNumeric1Foo(boolean value) {
-      bitField0_ |= 0x00000020;
-      hasUnderbarPrecedingNumeric1Foo_ = value;
-    }
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_1foo = 9;</code>
-     */
-    private void clearHasUnderbarPrecedingNumeric1Foo() {
-      bitField0_ = (bitField0_ & ~0x00000020);
-      hasUnderbarPrecedingNumeric1Foo_ = false;
-    }
-
-    public static final int HAS_UNDERBAR_PRECEDING_NUMERIC_42BAR_FIELD_NUMBER = 13;
-    private boolean hasUnderbarPrecedingNumeric42Bar_;
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_42bar = 13;</code>
-     * @return Whether the hasUnderbarPrecedingNumeric42bar field is set.
-     */
-    @java.lang.Override
-    public boolean hasHasUnderbarPrecedingNumeric42Bar() {
-      return ((bitField0_ & 0x00000040) != 0);
-    }
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_42bar = 13;</code>
-     * @return The hasUnderbarPrecedingNumeric42bar.
-     */
-    @java.lang.Override
-    public boolean getHasUnderbarPrecedingNumeric42Bar() {
-      return hasUnderbarPrecedingNumeric42Bar_;
-    }
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_42bar = 13;</code>
-     * @param value The hasUnderbarPrecedingNumeric42bar to set.
-     */
-    private void setHasUnderbarPrecedingNumeric42Bar(boolean value) {
-      bitField0_ |= 0x00000040;
-      hasUnderbarPrecedingNumeric42Bar_ = value;
-    }
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_42bar = 13;</code>
-     */
-    private void clearHasUnderbarPrecedingNumeric42Bar() {
-      bitField0_ = (bitField0_ & ~0x00000040);
-      hasUnderbarPrecedingNumeric42Bar_ = false;
-    }
-
-    public static final int HAS_UNDERBAR_PRECEDING_NUMERIC_123FOO42BAR_BAZ_FIELD_NUMBER = 14;
-    private boolean hasUnderbarPrecedingNumeric123Foo42BarBaz_;
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_123foo42bar_baz = 14;</code>
-     * @return Whether the hasUnderbarPrecedingNumeric123foo42barBaz field is set.
-     */
-    @java.lang.Override
-    public boolean hasHasUnderbarPrecedingNumeric123Foo42BarBaz() {
-      return ((bitField0_ & 0x00000080) != 0);
-    }
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_123foo42bar_baz = 14;</code>
-     * @return The hasUnderbarPrecedingNumeric123foo42barBaz.
-     */
-    @java.lang.Override
-    public boolean getHasUnderbarPrecedingNumeric123Foo42BarBaz() {
-      return hasUnderbarPrecedingNumeric123Foo42BarBaz_;
-    }
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_123foo42bar_baz = 14;</code>
-     * @param value The hasUnderbarPrecedingNumeric123foo42barBaz to set.
-     */
-    private void setHasUnderbarPrecedingNumeric123Foo42BarBaz(boolean value) {
-      bitField0_ |= 0x00000080;
-      hasUnderbarPrecedingNumeric123Foo42BarBaz_ = value;
-    }
-    /**
-     * <code>optional bool has_underbar_preceding_numeric_123foo42bar_baz = 14;</code>
-     */
-    private void clearHasUnderbarPrecedingNumeric123Foo42BarBaz() {
-      bitField0_ = (bitField0_ & ~0x00000080);
-      hasUnderbarPrecedingNumeric123Foo42BarBaz_ = false;
-    }
-
-    public static final int EXTENSION_FIELD_NUMBER = 12;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> extension_;
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @return A list containing the extension.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getExtensionList() {
-      return extension_;
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @return The count of extension.
-     */
-    @java.lang.Override
-    public int getExtensionCount() {
-      return extension_.size();
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param index The index of the element to return.
-     * @return The extension at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getExtension(int index) {
-      return extension_.get(index);
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the extension at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getExtensionBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          extension_.get(index));
-    }
-    private void ensureExtensionIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          extension_;  if (!tmp.isModifiable()) {
-        extension_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param index The index to set the value at.
-     * @param value The extension to set.
-     */
-    private void setExtension(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureExtensionIsMutable();
-      extension_.set(index, value);
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param value The extension to add.
-     */
-    private void addExtension(
-        java.lang.String value) {
-      value.getClass();
-  ensureExtensionIsMutable();
-      extension_.add(value);
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param values The extension to add.
-     */
-    private void addAllExtension(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureExtensionIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, extension_);
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     */
-    private void clearExtension() {
-      extension_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param value The bytes of the extension to add.
-     */
-    private void addExtensionBytes(
-        com.google.protobuf.ByteString value) {
-      ensureExtensionIsMutable();
-      extension_.add(value.toStringUtf8());
-    }
-
-    public static final int CLASS_FIELD_NUMBER = 15;
-    private com.google.protobuf.Internal.IntList class__;
-    /**
-     * <code>repeated int32 class = 15;</code>
-     * @return A list containing the class.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getClass_List() {
-      return class__;
-    }
-    /**
-     * <code>repeated int32 class = 15;</code>
-     * @return The count of class.
-     */
-    @java.lang.Override
-    public int getClass_Count() {
-      return class__.size();
-    }
-    /**
-     * <code>repeated int32 class = 15;</code>
-     * @param index The index of the element to return.
-     * @return The class at the given index.
-     */
-    @java.lang.Override
-    public int getClass_(int index) {
-      return class__.getInt(index);
-    }
-    private void ensureClass_IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = class__;
-      if (!tmp.isModifiable()) {
-        class__ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int32 class = 15;</code>
-     * @param index The index to set the value at.
-     * @param value The class to set.
-     */
-    private void setClass_(
-        int index, int value) {
-      ensureClass_IsMutable();
-      class__.setInt(index, value);
-    }
-    /**
-     * <code>repeated int32 class = 15;</code>
-     * @param value The class to add.
-     */
-    private void addClass_(int value) {
-      ensureClass_IsMutable();
-      class__.addInt(value);
-    }
-    /**
-     * <code>repeated int32 class = 15;</code>
-     * @param values The class to add.
-     */
-    private void addAllClass_(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureClass_IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, class__);
-    }
-    /**
-     * <code>repeated int32 class = 15;</code>
-     */
-    private void clearClass_() {
-      class__ = emptyIntList();
-    }
-
-    public static final int INT_FIELD_NUMBER = 16;
-    private double int_;
-    /**
-     * <code>optional double int = 16;</code>
-     * @return Whether the int field is set.
-     */
-    @java.lang.Override
-    public boolean hasInt() {
-      return ((bitField0_ & 0x00000100) != 0);
-    }
-    /**
-     * <code>optional double int = 16;</code>
-     * @return The int.
-     */
-    @java.lang.Override
-    public double getInt() {
-      return int_;
-    }
-    /**
-     * <code>optional double int = 16;</code>
-     * @param value The int to set.
-     */
-    private void setInt(double value) {
-      bitField0_ |= 0x00000100;
-      int_ = value;
-    }
-    /**
-     * <code>optional double int = 16;</code>
-     */
-    private void clearInt() {
-      bitField0_ = (bitField0_ & ~0x00000100);
-      int_ = 0D;
-    }
-
-    public static final int LONG_FIELD_NUMBER = 17;
-    private boolean long_;
-    /**
-     * <code>optional bool long = 17;</code>
-     * @return Whether the long field is set.
-     */
-    @java.lang.Override
-    public boolean hasLong() {
-      return ((bitField0_ & 0x00000200) != 0);
-    }
-    /**
-     * <code>optional bool long = 17;</code>
-     * @return The long.
-     */
-    @java.lang.Override
-    public boolean getLong() {
-      return long_;
-    }
-    /**
-     * <code>optional bool long = 17;</code>
-     * @param value The long to set.
-     */
-    private void setLong(boolean value) {
-      bitField0_ |= 0x00000200;
-      long_ = value;
-    }
-    /**
-     * <code>optional bool long = 17;</code>
-     */
-    private void clearLong() {
-      bitField0_ = (bitField0_ & ~0x00000200);
-      long_ = false;
-    }
-
-    public static final int BOOLEAN_FIELD_NUMBER = 18;
-    private long boolean_;
-    /**
-     * <code>optional int64 boolean = 18;</code>
-     * @return Whether the boolean field is set.
-     */
-    @java.lang.Override
-    public boolean hasBoolean() {
-      return ((bitField0_ & 0x00000400) != 0);
-    }
-    /**
-     * <code>optional int64 boolean = 18;</code>
-     * @return The boolean.
-     */
-    @java.lang.Override
-    public long getBoolean() {
-      return boolean_;
-    }
-    /**
-     * <code>optional int64 boolean = 18;</code>
-     * @param value The boolean to set.
-     */
-    private void setBoolean(long value) {
-      bitField0_ |= 0x00000400;
-      boolean_ = value;
-    }
-    /**
-     * <code>optional int64 boolean = 18;</code>
-     */
-    private void clearBoolean() {
-      bitField0_ = (bitField0_ & ~0x00000400);
-      boolean_ = 0L;
-    }
-
-    public static final int SEALED_FIELD_NUMBER = 19;
-    private java.lang.String sealed_;
-    /**
-     * <code>optional string sealed = 19;</code>
-     * @return Whether the sealed field is set.
-     */
-    @java.lang.Override
-    public boolean hasSealed() {
-      return ((bitField0_ & 0x00000800) != 0);
-    }
-    /**
-     * <code>optional string sealed = 19;</code>
-     * @return The sealed.
-     */
-    @java.lang.Override
-    public java.lang.String getSealed() {
-      return sealed_;
-    }
-    /**
-     * <code>optional string sealed = 19;</code>
-     * @return The bytes for sealed.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getSealedBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(sealed_);
-    }
-    /**
-     * <code>optional string sealed = 19;</code>
-     * @param value The sealed to set.
-     */
-    private void setSealed(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00000800;
-      sealed_ = value;
-    }
-    /**
-     * <code>optional string sealed = 19;</code>
-     */
-    private void clearSealed() {
-      bitField0_ = (bitField0_ & ~0x00000800);
-      sealed_ = getDefaultInstance().getSealed();
-    }
-    /**
-     * <code>optional string sealed = 19;</code>
-     * @param value The bytes for sealed to set.
-     */
-    private void setSealedBytes(
-        com.google.protobuf.ByteString value) {
-      sealed_ = value.toStringUtf8();
-      bitField0_ |= 0x00000800;
-    }
-
-    public static final int INTERFACE_FIELD_NUMBER = 20;
-    private float interface_;
-    /**
-     * <code>optional float interface = 20;</code>
-     * @return Whether the interface field is set.
-     */
-    @java.lang.Override
-    public boolean hasInterface() {
-      return ((bitField0_ & 0x00001000) != 0);
-    }
-    /**
-     * <code>optional float interface = 20;</code>
-     * @return The interface.
-     */
-    @java.lang.Override
-    public float getInterface() {
-      return interface_;
-    }
-    /**
-     * <code>optional float interface = 20;</code>
-     * @param value The interface to set.
-     */
-    private void setInterface(float value) {
-      bitField0_ |= 0x00001000;
-      interface_ = value;
-    }
-    /**
-     * <code>optional float interface = 20;</code>
-     */
-    private void clearInterface() {
-      bitField0_ = (bitField0_ & ~0x00001000);
-      interface_ = 0F;
-    }
-
-    public static final int IN_FIELD_NUMBER = 21;
-    private int in_;
-    /**
-     * <code>optional int32 in = 21;</code>
-     * @return Whether the in field is set.
-     */
-    @java.lang.Override
-    public boolean hasIn() {
-      return ((bitField0_ & 0x00002000) != 0);
-    }
-    /**
-     * <code>optional int32 in = 21;</code>
-     * @return The in.
-     */
-    @java.lang.Override
-    public int getIn() {
-      return in_;
-    }
-    /**
-     * <code>optional int32 in = 21;</code>
-     * @param value The in to set.
-     */
-    private void setIn(int value) {
-      bitField0_ |= 0x00002000;
-      in_ = value;
-    }
-    /**
-     * <code>optional int32 in = 21;</code>
-     */
-    private void clearIn() {
-      bitField0_ = (bitField0_ & ~0x00002000);
-      in_ = 0;
-    }
-
-    public static final int OBJECT_FIELD_NUMBER = 22;
-    private java.lang.String object_;
-    /**
-     * <code>optional string object = 22;</code>
-     * @return Whether the object field is set.
-     */
-    @java.lang.Override
-    public boolean hasObject() {
-      return ((bitField0_ & 0x00004000) != 0);
-    }
-    /**
-     * <code>optional string object = 22;</code>
-     * @return The object.
-     */
-    @java.lang.Override
-    public java.lang.String getObject() {
-      return object_;
-    }
-    /**
-     * <code>optional string object = 22;</code>
-     * @return The bytes for object.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getObjectBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(object_);
-    }
-    /**
-     * <code>optional string object = 22;</code>
-     * @param value The object to set.
-     */
-    private void setObject(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00004000;
-      object_ = value;
-    }
-    /**
-     * <code>optional string object = 22;</code>
-     */
-    private void clearObject() {
-      bitField0_ = (bitField0_ & ~0x00004000);
-      object_ = getDefaultInstance().getObject();
-    }
-    /**
-     * <code>optional string object = 22;</code>
-     * @param value The bytes for object to set.
-     */
-    private void setObjectBytes(
-        com.google.protobuf.ByteString value) {
-      object_ = value.toStringUtf8();
-      bitField0_ |= 0x00004000;
-    }
-
-    public static final int CACHED_SIZE_FIELD_NUMBER = 23;
-    private java.lang.String cachedSize__;
-    /**
-     * <code>optional string cached_size = 23;</code>
-     * @return Whether the cachedSize field is set.
-     */
-    @java.lang.Override
-    public boolean hasCachedSize_() {
-      return ((bitField0_ & 0x00008000) != 0);
-    }
-    /**
-     * <code>optional string cached_size = 23;</code>
-     * @return The cachedSize.
-     */
-    @java.lang.Override
-    public java.lang.String getCachedSize_() {
-      return cachedSize__;
-    }
-    /**
-     * <code>optional string cached_size = 23;</code>
-     * @return The bytes for cachedSize.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getCachedSize_Bytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(cachedSize__);
-    }
-    /**
-     * <code>optional string cached_size = 23;</code>
-     * @param value The cachedSize to set.
-     */
-    private void setCachedSize_(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00008000;
-      cachedSize__ = value;
-    }
-    /**
-     * <code>optional string cached_size = 23;</code>
-     */
-    private void clearCachedSize_() {
-      bitField0_ = (bitField0_ & ~0x00008000);
-      cachedSize__ = getDefaultInstance().getCachedSize_();
-    }
-    /**
-     * <code>optional string cached_size = 23;</code>
-     * @param value The bytes for cachedSize to set.
-     */
-    private void setCachedSize_Bytes(
-        com.google.protobuf.ByteString value) {
-      cachedSize__ = value.toStringUtf8();
-      bitField0_ |= 0x00008000;
-    }
-
-    public static final int SERIALIZED_SIZE_FIELD_NUMBER = 24;
-    private boolean serializedSize__;
-    /**
-     * <code>optional bool serialized_size = 24;</code>
-     * @return Whether the serializedSize field is set.
-     */
-    @java.lang.Override
-    public boolean hasSerializedSize_() {
-      return ((bitField0_ & 0x00010000) != 0);
-    }
-    /**
-     * <code>optional bool serialized_size = 24;</code>
-     * @return The serializedSize.
-     */
-    @java.lang.Override
-    public boolean getSerializedSize_() {
-      return serializedSize__;
-    }
-    /**
-     * <code>optional bool serialized_size = 24;</code>
-     * @param value The serializedSize to set.
-     */
-    private void setSerializedSize_(boolean value) {
-      bitField0_ |= 0x00010000;
-      serializedSize__ = value;
-    }
-    /**
-     * <code>optional bool serialized_size = 24;</code>
-     */
-    private void clearSerializedSize_() {
-      bitField0_ = (bitField0_ & ~0x00010000);
-      serializedSize__ = false;
-    }
-
-    public static final int BY_FIELD_NUMBER = 25;
-    private java.lang.String by_;
-    /**
-     * <code>optional string by = 25;</code>
-     * @return Whether the by field is set.
-     */
-    @java.lang.Override
-    public boolean hasBy() {
-      return ((bitField0_ & 0x00020000) != 0);
-    }
-    /**
-     * <code>optional string by = 25;</code>
-     * @return The by.
-     */
-    @java.lang.Override
-    public java.lang.String getBy() {
-      return by_;
-    }
-    /**
-     * <code>optional string by = 25;</code>
-     * @return The bytes for by.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getByBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(by_);
-    }
-    /**
-     * <code>optional string by = 25;</code>
-     * @param value The by to set.
-     */
-    private void setBy(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00020000;
-      by_ = value;
-    }
-    /**
-     * <code>optional string by = 25;</code>
-     */
-    private void clearBy() {
-      bitField0_ = (bitField0_ & ~0x00020000);
-      by_ = getDefaultInstance().getBy();
-    }
-    /**
-     * <code>optional string by = 25;</code>
-     * @param value The bytes for by to set.
-     */
-    private void setByBytes(
-        com.google.protobuf.ByteString value) {
-      by_ = value.toStringUtf8();
-      bitField0_ |= 0x00020000;
-    }
-
-    public static evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2 parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2 parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2 parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2 parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2 parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2 parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2 parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2 parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2 parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2 parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2 parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2 parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2 prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code evil_names_proto2.EvilNamesProto2}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
-          evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2, Builder> implements
-        // @@protoc_insertion_point(builder_implements:evil_names_proto2.EvilNamesProto2)
-        evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2OrBuilder {
-      // Construct using evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-      @java.lang.Override
-      public CamelCaseCase
-          getCamelCaseCase() {
-        return instance.getCamelCaseCase();
-      }
-
-      public Builder clearCamelCase() {
-        copyOnWrite();
-        instance.clearCamelCase();
-        return this;
-      }
-
-
-      /**
-       * <code>optional bool initialized = 1;</code>
-       * @return Whether the initialized field is set.
-       */
-      @java.lang.Override
-      public boolean hasInitialized() {
-        return instance.hasInitialized();
-      }
-      /**
-       * <code>optional bool initialized = 1;</code>
-       * @return The initialized.
-       */
-      @java.lang.Override
-      public boolean getInitialized() {
-        return instance.getInitialized();
-      }
-      /**
-       * <code>optional bool initialized = 1;</code>
-       * @param value The initialized to set.
-       * @return This builder for chaining.
-       */
-      public Builder setInitialized(boolean value) {
-        copyOnWrite();
-        instance.setInitialized(value);
-        return this;
-      }
-      /**
-       * <code>optional bool initialized = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearInitialized() {
-        copyOnWrite();
-        instance.clearInitialized();
-        return this;
-      }
-
-      /**
-       * <code>optional bool has_foo = 2;</code>
-       * @return Whether the hasFoo field is set.
-       */
-      @java.lang.Override
-      public boolean hasHasFoo() {
-        return instance.hasHasFoo();
-      }
-      /**
-       * <code>optional bool has_foo = 2;</code>
-       * @return The hasFoo.
-       */
-      @java.lang.Override
-      public boolean getHasFoo() {
-        return instance.getHasFoo();
-      }
-      /**
-       * <code>optional bool has_foo = 2;</code>
-       * @param value The hasFoo to set.
-       * @return This builder for chaining.
-       */
-      public Builder setHasFoo(boolean value) {
-        copyOnWrite();
-        instance.setHasFoo(value);
-        return this;
-      }
-      /**
-       * <code>optional bool has_foo = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearHasFoo() {
-        copyOnWrite();
-        instance.clearHasFoo();
-        return this;
-      }
-
-      /**
-       * <code>optional string Bar = 3;</code>
-       * @return Whether the bar field is set.
-       */
-      @java.lang.Override
-      public boolean hasBar() {
-        return instance.hasBar();
-      }
-      /**
-       * <code>optional string Bar = 3;</code>
-       * @return The bar.
-       */
-      @java.lang.Override
-      public java.lang.String getBar() {
-        return instance.getBar();
-      }
-      /**
-       * <code>optional string Bar = 3;</code>
-       * @return The bytes for bar.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getBarBytes() {
-        return instance.getBarBytes();
-      }
-      /**
-       * <code>optional string Bar = 3;</code>
-       * @param value The bar to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBar(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setBar(value);
-        return this;
-      }
-      /**
-       * <code>optional string Bar = 3;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearBar() {
-        copyOnWrite();
-        instance.clearBar();
-        return this;
-      }
-      /**
-       * <code>optional string Bar = 3;</code>
-       * @param value The bytes for bar to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBarBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setBarBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional bool is_initialized = 4;</code>
-       * @return Whether the isInitialized field is set.
-       */
-      @java.lang.Override
-      public boolean hasIsInitialized() {
-        return instance.hasIsInitialized();
-      }
-      /**
-       * <code>optional bool is_initialized = 4;</code>
-       * @return The isInitialized.
-       */
-      @java.lang.Override
-      public boolean getIsInitialized() {
-        return instance.getIsInitialized();
-      }
-      /**
-       * <code>optional bool is_initialized = 4;</code>
-       * @param value The isInitialized to set.
-       * @return This builder for chaining.
-       */
-      public Builder setIsInitialized(boolean value) {
-        copyOnWrite();
-        instance.setIsInitialized(value);
-        return this;
-      }
-      /**
-       * <code>optional bool is_initialized = 4;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearIsInitialized() {
-        copyOnWrite();
-        instance.clearIsInitialized();
-        return this;
-      }
-
-      /**
-       * <code>string fooBar = 5;</code>
-       * @return Whether the fooBar field is set.
-       */
-      @java.lang.Override
-      public boolean hasFooBar() {
-        return instance.hasFooBar();
-      }
-      /**
-       * <code>string fooBar = 5;</code>
-       * @return The fooBar.
-       */
-      @java.lang.Override
-      public java.lang.String getFooBar() {
-        return instance.getFooBar();
-      }
-      /**
-       * <code>string fooBar = 5;</code>
-       * @return The bytes for fooBar.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getFooBarBytes() {
-        return instance.getFooBarBytes();
-      }
-      /**
-       * <code>string fooBar = 5;</code>
-       * @param value The fooBar to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooBar(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setFooBar(value);
-        return this;
-      }
-      /**
-       * <code>string fooBar = 5;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFooBar() {
-        copyOnWrite();
-        instance.clearFooBar();
-        return this;
-      }
-      /**
-       * <code>string fooBar = 5;</code>
-       * @param value The bytes for fooBar to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooBarBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setFooBarBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>repeated string ALL_CAPS = 7;</code>
-       * @return A list containing the aLLCAPS.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getALLCAPSList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getALLCAPSList());
-      }
-      /**
-       * <code>repeated string ALL_CAPS = 7;</code>
-       * @return The count of aLLCAPS.
-       */
-      @java.lang.Override
-      public int getALLCAPSCount() {
-        return instance.getALLCAPSCount();
-      }
-      /**
-       * <code>repeated string ALL_CAPS = 7;</code>
-       * @param index The index of the element to return.
-       * @return The aLLCAPS at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getALLCAPS(int index) {
-        return instance.getALLCAPS(index);
-      }
-      /**
-       * <code>repeated string ALL_CAPS = 7;</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the aLLCAPS at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getALLCAPSBytes(int index) {
-        return instance.getALLCAPSBytes(index);
-      }
-      /**
-       * <code>repeated string ALL_CAPS = 7;</code>
-       * @param index The index to set the value at.
-       * @param value The aLLCAPS to set.
-       * @return This builder for chaining.
-       */
-      public Builder setALLCAPS(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setALLCAPS(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string ALL_CAPS = 7;</code>
-       * @param value The aLLCAPS to add.
-       * @return This builder for chaining.
-       */
-      public Builder addALLCAPS(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addALLCAPS(value);
-        return this;
-      }
-      /**
-       * <code>repeated string ALL_CAPS = 7;</code>
-       * @param values The aLLCAPS to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllALLCAPS(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllALLCAPS(values);
-        return this;
-      }
-      /**
-       * <code>repeated string ALL_CAPS = 7;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearALLCAPS() {
-        copyOnWrite();
-        instance.clearALLCAPS();
-        return this;
-      }
-      /**
-       * <code>repeated string ALL_CAPS = 7;</code>
-       * @param value The bytes of the aLLCAPS to add.
-       * @return This builder for chaining.
-       */
-      public Builder addALLCAPSBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addALLCAPSBytes(value);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getALLCAPSMAPCount() {
-        return instance.getALLCAPSMAPMap().size();
-      }
-      /**
-       * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsALLCAPSMAP(
-          int key) {
-        
-        return instance.getALLCAPSMAPMap().containsKey(key);
-      }
-
-      public Builder clearALLCAPSMAP() {
-        copyOnWrite();
-        instance.getMutableALLCAPSMAPMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-       */
-
-      public Builder removeALLCAPSMAP(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableALLCAPSMAPMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getALLCAPSMAPMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Boolean> getALLCAPSMAP() {
-        return getALLCAPSMAPMap();
-      }
-      /**
-       * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Boolean> getALLCAPSMAPMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getALLCAPSMAPMap());
-      }
-      /**
-       * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-       */
-      @java.lang.Override
-
-      public boolean getALLCAPSMAPOrDefault(
-          int key,
-          boolean defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Boolean> map =
-            instance.getALLCAPSMAPMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-       */
-      @java.lang.Override
-
-      public boolean getALLCAPSMAPOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Boolean> map =
-            instance.getALLCAPSMAPMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-       */
-      public Builder putALLCAPSMAP(
-          int key,
-          boolean value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableALLCAPSMAPMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-       */
-      public Builder putAllALLCAPSMAP(
-          java.util.Map<java.lang.Integer, java.lang.Boolean> values) {
-        copyOnWrite();
-        instance.getMutableALLCAPSMAPMap().putAll(values);
-        return this;
-      }
-
-      /**
-       * <code>optional bool has_underbar_preceding_numeric_1foo = 9;</code>
-       * @return Whether the hasUnderbarPrecedingNumeric1foo field is set.
-       */
-      @java.lang.Override
-      public boolean hasHasUnderbarPrecedingNumeric1Foo() {
-        return instance.hasHasUnderbarPrecedingNumeric1Foo();
-      }
-      /**
-       * <code>optional bool has_underbar_preceding_numeric_1foo = 9;</code>
-       * @return The hasUnderbarPrecedingNumeric1foo.
-       */
-      @java.lang.Override
-      public boolean getHasUnderbarPrecedingNumeric1Foo() {
-        return instance.getHasUnderbarPrecedingNumeric1Foo();
-      }
-      /**
-       * <code>optional bool has_underbar_preceding_numeric_1foo = 9;</code>
-       * @param value The hasUnderbarPrecedingNumeric1foo to set.
-       * @return This builder for chaining.
-       */
-      public Builder setHasUnderbarPrecedingNumeric1Foo(boolean value) {
-        copyOnWrite();
-        instance.setHasUnderbarPrecedingNumeric1Foo(value);
-        return this;
-      }
-      /**
-       * <code>optional bool has_underbar_preceding_numeric_1foo = 9;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearHasUnderbarPrecedingNumeric1Foo() {
-        copyOnWrite();
-        instance.clearHasUnderbarPrecedingNumeric1Foo();
-        return this;
-      }
-
-      /**
-       * <code>optional bool has_underbar_preceding_numeric_42bar = 13;</code>
-       * @return Whether the hasUnderbarPrecedingNumeric42bar field is set.
-       */
-      @java.lang.Override
-      public boolean hasHasUnderbarPrecedingNumeric42Bar() {
-        return instance.hasHasUnderbarPrecedingNumeric42Bar();
-      }
-      /**
-       * <code>optional bool has_underbar_preceding_numeric_42bar = 13;</code>
-       * @return The hasUnderbarPrecedingNumeric42bar.
-       */
-      @java.lang.Override
-      public boolean getHasUnderbarPrecedingNumeric42Bar() {
-        return instance.getHasUnderbarPrecedingNumeric42Bar();
-      }
-      /**
-       * <code>optional bool has_underbar_preceding_numeric_42bar = 13;</code>
-       * @param value The hasUnderbarPrecedingNumeric42bar to set.
-       * @return This builder for chaining.
-       */
-      public Builder setHasUnderbarPrecedingNumeric42Bar(boolean value) {
-        copyOnWrite();
-        instance.setHasUnderbarPrecedingNumeric42Bar(value);
-        return this;
-      }
-      /**
-       * <code>optional bool has_underbar_preceding_numeric_42bar = 13;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearHasUnderbarPrecedingNumeric42Bar() {
-        copyOnWrite();
-        instance.clearHasUnderbarPrecedingNumeric42Bar();
-        return this;
-      }
-
-      /**
-       * <code>optional bool has_underbar_preceding_numeric_123foo42bar_baz = 14;</code>
-       * @return Whether the hasUnderbarPrecedingNumeric123foo42barBaz field is set.
-       */
-      @java.lang.Override
-      public boolean hasHasUnderbarPrecedingNumeric123Foo42BarBaz() {
-        return instance.hasHasUnderbarPrecedingNumeric123Foo42BarBaz();
-      }
-      /**
-       * <code>optional bool has_underbar_preceding_numeric_123foo42bar_baz = 14;</code>
-       * @return The hasUnderbarPrecedingNumeric123foo42barBaz.
-       */
-      @java.lang.Override
-      public boolean getHasUnderbarPrecedingNumeric123Foo42BarBaz() {
-        return instance.getHasUnderbarPrecedingNumeric123Foo42BarBaz();
-      }
-      /**
-       * <code>optional bool has_underbar_preceding_numeric_123foo42bar_baz = 14;</code>
-       * @param value The hasUnderbarPrecedingNumeric123foo42barBaz to set.
-       * @return This builder for chaining.
-       */
-      public Builder setHasUnderbarPrecedingNumeric123Foo42BarBaz(boolean value) {
-        copyOnWrite();
-        instance.setHasUnderbarPrecedingNumeric123Foo42BarBaz(value);
-        return this;
-      }
-      /**
-       * <code>optional bool has_underbar_preceding_numeric_123foo42bar_baz = 14;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearHasUnderbarPrecedingNumeric123Foo42BarBaz() {
-        copyOnWrite();
-        instance.clearHasUnderbarPrecedingNumeric123Foo42BarBaz();
-        return this;
-      }
-
-      /**
-       * <code>repeated string extension = 12;</code>
-       * @return A list containing the extension.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getExtensionList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getExtensionList());
-      }
-      /**
-       * <code>repeated string extension = 12;</code>
-       * @return The count of extension.
-       */
-      @java.lang.Override
-      public int getExtensionCount() {
-        return instance.getExtensionCount();
-      }
-      /**
-       * <code>repeated string extension = 12;</code>
-       * @param index The index of the element to return.
-       * @return The extension at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getExtension(int index) {
-        return instance.getExtension(index);
-      }
-      /**
-       * <code>repeated string extension = 12;</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the extension at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getExtensionBytes(int index) {
-        return instance.getExtensionBytes(index);
-      }
-      /**
-       * <code>repeated string extension = 12;</code>
-       * @param index The index to set the value at.
-       * @param value The extension to set.
-       * @return This builder for chaining.
-       */
-      public Builder setExtension(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setExtension(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string extension = 12;</code>
-       * @param value The extension to add.
-       * @return This builder for chaining.
-       */
-      public Builder addExtension(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addExtension(value);
-        return this;
-      }
-      /**
-       * <code>repeated string extension = 12;</code>
-       * @param values The extension to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllExtension(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllExtension(values);
-        return this;
-      }
-      /**
-       * <code>repeated string extension = 12;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearExtension() {
-        copyOnWrite();
-        instance.clearExtension();
-        return this;
-      }
-      /**
-       * <code>repeated string extension = 12;</code>
-       * @param value The bytes of the extension to add.
-       * @return This builder for chaining.
-       */
-      public Builder addExtensionBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addExtensionBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>repeated int32 class = 15;</code>
-       * @return A list containing the class.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getClass_List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getClass_List());
-      }
-      /**
-       * <code>repeated int32 class = 15;</code>
-       * @return The count of class.
-       */
-      @java.lang.Override
-      public int getClass_Count() {
-        return instance.getClass_Count();
-      }
-      /**
-       * <code>repeated int32 class = 15;</code>
-       * @param index The index of the element to return.
-       * @return The class at the given index.
-       */
-      @java.lang.Override
-      public int getClass_(int index) {
-        return instance.getClass_(index);
-      }
-      /**
-       * <code>repeated int32 class = 15;</code>
-       * @param value The class to set.
-       * @return This builder for chaining.
-       */
-      public Builder setClass_(
-          int index, int value) {
-        copyOnWrite();
-        instance.setClass_(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 class = 15;</code>
-       * @param value The class to add.
-       * @return This builder for chaining.
-       */
-      public Builder addClass_(int value) {
-        copyOnWrite();
-        instance.addClass_(value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 class = 15;</code>
-       * @param values The class to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllClass_(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllClass_(values);
-        return this;
-      }
-      /**
-       * <code>repeated int32 class = 15;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearClass_() {
-        copyOnWrite();
-        instance.clearClass_();
-        return this;
-      }
-
-      /**
-       * <code>optional double int = 16;</code>
-       * @return Whether the int field is set.
-       */
-      @java.lang.Override
-      public boolean hasInt() {
-        return instance.hasInt();
-      }
-      /**
-       * <code>optional double int = 16;</code>
-       * @return The int.
-       */
-      @java.lang.Override
-      public double getInt() {
-        return instance.getInt();
-      }
-      /**
-       * <code>optional double int = 16;</code>
-       * @param value The int to set.
-       * @return This builder for chaining.
-       */
-      public Builder setInt(double value) {
-        copyOnWrite();
-        instance.setInt(value);
-        return this;
-      }
-      /**
-       * <code>optional double int = 16;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearInt() {
-        copyOnWrite();
-        instance.clearInt();
-        return this;
-      }
-
-      /**
-       * <code>optional bool long = 17;</code>
-       * @return Whether the long field is set.
-       */
-      @java.lang.Override
-      public boolean hasLong() {
-        return instance.hasLong();
-      }
-      /**
-       * <code>optional bool long = 17;</code>
-       * @return The long.
-       */
-      @java.lang.Override
-      public boolean getLong() {
-        return instance.getLong();
-      }
-      /**
-       * <code>optional bool long = 17;</code>
-       * @param value The long to set.
-       * @return This builder for chaining.
-       */
-      public Builder setLong(boolean value) {
-        copyOnWrite();
-        instance.setLong(value);
-        return this;
-      }
-      /**
-       * <code>optional bool long = 17;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearLong() {
-        copyOnWrite();
-        instance.clearLong();
-        return this;
-      }
-
-      /**
-       * <code>optional int64 boolean = 18;</code>
-       * @return Whether the boolean field is set.
-       */
-      @java.lang.Override
-      public boolean hasBoolean() {
-        return instance.hasBoolean();
-      }
-      /**
-       * <code>optional int64 boolean = 18;</code>
-       * @return The boolean.
-       */
-      @java.lang.Override
-      public long getBoolean() {
-        return instance.getBoolean();
-      }
-      /**
-       * <code>optional int64 boolean = 18;</code>
-       * @param value The boolean to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBoolean(long value) {
-        copyOnWrite();
-        instance.setBoolean(value);
-        return this;
-      }
-      /**
-       * <code>optional int64 boolean = 18;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearBoolean() {
-        copyOnWrite();
-        instance.clearBoolean();
-        return this;
-      }
-
-      /**
-       * <code>optional string sealed = 19;</code>
-       * @return Whether the sealed field is set.
-       */
-      @java.lang.Override
-      public boolean hasSealed() {
-        return instance.hasSealed();
-      }
-      /**
-       * <code>optional string sealed = 19;</code>
-       * @return The sealed.
-       */
-      @java.lang.Override
-      public java.lang.String getSealed() {
-        return instance.getSealed();
-      }
-      /**
-       * <code>optional string sealed = 19;</code>
-       * @return The bytes for sealed.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getSealedBytes() {
-        return instance.getSealedBytes();
-      }
-      /**
-       * <code>optional string sealed = 19;</code>
-       * @param value The sealed to set.
-       * @return This builder for chaining.
-       */
-      public Builder setSealed(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setSealed(value);
-        return this;
-      }
-      /**
-       * <code>optional string sealed = 19;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearSealed() {
-        copyOnWrite();
-        instance.clearSealed();
-        return this;
-      }
-      /**
-       * <code>optional string sealed = 19;</code>
-       * @param value The bytes for sealed to set.
-       * @return This builder for chaining.
-       */
-      public Builder setSealedBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setSealedBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional float interface = 20;</code>
-       * @return Whether the interface field is set.
-       */
-      @java.lang.Override
-      public boolean hasInterface() {
-        return instance.hasInterface();
-      }
-      /**
-       * <code>optional float interface = 20;</code>
-       * @return The interface.
-       */
-      @java.lang.Override
-      public float getInterface() {
-        return instance.getInterface();
-      }
-      /**
-       * <code>optional float interface = 20;</code>
-       * @param value The interface to set.
-       * @return This builder for chaining.
-       */
-      public Builder setInterface(float value) {
-        copyOnWrite();
-        instance.setInterface(value);
-        return this;
-      }
-      /**
-       * <code>optional float interface = 20;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearInterface() {
-        copyOnWrite();
-        instance.clearInterface();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 in = 21;</code>
-       * @return Whether the in field is set.
-       */
-      @java.lang.Override
-      public boolean hasIn() {
-        return instance.hasIn();
-      }
-      /**
-       * <code>optional int32 in = 21;</code>
-       * @return The in.
-       */
-      @java.lang.Override
-      public int getIn() {
-        return instance.getIn();
-      }
-      /**
-       * <code>optional int32 in = 21;</code>
-       * @param value The in to set.
-       * @return This builder for chaining.
-       */
-      public Builder setIn(int value) {
-        copyOnWrite();
-        instance.setIn(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 in = 21;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearIn() {
-        copyOnWrite();
-        instance.clearIn();
-        return this;
-      }
-
-      /**
-       * <code>optional string object = 22;</code>
-       * @return Whether the object field is set.
-       */
-      @java.lang.Override
-      public boolean hasObject() {
-        return instance.hasObject();
-      }
-      /**
-       * <code>optional string object = 22;</code>
-       * @return The object.
-       */
-      @java.lang.Override
-      public java.lang.String getObject() {
-        return instance.getObject();
-      }
-      /**
-       * <code>optional string object = 22;</code>
-       * @return The bytes for object.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getObjectBytes() {
-        return instance.getObjectBytes();
-      }
-      /**
-       * <code>optional string object = 22;</code>
-       * @param value The object to set.
-       * @return This builder for chaining.
-       */
-      public Builder setObject(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setObject(value);
-        return this;
-      }
-      /**
-       * <code>optional string object = 22;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearObject() {
-        copyOnWrite();
-        instance.clearObject();
-        return this;
-      }
-      /**
-       * <code>optional string object = 22;</code>
-       * @param value The bytes for object to set.
-       * @return This builder for chaining.
-       */
-      public Builder setObjectBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setObjectBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional string cached_size = 23;</code>
-       * @return Whether the cachedSize field is set.
-       */
-      @java.lang.Override
-      public boolean hasCachedSize_() {
-        return instance.hasCachedSize_();
-      }
-      /**
-       * <code>optional string cached_size = 23;</code>
-       * @return The cachedSize.
-       */
-      @java.lang.Override
-      public java.lang.String getCachedSize_() {
-        return instance.getCachedSize_();
-      }
-      /**
-       * <code>optional string cached_size = 23;</code>
-       * @return The bytes for cachedSize.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getCachedSize_Bytes() {
-        return instance.getCachedSize_Bytes();
-      }
-      /**
-       * <code>optional string cached_size = 23;</code>
-       * @param value The cachedSize to set.
-       * @return This builder for chaining.
-       */
-      public Builder setCachedSize_(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setCachedSize_(value);
-        return this;
-      }
-      /**
-       * <code>optional string cached_size = 23;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearCachedSize_() {
-        copyOnWrite();
-        instance.clearCachedSize_();
-        return this;
-      }
-      /**
-       * <code>optional string cached_size = 23;</code>
-       * @param value The bytes for cachedSize to set.
-       * @return This builder for chaining.
-       */
-      public Builder setCachedSize_Bytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setCachedSize_Bytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional bool serialized_size = 24;</code>
-       * @return Whether the serializedSize field is set.
-       */
-      @java.lang.Override
-      public boolean hasSerializedSize_() {
-        return instance.hasSerializedSize_();
-      }
-      /**
-       * <code>optional bool serialized_size = 24;</code>
-       * @return The serializedSize.
-       */
-      @java.lang.Override
-      public boolean getSerializedSize_() {
-        return instance.getSerializedSize_();
-      }
-      /**
-       * <code>optional bool serialized_size = 24;</code>
-       * @param value The serializedSize to set.
-       * @return This builder for chaining.
-       */
-      public Builder setSerializedSize_(boolean value) {
-        copyOnWrite();
-        instance.setSerializedSize_(value);
-        return this;
-      }
-      /**
-       * <code>optional bool serialized_size = 24;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearSerializedSize_() {
-        copyOnWrite();
-        instance.clearSerializedSize_();
-        return this;
-      }
-
-      /**
-       * <code>optional string by = 25;</code>
-       * @return Whether the by field is set.
-       */
-      @java.lang.Override
-      public boolean hasBy() {
-        return instance.hasBy();
-      }
-      /**
-       * <code>optional string by = 25;</code>
-       * @return The by.
-       */
-      @java.lang.Override
-      public java.lang.String getBy() {
-        return instance.getBy();
-      }
-      /**
-       * <code>optional string by = 25;</code>
-       * @return The bytes for by.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getByBytes() {
-        return instance.getByBytes();
-      }
-      /**
-       * <code>optional string by = 25;</code>
-       * @param value The by to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBy(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setBy(value);
-        return this;
-      }
-      /**
-       * <code>optional string by = 25;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearBy() {
-        copyOnWrite();
-        instance.clearBy();
-        return this;
-      }
-      /**
-       * <code>optional string by = 25;</code>
-       * @param value The bytes for by to set.
-       * @return This builder for chaining.
-       */
-      public Builder setByBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setByBytes(value);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:evil_names_proto2.EvilNamesProto2)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "camelCase_",
-              "camelCaseCase_",
-              "bitField0_",
-              "initialized_",
-              "hasFoo_",
-              "bar_",
-              "isInitialized_",
-              "aLLCAPS_",
-              "aLLCAPSMAP_",
-              ALLCAPSMAPDefaultEntryHolder.defaultEntry,
-              "hasUnderbarPrecedingNumeric1Foo_",
-              "extension_",
-              "hasUnderbarPrecedingNumeric42Bar_",
-              "hasUnderbarPrecedingNumeric123Foo42BarBaz_",
-              "class__",
-              "int_",
-              "long_",
-              "boolean_",
-              "sealed_",
-              "interface_",
-              "in_",
-              "object_",
-              "cachedSize__",
-              "serializedSize__",
-              "by_",
-            };
-            java.lang.String info =
-                "\u0001\u0016\u0001\u0001\u0001\u0019\u0016\u0001\u0003\u0000\u0001\u1007\u0000\u0002" +
-                "\u1007\u0001\u0003\u1008\u0002\u0004\u1007\u0003\u0005\u103b\u0000\u0007\u001a\b" +
-                "2\t\u1007\u0005\f\u001a\r\u1007\u0006\u000e\u1007\u0007\u000f\u0016\u0010\u1000\b" +
-                "\u0011\u1007\t\u0012\u1002\n\u0013\u1008\u000b\u0014\u1001\f\u0015\u1004\r\u0016" +
-                "\u1008\u000e\u0017\u1008\u000f\u0018\u1007\u0010\u0019\u1008\u0011";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2> parser = PARSER;
-          if (parser == null) {
-            synchronized (evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:evil_names_proto2.EvilNamesProto2)
-    private static final evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2 DEFAULT_INSTANCE;
-    static {
-      EvilNamesProto2 defaultInstance = new EvilNamesProto2();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        EvilNamesProto2.class, defaultInstance);
-    }
-
-    public static evil_names_proto2.EvilNamesProto2OuterClass.EvilNamesProto2 getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<EvilNamesProto2> PARSER;
-
-    public static com.google.protobuf.Parser<EvilNamesProto2> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface HardKeywordsAllTypesOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:evil_names_proto2.HardKeywordsAllTypes)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional int32 as = 1;</code>
-     * @return Whether the as field is set.
-     */
-    boolean hasAs();
-    /**
-     * <code>optional int32 as = 1;</code>
-     * @return The as.
-     */
-    int getAs();
-
-    /**
-     * <code>optional string in = 2;</code>
-     * @return Whether the in field is set.
-     */
-    boolean hasIn();
-    /**
-     * <code>optional string in = 2;</code>
-     * @return The in.
-     */
-    java.lang.String getIn();
-    /**
-     * <code>optional string in = 2;</code>
-     * @return The bytes for in.
-     */
-    com.google.protobuf.ByteString
-        getInBytes();
-
-    /**
-     * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     * @return Whether the break field is set.
-     */
-    boolean hasBreak();
-    /**
-     * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     * @return The break.
-     */
-    evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum getBreak();
-
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    int getContinueCount();
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    boolean containsContinue(
-        int key);
-    /**
-     * Use {@link #getContinueMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getContinue();
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getContinueMap();
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-
-    int getContinueOrDefault(
-        int key,
-        int defaultValue);
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-
-    int getContinueOrThrow(
-        int key);
-
-    /**
-     * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     * @return Whether the do field is set.
-     */
-    boolean hasDo();
-    /**
-     * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     * @return The do.
-     */
-    evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage getDo();
-
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @return A list containing the else.
-     */
-    java.util.List<java.lang.Integer> getElseList();
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @return The count of else.
-     */
-    int getElseCount();
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @param index The index of the element to return.
-     * @return The else at the given index.
-     */
-    int getElse(int index);
-
-    /**
-     * <code>repeated string for = 7;</code>
-     * @return A list containing the for.
-     */
-    java.util.List<java.lang.String>
-        getForList();
-    /**
-     * <code>repeated string for = 7;</code>
-     * @return The count of for.
-     */
-    int getForCount();
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param index The index of the element to return.
-     * @return The for at the given index.
-     */
-    java.lang.String getFor(int index);
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param index The index of the element to return.
-     * @return The for at the given index.
-     */
-    com.google.protobuf.ByteString
-        getForBytes(int index);
-
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @return A list containing the fun.
-     */
-    java.util.List<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum> getFunList();
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @return The count of fun.
-     */
-    int getFunCount();
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param index The index of the element to return.
-     * @return The fun at the given index.
-     */
-    evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum getFun(int index);
-
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    java.util.List<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage> 
-        getIfList();
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage getIf(int index);
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    int getIfCount();
-  }
-  /**
-   * Protobuf type {@code evil_names_proto2.HardKeywordsAllTypes}
-   */
-  public  static final class HardKeywordsAllTypes extends
-      com.google.protobuf.GeneratedMessageLite<
-          HardKeywordsAllTypes, HardKeywordsAllTypes.Builder> implements
-      // @@protoc_insertion_point(message_implements:evil_names_proto2.HardKeywordsAllTypes)
-      HardKeywordsAllTypesOrBuilder {
-    private HardKeywordsAllTypes() {
-      in_ = "";
-      break_ = 1;
-      else_ = emptyIntList();
-      for_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      fun_ = emptyIntList();
-      if_ = emptyProtobufList();
-    }
-    /**
-     * Protobuf enum {@code evil_names_proto2.HardKeywordsAllTypes.NestedEnum}
-     */
-    public enum NestedEnum
-        implements com.google.protobuf.Internal.EnumLite {
-      /**
-       * <code>FOO = 1;</code>
-       */
-      FOO(1),
-      /**
-       * <code>BAR = 2;</code>
-       */
-      BAR(2),
-      ;
-
-      /**
-       * <code>FOO = 1;</code>
-       */
-      public static final int FOO_VALUE = 1;
-      /**
-       * <code>BAR = 2;</code>
-       */
-      public static final int BAR_VALUE = 2;
-
-
-      @java.lang.Override
-      public final int getNumber() {
-        return value;
-      }
-
-      /**
-       * @param value The number of the enum to look for.
-       * @return The enum associated with the given number.
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static NestedEnum valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static NestedEnum forNumber(int value) {
-        switch (value) {
-          case 1: return FOO;
-          case 2: return BAR;
-          default: return null;
-        }
-      }
-
-      public static com.google.protobuf.Internal.EnumLiteMap<NestedEnum>
-          internalGetValueMap() {
-        return internalValueMap;
-      }
-      private static final com.google.protobuf.Internal.EnumLiteMap<
-          NestedEnum> internalValueMap =
-            new com.google.protobuf.Internal.EnumLiteMap<NestedEnum>() {
-              @java.lang.Override
-              public NestedEnum findValueByNumber(int number) {
-                return NestedEnum.forNumber(number);
-              }
-            };
-
-      public static com.google.protobuf.Internal.EnumVerifier 
-          internalGetVerifier() {
-        return NestedEnumVerifier.INSTANCE;
-      }
-
-      private static final class NestedEnumVerifier implements 
-           com.google.protobuf.Internal.EnumVerifier { 
-              static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new NestedEnumVerifier();
-              @java.lang.Override
-              public boolean isInRange(int number) {
-                return NestedEnum.forNumber(number) != null;
-              }
-            };
-
-      private final int value;
-
-      private NestedEnum(int value) {
-        this.value = value;
-      }
-
-      // @@protoc_insertion_point(enum_scope:evil_names_proto2.HardKeywordsAllTypes.NestedEnum)
-    }
-
-    public interface NestedMessageOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:evil_names_proto2.HardKeywordsAllTypes.NestedMessage)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int32 while = 1;</code>
-       * @return Whether the while field is set.
-       */
-      boolean hasWhile();
-      /**
-       * <code>optional int32 while = 1;</code>
-       * @return The while.
-       */
-      int getWhile();
-    }
-    /**
-     * Protobuf type {@code evil_names_proto2.HardKeywordsAllTypes.NestedMessage}
-     */
-    public  static final class NestedMessage extends
-        com.google.protobuf.GeneratedMessageLite<
-            NestedMessage, NestedMessage.Builder> implements
-        // @@protoc_insertion_point(message_implements:evil_names_proto2.HardKeywordsAllTypes.NestedMessage)
-        NestedMessageOrBuilder {
-      private NestedMessage() {
-      }
-      private int bitField0_;
-      public static final int WHILE_FIELD_NUMBER = 1;
-      private int while_;
-      /**
-       * <code>optional int32 while = 1;</code>
-       * @return Whether the while field is set.
-       */
-      @java.lang.Override
-      public boolean hasWhile() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int32 while = 1;</code>
-       * @return The while.
-       */
-      @java.lang.Override
-      public int getWhile() {
-        return while_;
-      }
-      /**
-       * <code>optional int32 while = 1;</code>
-       * @param value The while to set.
-       */
-      private void setWhile(int value) {
-        bitField0_ |= 0x00000001;
-        while_ = value;
-      }
-      /**
-       * <code>optional int32 while = 1;</code>
-       */
-      private void clearWhile() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        while_ = 0;
-      }
-
-      public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code evil_names_proto2.HardKeywordsAllTypes.NestedMessage}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage, Builder> implements
-          // @@protoc_insertion_point(builder_implements:evil_names_proto2.HardKeywordsAllTypes.NestedMessage)
-          evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessageOrBuilder {
-        // Construct using evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int32 while = 1;</code>
-         * @return Whether the while field is set.
-         */
-        @java.lang.Override
-        public boolean hasWhile() {
-          return instance.hasWhile();
-        }
-        /**
-         * <code>optional int32 while = 1;</code>
-         * @return The while.
-         */
-        @java.lang.Override
-        public int getWhile() {
-          return instance.getWhile();
-        }
-        /**
-         * <code>optional int32 while = 1;</code>
-         * @param value The while to set.
-         * @return This builder for chaining.
-         */
-        public Builder setWhile(int value) {
-          copyOnWrite();
-          instance.setWhile(value);
-          return this;
-        }
-        /**
-         * <code>optional int32 while = 1;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearWhile() {
-          copyOnWrite();
-          instance.clearWhile();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:evil_names_proto2.HardKeywordsAllTypes.NestedMessage)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "while_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1004\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage> parser = PARSER;
-            if (parser == null) {
-              synchronized (evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:evil_names_proto2.HardKeywordsAllTypes.NestedMessage)
-      private static final evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage DEFAULT_INSTANCE;
-      static {
-        NestedMessage defaultInstance = new NestedMessage();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          NestedMessage.class, defaultInstance);
-      }
-
-      public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<NestedMessage> PARSER;
-
-      public static com.google.protobuf.Parser<NestedMessage> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int bitField0_;
-    public static final int AS_FIELD_NUMBER = 1;
-    private int as_;
-    /**
-     * <code>optional int32 as = 1;</code>
-     * @return Whether the as field is set.
-     */
-    @java.lang.Override
-    public boolean hasAs() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 as = 1;</code>
-     * @return The as.
-     */
-    @java.lang.Override
-    public int getAs() {
-      return as_;
-    }
-    /**
-     * <code>optional int32 as = 1;</code>
-     * @param value The as to set.
-     */
-    private void setAs(int value) {
-      bitField0_ |= 0x00000001;
-      as_ = value;
-    }
-    /**
-     * <code>optional int32 as = 1;</code>
-     */
-    private void clearAs() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      as_ = 0;
-    }
-
-    public static final int IN_FIELD_NUMBER = 2;
-    private java.lang.String in_;
-    /**
-     * <code>optional string in = 2;</code>
-     * @return Whether the in field is set.
-     */
-    @java.lang.Override
-    public boolean hasIn() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional string in = 2;</code>
-     * @return The in.
-     */
-    @java.lang.Override
-    public java.lang.String getIn() {
-      return in_;
-    }
-    /**
-     * <code>optional string in = 2;</code>
-     * @return The bytes for in.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getInBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(in_);
-    }
-    /**
-     * <code>optional string in = 2;</code>
-     * @param value The in to set.
-     */
-    private void setIn(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00000002;
-      in_ = value;
-    }
-    /**
-     * <code>optional string in = 2;</code>
-     */
-    private void clearIn() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      in_ = getDefaultInstance().getIn();
-    }
-    /**
-     * <code>optional string in = 2;</code>
-     * @param value The bytes for in to set.
-     */
-    private void setInBytes(
-        com.google.protobuf.ByteString value) {
-      in_ = value.toStringUtf8();
-      bitField0_ |= 0x00000002;
-    }
-
-    public static final int BREAK_FIELD_NUMBER = 3;
-    private int break_;
-    /**
-     * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     * @return Whether the break field is set.
-     */
-    @java.lang.Override
-    public boolean hasBreak() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     * @return The break.
-     */
-    @java.lang.Override
-    public evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum getBreak() {
-      evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum result = evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum.forNumber(break_);
-      return result == null ? evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum.FOO : result;
-    }
-    /**
-     * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     * @param value The break to set.
-     */
-    private void setBreak(evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum value) {
-      break_ = value.getNumber();
-      bitField0_ |= 0x00000004;
-    }
-    /**
-     * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     */
-    private void clearBreak() {
-      bitField0_ = (bitField0_ & ~0x00000004);
-      break_ = 1;
-    }
-
-    public static final int CONTINUE_FIELD_NUMBER = 4;
-    private static final class ContinueDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> continue_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetContinue() {
-      return continue_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableContinue() {
-      if (!continue_.isMutable()) {
-        continue_ = continue_.mutableCopy();
-      }
-      return continue_;
-    }
-    @java.lang.Override
-
-    public int getContinueCount() {
-      return internalGetContinue().size();
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsContinue(
-        int key) {
-      
-      return internalGetContinue().containsKey(key);
-    }
-    /**
-     * Use {@link #getContinueMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getContinue() {
-      return getContinueMap();
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getContinueMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetContinue());
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    @java.lang.Override
-
-    public int getContinueOrDefault(
-        int key,
-        int defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetContinue();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    @java.lang.Override
-
-    public int getContinueOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetContinue();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMutableContinueMap() {
-      return internalGetMutableContinue();
-    }
-
-    public static final int DO_FIELD_NUMBER = 5;
-    private evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage do_;
-    /**
-     * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     */
-    @java.lang.Override
-    public boolean hasDo() {
-      return ((bitField0_ & 0x00000008) != 0);
-    }
-    /**
-     * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     */
-    @java.lang.Override
-    public evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage getDo() {
-      return do_ == null ? evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage.getDefaultInstance() : do_;
-    }
-    /**
-     * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     */
-    private void setDo(evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-      value.getClass();
-  do_ = value;
-      bitField0_ |= 0x00000008;
-      }
-    /**
-     * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeDo(evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-      value.getClass();
-  if (do_ != null &&
-          do_ != evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage.getDefaultInstance()) {
-        do_ =
-          evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage.newBuilder(do_).mergeFrom(value).buildPartial();
-      } else {
-        do_ = value;
-      }
-      bitField0_ |= 0x00000008;
-    }
-    /**
-     * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     */
-    private void clearDo() {  do_ = null;
-      bitField0_ = (bitField0_ & ~0x00000008);
-    }
-
-    public static final int ELSE_FIELD_NUMBER = 6;
-    private com.google.protobuf.Internal.IntList else_;
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @return A list containing the else.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getElseList() {
-      return else_;
-    }
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @return The count of else.
-     */
-    @java.lang.Override
-    public int getElseCount() {
-      return else_.size();
-    }
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @param index The index of the element to return.
-     * @return The else at the given index.
-     */
-    @java.lang.Override
-    public int getElse(int index) {
-      return else_.getInt(index);
-    }
-    private void ensureElseIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = else_;
-      if (!tmp.isModifiable()) {
-        else_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @param index The index to set the value at.
-     * @param value The else to set.
-     */
-    private void setElse(
-        int index, int value) {
-      ensureElseIsMutable();
-      else_.setInt(index, value);
-    }
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @param value The else to add.
-     */
-    private void addElse(int value) {
-      ensureElseIsMutable();
-      else_.addInt(value);
-    }
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @param values The else to add.
-     */
-    private void addAllElse(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureElseIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, else_);
-    }
-    /**
-     * <code>repeated int32 else = 6;</code>
-     */
-    private void clearElse() {
-      else_ = emptyIntList();
-    }
-
-    public static final int FOR_FIELD_NUMBER = 7;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> for_;
-    /**
-     * <code>repeated string for = 7;</code>
-     * @return A list containing the for.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getForList() {
-      return for_;
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @return The count of for.
-     */
-    @java.lang.Override
-    public int getForCount() {
-      return for_.size();
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param index The index of the element to return.
-     * @return The for at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getFor(int index) {
-      return for_.get(index);
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the for at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getForBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          for_.get(index));
-    }
-    private void ensureForIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          for_;  if (!tmp.isModifiable()) {
-        for_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param index The index to set the value at.
-     * @param value The for to set.
-     */
-    private void setFor(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureForIsMutable();
-      for_.set(index, value);
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param value The for to add.
-     */
-    private void addFor(
-        java.lang.String value) {
-      value.getClass();
-  ensureForIsMutable();
-      for_.add(value);
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param values The for to add.
-     */
-    private void addAllFor(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureForIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, for_);
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     */
-    private void clearFor() {
-      for_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param value The bytes of the for to add.
-     */
-    private void addForBytes(
-        com.google.protobuf.ByteString value) {
-      ensureForIsMutable();
-      for_.add(value.toStringUtf8());
-    }
-
-    public static final int FUN_FIELD_NUMBER = 8;
-    private com.google.protobuf.Internal.IntList fun_;
-    private static final com.google.protobuf.Internal.ListAdapter.Converter<
-        java.lang.Integer, evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum> fun_converter_ =
-            new com.google.protobuf.Internal.ListAdapter.Converter<
-                java.lang.Integer, evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum>() {
-              @java.lang.Override
-              public evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum convert(java.lang.Integer from) {
-                evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum result = evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum.forNumber(from);
-                return result == null ? evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum.FOO : result;
-              }
-            };
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @return A list containing the fun.
-     */
-    @java.lang.Override
-    public java.util.List<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum> getFunList() {
-      return new com.google.protobuf.Internal.ListAdapter<
-          java.lang.Integer, evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum>(fun_, fun_converter_);
-    }
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @return The count of fun.
-     */
-    @java.lang.Override
-    public int getFunCount() {
-      return fun_.size();
-    }
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param index The index of the element to return.
-     * @return The fun at the given index.
-     */
-    @java.lang.Override
-    public evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum getFun(int index) {
-      return fun_converter_.convert(fun_.getInt(index));
-    }
-    private void ensureFunIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = fun_;
-      if (!tmp.isModifiable()) {
-        fun_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-      }
-    }
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param index The index to set the value at.
-     * @param value The fun to set.
-     */
-    private void setFun(
-        int index, evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum value) {
-      value.getClass();
-  ensureFunIsMutable();
-      fun_.setInt(index, value.getNumber());
-    }
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param value The fun to add.
-     */
-    private void addFun(evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum value) {
-      value.getClass();
-  ensureFunIsMutable();
-      fun_.addInt(value.getNumber());
-    }
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param values The fun to add.
-     */
-    private void addAllFun(
-        java.lang.Iterable<? extends evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum> values) {
-      ensureFunIsMutable();
-      for (evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum value : values) {
-        fun_.addInt(value.getNumber());
-      }
-    }
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     */
-    private void clearFun() {
-      fun_ = emptyIntList();
-    }
-
-    public static final int IF_FIELD_NUMBER = 9;
-    private com.google.protobuf.Internal.ProtobufList<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage> if_;
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    @java.lang.Override
-    public java.util.List<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage> getIfList() {
-      return if_;
-    }
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    public java.util.List<? extends evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessageOrBuilder> 
-        getIfOrBuilderList() {
-      return if_;
-    }
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    @java.lang.Override
-    public int getIfCount() {
-      return if_.size();
-    }
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    @java.lang.Override
-    public evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage getIf(int index) {
-      return if_.get(index);
-    }
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    public evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessageOrBuilder getIfOrBuilder(
-        int index) {
-      return if_.get(index);
-    }
-    private void ensureIfIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage> tmp = if_;
-      if (!tmp.isModifiable()) {
-        if_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    private void setIf(
-        int index, evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-      value.getClass();
-  ensureIfIsMutable();
-      if_.set(index, value);
-    }
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    private void addIf(evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-      value.getClass();
-  ensureIfIsMutable();
-      if_.add(value);
-    }
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    private void addIf(
-        int index, evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-      value.getClass();
-  ensureIfIsMutable();
-      if_.add(index, value);
-    }
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    private void addAllIf(
-        java.lang.Iterable<? extends evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage> values) {
-      ensureIfIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, if_);
-    }
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    private void clearIf() {
-      if_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    private void removeIf(int index) {
-      ensureIfIsMutable();
-      if_.remove(index);
-    }
-
-    public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code evil_names_proto2.HardKeywordsAllTypes}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes, Builder> implements
-        // @@protoc_insertion_point(builder_implements:evil_names_proto2.HardKeywordsAllTypes)
-        evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypesOrBuilder {
-      // Construct using evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int32 as = 1;</code>
-       * @return Whether the as field is set.
-       */
-      @java.lang.Override
-      public boolean hasAs() {
-        return instance.hasAs();
-      }
-      /**
-       * <code>optional int32 as = 1;</code>
-       * @return The as.
-       */
-      @java.lang.Override
-      public int getAs() {
-        return instance.getAs();
-      }
-      /**
-       * <code>optional int32 as = 1;</code>
-       * @param value The as to set.
-       * @return This builder for chaining.
-       */
-      public Builder setAs(int value) {
-        copyOnWrite();
-        instance.setAs(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 as = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearAs() {
-        copyOnWrite();
-        instance.clearAs();
-        return this;
-      }
-
-      /**
-       * <code>optional string in = 2;</code>
-       * @return Whether the in field is set.
-       */
-      @java.lang.Override
-      public boolean hasIn() {
-        return instance.hasIn();
-      }
-      /**
-       * <code>optional string in = 2;</code>
-       * @return The in.
-       */
-      @java.lang.Override
-      public java.lang.String getIn() {
-        return instance.getIn();
-      }
-      /**
-       * <code>optional string in = 2;</code>
-       * @return The bytes for in.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getInBytes() {
-        return instance.getInBytes();
-      }
-      /**
-       * <code>optional string in = 2;</code>
-       * @param value The in to set.
-       * @return This builder for chaining.
-       */
-      public Builder setIn(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setIn(value);
-        return this;
-      }
-      /**
-       * <code>optional string in = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearIn() {
-        copyOnWrite();
-        instance.clearIn();
-        return this;
-      }
-      /**
-       * <code>optional string in = 2;</code>
-       * @param value The bytes for in to set.
-       * @return This builder for chaining.
-       */
-      public Builder setInBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setInBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-       * @return Whether the break field is set.
-       */
-      @java.lang.Override
-      public boolean hasBreak() {
-        return instance.hasBreak();
-      }
-      /**
-       * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-       * @return The break.
-       */
-      @java.lang.Override
-      public evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum getBreak() {
-        return instance.getBreak();
-      }
-      /**
-       * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-       * @param value The enum numeric value on the wire for break to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBreak(evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum value) {
-        copyOnWrite();
-        instance.setBreak(value);
-        return this;
-      }
-      /**
-       * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearBreak() {
-        copyOnWrite();
-        instance.clearBreak();
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getContinueCount() {
-        return instance.getContinueMap().size();
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; continue = 4;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsContinue(
-          int key) {
-        
-        return instance.getContinueMap().containsKey(key);
-      }
-
-      public Builder clearContinue() {
-        copyOnWrite();
-        instance.getMutableContinueMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; continue = 4;</code>
-       */
-
-      public Builder removeContinue(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableContinueMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getContinueMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getContinue() {
-        return getContinueMap();
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; continue = 4;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getContinueMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getContinueMap());
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; continue = 4;</code>
-       */
-      @java.lang.Override
-
-      public int getContinueOrDefault(
-          int key,
-          int defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getContinueMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; continue = 4;</code>
-       */
-      @java.lang.Override
-
-      public int getContinueOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getContinueMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; continue = 4;</code>
-       */
-      public Builder putContinue(
-          int key,
-          int value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableContinueMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; continue = 4;</code>
-       */
-      public Builder putAllContinue(
-          java.util.Map<java.lang.Integer, java.lang.Integer> values) {
-        copyOnWrite();
-        instance.getMutableContinueMap().putAll(values);
-        return this;
-      }
-
-      /**
-       * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-       */
-      @java.lang.Override
-      public boolean hasDo() {
-        return instance.hasDo();
-      }
-      /**
-       * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-       */
-      @java.lang.Override
-      public evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage getDo() {
-        return instance.getDo();
-      }
-      /**
-       * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-       */
-      public Builder setDo(evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.setDo(value);
-        return this;
-        }
-      /**
-       * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-       */
-      public Builder setDo(
-          evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setDo(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-       */
-      public Builder mergeDo(evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.mergeDo(value);
-        return this;
-      }
-      /**
-       * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-       */
-      public Builder clearDo() {  copyOnWrite();
-        instance.clearDo();
-        return this;
-      }
-
-      /**
-       * <code>repeated int32 else = 6;</code>
-       * @return A list containing the else.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getElseList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getElseList());
-      }
-      /**
-       * <code>repeated int32 else = 6;</code>
-       * @return The count of else.
-       */
-      @java.lang.Override
-      public int getElseCount() {
-        return instance.getElseCount();
-      }
-      /**
-       * <code>repeated int32 else = 6;</code>
-       * @param index The index of the element to return.
-       * @return The else at the given index.
-       */
-      @java.lang.Override
-      public int getElse(int index) {
-        return instance.getElse(index);
-      }
-      /**
-       * <code>repeated int32 else = 6;</code>
-       * @param value The else to set.
-       * @return This builder for chaining.
-       */
-      public Builder setElse(
-          int index, int value) {
-        copyOnWrite();
-        instance.setElse(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 else = 6;</code>
-       * @param value The else to add.
-       * @return This builder for chaining.
-       */
-      public Builder addElse(int value) {
-        copyOnWrite();
-        instance.addElse(value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 else = 6;</code>
-       * @param values The else to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllElse(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllElse(values);
-        return this;
-      }
-      /**
-       * <code>repeated int32 else = 6;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearElse() {
-        copyOnWrite();
-        instance.clearElse();
-        return this;
-      }
-
-      /**
-       * <code>repeated string for = 7;</code>
-       * @return A list containing the for.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getForList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getForList());
-      }
-      /**
-       * <code>repeated string for = 7;</code>
-       * @return The count of for.
-       */
-      @java.lang.Override
-      public int getForCount() {
-        return instance.getForCount();
-      }
-      /**
-       * <code>repeated string for = 7;</code>
-       * @param index The index of the element to return.
-       * @return The for at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getFor(int index) {
-        return instance.getFor(index);
-      }
-      /**
-       * <code>repeated string for = 7;</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the for at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getForBytes(int index) {
-        return instance.getForBytes(index);
-      }
-      /**
-       * <code>repeated string for = 7;</code>
-       * @param index The index to set the value at.
-       * @param value The for to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFor(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setFor(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string for = 7;</code>
-       * @param value The for to add.
-       * @return This builder for chaining.
-       */
-      public Builder addFor(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addFor(value);
-        return this;
-      }
-      /**
-       * <code>repeated string for = 7;</code>
-       * @param values The for to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllFor(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllFor(values);
-        return this;
-      }
-      /**
-       * <code>repeated string for = 7;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFor() {
-        copyOnWrite();
-        instance.clearFor();
-        return this;
-      }
-      /**
-       * <code>repeated string for = 7;</code>
-       * @param value The bytes of the for to add.
-       * @return This builder for chaining.
-       */
-      public Builder addForBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addForBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-       * @return A list containing the fun.
-       */
-      @java.lang.Override
-      public java.util.List<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum> getFunList() {
-        return instance.getFunList();
-      }
-      /**
-       * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-       * @return The count of fun.
-       */
-      @java.lang.Override
-      public int getFunCount() {
-        return instance.getFunCount();
-      }
-      /**
-       * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-       * @param index The index of the element to return.
-       * @return The fun at the given index.
-       */
-      @java.lang.Override
-      public evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum getFun(int index) {
-        return instance.getFun(index);
-      }
-      /**
-       * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-       * @param index The index to set the value at.
-       * @param value The fun to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFun(
-          int index, evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum value) {
-        copyOnWrite();
-        instance.setFun(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-       * @param value The fun to add.
-       * @return This builder for chaining.
-       */
-      public Builder addFun(evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum value) {
-        copyOnWrite();
-        instance.addFun(value);
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-       * @param values The fun to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllFun(
-          java.lang.Iterable<? extends evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum> values) {
-        copyOnWrite();
-        instance.addAllFun(values);  return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFun() {
-        copyOnWrite();
-        instance.clearFun();
-        return this;
-      }
-
-      /**
-       * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      @java.lang.Override
-      public java.util.List<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage> getIfList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getIfList());
-      }
-      /**
-       * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      @java.lang.Override
-      public int getIfCount() {
-        return instance.getIfCount();
-      }/**
-       * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      @java.lang.Override
-      public evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage getIf(int index) {
-        return instance.getIf(index);
-      }
-      /**
-       * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      public Builder setIf(
-          int index, evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.setIf(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      public Builder setIf(
-          int index, evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setIf(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      public Builder addIf(evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.addIf(value);
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      public Builder addIf(
-          int index, evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.addIf(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      public Builder addIf(
-          evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addIf(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      public Builder addIf(
-          int index, evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addIf(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      public Builder addAllIf(
-          java.lang.Iterable<? extends evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage> values) {
-        copyOnWrite();
-        instance.addAllIf(values);
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      public Builder clearIf() {
-        copyOnWrite();
-        instance.clearIf();
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      public Builder removeIf(int index) {
-        copyOnWrite();
-        instance.removeIf(index);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:evil_names_proto2.HardKeywordsAllTypes)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "as_",
-              "in_",
-              "break_",
-              evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum.internalGetVerifier(),
-              "continue_",
-              ContinueDefaultEntryHolder.defaultEntry,
-              "do_",
-              "else_",
-              "for_",
-              "fun_",
-              evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum.internalGetVerifier(),
-              "if_",
-              evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage.class,
-            };
-            java.lang.String info =
-                "\u0001\t\u0000\u0001\u0001\t\t\u0001\u0004\u0000\u0001\u1004\u0000\u0002\u1008\u0001" +
-                "\u0003\u100c\u0002\u00042\u0005\u1009\u0003\u0006\u0016\u0007\u001a\b\u001e\t\u001b" +
-                "";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes> parser = PARSER;
-          if (parser == null) {
-            synchronized (evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:evil_names_proto2.HardKeywordsAllTypes)
-    private static final evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes DEFAULT_INSTANCE;
-    static {
-      HardKeywordsAllTypes defaultInstance = new HardKeywordsAllTypes();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        HardKeywordsAllTypes.class, defaultInstance);
-    }
-
-    public static evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<HardKeywordsAllTypes> PARSER;
-
-    public static com.google.protobuf.Parser<HardKeywordsAllTypes> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface InterfaceOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:evil_names_proto2.Interface)
-      com.google.protobuf.MessageLiteOrBuilder {
-  }
-  /**
-   * Protobuf type {@code evil_names_proto2.Interface}
-   */
-  public  static final class Interface extends
-      com.google.protobuf.GeneratedMessageLite<
-          Interface, Interface.Builder> implements
-      // @@protoc_insertion_point(message_implements:evil_names_proto2.Interface)
-      InterfaceOrBuilder {
-    private Interface() {
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.Interface parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.Interface parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.Interface parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.Interface parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.Interface parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.Interface parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.Interface parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.Interface parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.Interface parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.Interface parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.Interface parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static evil_names_proto2.EvilNamesProto2OuterClass.Interface parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(evil_names_proto2.EvilNamesProto2OuterClass.Interface prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code evil_names_proto2.Interface}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          evil_names_proto2.EvilNamesProto2OuterClass.Interface, Builder> implements
-        // @@protoc_insertion_point(builder_implements:evil_names_proto2.Interface)
-        evil_names_proto2.EvilNamesProto2OuterClass.InterfaceOrBuilder {
-      // Construct using evil_names_proto2.EvilNamesProto2OuterClass.Interface.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:evil_names_proto2.Interface)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new evil_names_proto2.EvilNamesProto2OuterClass.Interface();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<evil_names_proto2.EvilNamesProto2OuterClass.Interface> parser = PARSER;
-          if (parser == null) {
-            synchronized (evil_names_proto2.EvilNamesProto2OuterClass.Interface.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<evil_names_proto2.EvilNamesProto2OuterClass.Interface>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:evil_names_proto2.Interface)
-    private static final evil_names_proto2.EvilNamesProto2OuterClass.Interface DEFAULT_INSTANCE;
-    static {
-      Interface defaultInstance = new Interface();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        Interface.class, defaultInstance);
-    }
-
-    public static evil_names_proto2.EvilNamesProto2OuterClass.Interface getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<Interface> PARSER;
-
-    public static com.google.protobuf.Parser<Interface> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/evil_names_proto2/EvilNamesProto2OuterClassKt.kt b/java/kotlin-lite/target/generated-test-sources/evil_names_proto2/EvilNamesProto2OuterClassKt.kt
deleted file mode 100644
index e69de29..0000000
--- a/java/kotlin-lite/target/generated-test-sources/evil_names_proto2/EvilNamesProto2OuterClassKt.kt
+++ /dev/null
diff --git a/java/kotlin-lite/target/generated-test-sources/evil_names_proto2/HardKeywordsAllTypesKt.kt b/java/kotlin-lite/target/generated-test-sources/evil_names_proto2/HardKeywordsAllTypesKt.kt
deleted file mode 100644
index b47bd85..0000000
--- a/java/kotlin-lite/target/generated-test-sources/evil_names_proto2/HardKeywordsAllTypesKt.kt
+++ /dev/null
@@ -1,486 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: com/google/protobuf/evil_names_proto2.proto
-
-package evil_names_proto2;
-
-@kotlin.jvm.JvmSynthetic
-inline fun hardKeywordsAllTypes(block: evil_names_proto2.HardKeywordsAllTypesKt.Dsl.() -> Unit): evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes =
-  evil_names_proto2.HardKeywordsAllTypesKt.Dsl._create(evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.newBuilder()).apply { block() }._build()
-object HardKeywordsAllTypesKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes = _builder.build()
-
-    /**
-     * <code>optional int32 as = 1;</code>
-     */
-    var as_: kotlin.Int
-      @JvmName("getAs_")
-      get() = _builder.getAs()
-      @JvmName("setAs_")
-      set(value) {
-        _builder.setAs(value)
-      }
-    /**
-     * <code>optional int32 as = 1;</code>
-     */
-    fun clearAs_() {
-      _builder.clearAs()
-    }
-    /**
-     * <code>optional int32 as = 1;</code>
-     * @return Whether the as field is set.
-     */
-    fun hasAs_(): kotlin.Boolean {
-      return _builder.hasAs()
-    }
-
-    /**
-     * <code>optional string in = 2;</code>
-     */
-    var in_: kotlin.String
-      @JvmName("getIn_")
-      get() = _builder.getIn()
-      @JvmName("setIn_")
-      set(value) {
-        _builder.setIn(value)
-      }
-    /**
-     * <code>optional string in = 2;</code>
-     */
-    fun clearIn_() {
-      _builder.clearIn()
-    }
-    /**
-     * <code>optional string in = 2;</code>
-     * @return Whether the in field is set.
-     */
-    fun hasIn_(): kotlin.Boolean {
-      return _builder.hasIn()
-    }
-
-    /**
-     * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     */
-    var break_: evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum
-      @JvmName("getBreak_")
-      get() = _builder.getBreak()
-      @JvmName("setBreak_")
-      set(value) {
-        _builder.setBreak(value)
-      }
-    /**
-     * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     */
-    fun clearBreak_() {
-      _builder.clearBreak()
-    }
-    /**
-     * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     * @return Whether the break field is set.
-     */
-    fun hasBreak_(): kotlin.Boolean {
-      return _builder.hasBreak()
-    }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class Continue_Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-     val continue_: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, Continue_Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getContinue_Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getContinueMap()
-      )
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    @JvmName("putContinue_")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, Continue_Proxy>
-      .put(key: kotlin.Int, value: kotlin.Int) {
-         _builder.putContinue(key, value)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setContinue_")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, Continue_Proxy>
-      .set(key: kotlin.Int, value: kotlin.Int) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeContinue_")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, Continue_Proxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeContinue(key)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllContinue_")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, Continue_Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Int>) {
-         _builder.putAllContinue(map)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearContinue_")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, Continue_Proxy>
-      .clear() {
-         _builder.clearContinue()
-       }
-
-    /**
-     * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     */
-    var do_: evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage
-      @JvmName("getDo_")
-      get() = _builder.getDo()
-      @JvmName("setDo_")
-      set(value) {
-        _builder.setDo(value)
-      }
-    /**
-     * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     */
-    fun clearDo_() {
-      _builder.clearDo()
-    }
-    /**
-     * <code>optional .evil_names_proto2.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     * @return Whether the do field is set.
-     */
-    fun hasDo_(): kotlin.Boolean {
-      return _builder.hasDo()
-    }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class Else_Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated int32 else = 6;</code>
-     */
-     val else_: com.google.protobuf.kotlin.DslList<kotlin.Int, Else_Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getElseList()
-      )
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @param value The else to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addElse_")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, Else_Proxy>.add(value: kotlin.Int) {
-      _builder.addElse(value)
-    }/**
-     * <code>repeated int32 else = 6;</code>
-     * @param value The else to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignElse_")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, Else_Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated int32 else = 6;</code>
-     * @param values The else to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllElse_")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, Else_Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllElse(values)
-    }/**
-     * <code>repeated int32 else = 6;</code>
-     * @param values The else to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllElse_")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, Else_Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated int32 else = 6;</code>
-     * @param index The index to set the value at.
-     * @param value The else to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setElse_")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, Else_Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setElse(index, value)
-    }/**
-     * <code>repeated int32 else = 6;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearElse_")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, Else_Proxy>.clear() {
-      _builder.clearElse()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class For_Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated string for = 7;</code>
-     * @return A list containing the for.
-     */
-    val for_: com.google.protobuf.kotlin.DslList<kotlin.String, For_Proxy>
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getForList()
-      )
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param value The for to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addFor_")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, For_Proxy>.add(value: kotlin.String) {
-      _builder.addFor(value)
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param value The for to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignFor_")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, For_Proxy>.plusAssign(value: kotlin.String) {
-      add(value)
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param values The for to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllFor_")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, For_Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.String>) {
-      _builder.addAllFor(values)
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param values The for to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllFor_")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, For_Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.String>) {
-      addAll(values)
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param index The index to set the value at.
-     * @param value The for to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setFor_")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.String, For_Proxy>.set(index: kotlin.Int, value: kotlin.String) {
-      _builder.setFor(index, value)
-    }/**
-     * <code>repeated string for = 7;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearFor_")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, For_Proxy>.clear() {
-      _builder.clearFor()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class Fun_Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     */
-     val fun_: com.google.protobuf.kotlin.DslList<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum, Fun_Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getFunList()
-      )
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param value The fun to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addFun_")
-    fun com.google.protobuf.kotlin.DslList<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum, Fun_Proxy>.add(value: evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum) {
-      _builder.addFun(value)
-    }/**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param value The fun to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignFun_")
-    inline operator fun com.google.protobuf.kotlin.DslList<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum, Fun_Proxy>.plusAssign(value: evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum) {
-      add(value)
-    }/**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param values The fun to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllFun_")
-    fun com.google.protobuf.kotlin.DslList<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum, Fun_Proxy>.addAll(values: kotlin.collections.Iterable<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum>) {
-      _builder.addAllFun(values)
-    }/**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param values The fun to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllFun_")
-    inline operator fun com.google.protobuf.kotlin.DslList<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum, Fun_Proxy>.plusAssign(values: kotlin.collections.Iterable<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum>) {
-      addAll(values)
-    }/**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param index The index to set the value at.
-     * @param value The fun to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setFun_")
-    operator fun com.google.protobuf.kotlin.DslList<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum, Fun_Proxy>.set(index: kotlin.Int, value: evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum) {
-      _builder.setFun(index, value)
-    }/**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearFun_")
-    fun com.google.protobuf.kotlin.DslList<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedEnum, Fun_Proxy>.clear() {
-      _builder.clearFun()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class If_Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-     val if_: com.google.protobuf.kotlin.DslList<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage, If_Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getIfList()
-      )
-    /**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     * @param value The if to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addIf_")
-    fun com.google.protobuf.kotlin.DslList<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage, If_Proxy>.add(value: evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage) {
-      _builder.addIf(value)
-    }/**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     * @param value The if to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignIf_")
-    inline operator fun com.google.protobuf.kotlin.DslList<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage, If_Proxy>.plusAssign(value: evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage) {
-      add(value)
-    }/**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     * @param values The if to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllIf_")
-    fun com.google.protobuf.kotlin.DslList<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage, If_Proxy>.addAll(values: kotlin.collections.Iterable<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage>) {
-      _builder.addAllIf(values)
-    }/**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     * @param values The if to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllIf_")
-    inline operator fun com.google.protobuf.kotlin.DslList<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage, If_Proxy>.plusAssign(values: kotlin.collections.Iterable<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage>) {
-      addAll(values)
-    }/**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     * @param index The index to set the value at.
-     * @param value The if to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setIf_")
-    operator fun com.google.protobuf.kotlin.DslList<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage, If_Proxy>.set(index: kotlin.Int, value: evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage) {
-      _builder.setIf(index, value)
-    }/**
-     * <code>repeated .evil_names_proto2.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearIf_")
-    fun com.google.protobuf.kotlin.DslList<evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage, If_Proxy>.clear() {
-      _builder.clearIf()
-    }}
-  @kotlin.jvm.JvmSynthetic
-  inline fun nestedMessage(block: evil_names_proto2.HardKeywordsAllTypesKt.NestedMessageKt.Dsl.() -> Unit): evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage =
-    evil_names_proto2.HardKeywordsAllTypesKt.NestedMessageKt.Dsl._create(evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage.newBuilder()).apply { block() }._build()
-  object NestedMessageKt {
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    @com.google.protobuf.kotlin.ProtoDslMarker
-    class Dsl private constructor(
-      @kotlin.jvm.JvmField private val _builder: evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage.Builder
-    ) {
-      companion object {
-        @kotlin.jvm.JvmSynthetic
-        @kotlin.PublishedApi
-        internal fun _create(builder: evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage.Builder): Dsl = Dsl(builder)
-      }
-
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _build(): evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage = _builder.build()
-
-      /**
-       * <code>optional int32 while = 1;</code>
-       */
-      var while_: kotlin.Int
-        @JvmName("getWhile_")
-        get() = _builder.getWhile()
-        @JvmName("setWhile_")
-        set(value) {
-          _builder.setWhile(value)
-        }
-      /**
-       * <code>optional int32 while = 1;</code>
-       */
-      fun clearWhile_() {
-        _builder.clearWhile()
-      }
-      /**
-       * <code>optional int32 while = 1;</code>
-       * @return Whether the while field is set.
-       */
-      fun hasWhile_(): kotlin.Boolean {
-        return _builder.hasWhile()
-      }
-    }
-  }
-}
-inline fun evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.copy(block: evil_names_proto2.HardKeywordsAllTypesKt.Dsl.() -> Unit): evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes =
-  evil_names_proto2.HardKeywordsAllTypesKt.Dsl._create(this.toBuilder()).apply { block() }._build()
-inline fun evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage.copy(block: evil_names_proto2.HardKeywordsAllTypesKt.NestedMessageKt.Dsl.() -> Unit): evil_names_proto2.EvilNamesProto2OuterClass.HardKeywordsAllTypes.NestedMessage =
-  evil_names_proto2.HardKeywordsAllTypesKt.NestedMessageKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/evil_names_proto2/InterfaceKt.kt b/java/kotlin-lite/target/generated-test-sources/evil_names_proto2/InterfaceKt.kt
deleted file mode 100644
index bc70c78..0000000
--- a/java/kotlin-lite/target/generated-test-sources/evil_names_proto2/InterfaceKt.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: com/google/protobuf/evil_names_proto2.proto
-
-package evil_names_proto2;
-
-@kotlin.jvm.JvmSynthetic
-inline fun interface_(block: evil_names_proto2.InterfaceKt.Dsl.() -> Unit): evil_names_proto2.EvilNamesProto2OuterClass.Interface =
-  evil_names_proto2.InterfaceKt.Dsl._create(evil_names_proto2.EvilNamesProto2OuterClass.Interface.newBuilder()).apply { block() }._build()
-object InterfaceKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: evil_names_proto2.EvilNamesProto2OuterClass.Interface.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: evil_names_proto2.EvilNamesProto2OuterClass.Interface.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): evil_names_proto2.EvilNamesProto2OuterClass.Interface = _builder.build()
-  }
-}
-inline fun evil_names_proto2.EvilNamesProto2OuterClass.Interface.copy(block: evil_names_proto2.InterfaceKt.Dsl.() -> Unit): evil_names_proto2.EvilNamesProto2OuterClass.Interface =
-  evil_names_proto2.InterfaceKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/evil_names_proto3/ClassKt.kt b/java/kotlin-lite/target/generated-test-sources/evil_names_proto3/ClassKt.kt
deleted file mode 100644
index be027da..0000000
--- a/java/kotlin-lite/target/generated-test-sources/evil_names_proto3/ClassKt.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: com/google/protobuf/evil_names_proto3.proto
-
-package evil_names_proto3;
-
-@kotlin.jvm.JvmSynthetic
-inline fun class_(block: evil_names_proto3.ClassKt.Dsl.() -> Unit): evil_names_proto3.EvilNamesProto3OuterClass.Class =
-  evil_names_proto3.ClassKt.Dsl._create(evil_names_proto3.EvilNamesProto3OuterClass.Class.newBuilder()).apply { block() }._build()
-object ClassKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: evil_names_proto3.EvilNamesProto3OuterClass.Class.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: evil_names_proto3.EvilNamesProto3OuterClass.Class.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): evil_names_proto3.EvilNamesProto3OuterClass.Class = _builder.build()
-  }
-}
-inline fun evil_names_proto3.EvilNamesProto3OuterClass.Class.copy(block: evil_names_proto3.ClassKt.Dsl.() -> Unit): evil_names_proto3.EvilNamesProto3OuterClass.Class =
-  evil_names_proto3.ClassKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/evil_names_proto3/EvilNamesProto3Kt.kt b/java/kotlin-lite/target/generated-test-sources/evil_names_proto3/EvilNamesProto3Kt.kt
deleted file mode 100644
index 40322a2..0000000
--- a/java/kotlin-lite/target/generated-test-sources/evil_names_proto3/EvilNamesProto3Kt.kt
+++ /dev/null
@@ -1,1078 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: com/google/protobuf/evil_names_proto3.proto
-
-package evil_names_proto3;
-
-@kotlin.jvm.JvmSynthetic
-inline fun evilNamesProto3(block: evil_names_proto3.EvilNamesProto3Kt.Dsl.() -> Unit): evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3 =
-  evil_names_proto3.EvilNamesProto3Kt.Dsl._create(evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3.newBuilder()).apply { block() }._build()
-object EvilNamesProto3Kt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3 = _builder.build()
-
-    /**
-     * <code>bool initialized = 1;</code>
-     */
-    var initialized: kotlin.Boolean
-      @JvmName("getInitialized")
-      get() = _builder.getInitialized()
-      @JvmName("setInitialized")
-      set(value) {
-        _builder.setInitialized(value)
-      }
-    /**
-     * <code>bool initialized = 1;</code>
-     */
-    fun clearInitialized() {
-      _builder.clearInitialized()
-    }
-
-    /**
-     * <code>bool has_foo = 2;</code>
-     */
-    var hasFoo: kotlin.Boolean
-      @JvmName("getHasFoo")
-      get() = _builder.getHasFoo()
-      @JvmName("setHasFoo")
-      set(value) {
-        _builder.setHasFoo(value)
-      }
-    /**
-     * <code>bool has_foo = 2;</code>
-     */
-    fun clearHasFoo() {
-      _builder.clearHasFoo()
-    }
-
-    /**
-     * <code>string Bar = 3;</code>
-     */
-    var bar: kotlin.String
-      @JvmName("getBar")
-      get() = _builder.getBar()
-      @JvmName("setBar")
-      set(value) {
-        _builder.setBar(value)
-      }
-    /**
-     * <code>string Bar = 3;</code>
-     */
-    fun clearBar() {
-      _builder.clearBar()
-    }
-
-    /**
-     * <code>bool is_initialized = 4;</code>
-     */
-    var isInitialized: kotlin.Boolean
-      @JvmName("getIsInitialized")
-      get() = _builder.getIsInitialized()
-      @JvmName("setIsInitialized")
-      set(value) {
-        _builder.setIsInitialized(value)
-      }
-    /**
-     * <code>bool is_initialized = 4;</code>
-     */
-    fun clearIsInitialized() {
-      _builder.clearIsInitialized()
-    }
-
-    /**
-     * <code>string fooBar = 5;</code>
-     */
-    var fooBar: kotlin.String
-      @JvmName("getFooBar")
-      get() = _builder.getFooBar()
-      @JvmName("setFooBar")
-      set(value) {
-        _builder.setFooBar(value)
-      }
-    /**
-     * <code>string fooBar = 5;</code>
-     */
-    fun clearFooBar() {
-      _builder.clearFooBar()
-    }
-    /**
-     * <code>string fooBar = 5;</code>
-     * @return Whether the fooBar field is set.
-     */
-    fun hasFooBar(): kotlin.Boolean {
-      return _builder.hasFooBar()
-    }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class ALLCAPSProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @return A list containing the aLLCAPS.
-     */
-    val aLLCAPS: com.google.protobuf.kotlin.DslList<kotlin.String, ALLCAPSProxy>
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getALLCAPSList()
-      )
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param value The aLLCAPS to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addALLCAPS")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, ALLCAPSProxy>.add(value: kotlin.String) {
-      _builder.addALLCAPS(value)
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param value The aLLCAPS to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignALLCAPS")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, ALLCAPSProxy>.plusAssign(value: kotlin.String) {
-      add(value)
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param values The aLLCAPS to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllALLCAPS")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, ALLCAPSProxy>.addAll(values: kotlin.collections.Iterable<kotlin.String>) {
-      _builder.addAllALLCAPS(values)
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param values The aLLCAPS to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllALLCAPS")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, ALLCAPSProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.String>) {
-      addAll(values)
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param index The index to set the value at.
-     * @param value The aLLCAPS to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setALLCAPS")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.String, ALLCAPSProxy>.set(index: kotlin.Int, value: kotlin.String) {
-      _builder.setALLCAPS(index, value)
-    }/**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearALLCAPS")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, ALLCAPSProxy>.clear() {
-      _builder.clearALLCAPS()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class ALLCAPSMAPProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-     val aLLCAPSMAP: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Boolean, ALLCAPSMAPProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getALLCAPSMAPMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getALLCAPSMAPMap()
-      )
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    @JvmName("putALLCAPSMAP")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Boolean, ALLCAPSMAPProxy>
-      .put(key: kotlin.Int, value: kotlin.Boolean) {
-         _builder.putALLCAPSMAP(key, value)
-       }
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setALLCAPSMAP")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Boolean, ALLCAPSMAPProxy>
-      .set(key: kotlin.Int, value: kotlin.Boolean) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeALLCAPSMAP")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Boolean, ALLCAPSMAPProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeALLCAPSMAP(key)
-       }
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllALLCAPSMAP")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Boolean, ALLCAPSMAPProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Boolean>) {
-         _builder.putAllALLCAPSMAP(map)
-       }
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearALLCAPSMAP")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Boolean, ALLCAPSMAPProxy>
-      .clear() {
-         _builder.clearALLCAPSMAP()
-       }
-
-    /**
-     * <code>bool has_underbar_preceding_numeric_1foo = 9;</code>
-     */
-    var hasUnderbarPrecedingNumeric1Foo: kotlin.Boolean
-      @JvmName("getHasUnderbarPrecedingNumeric1Foo")
-      get() = _builder.getHasUnderbarPrecedingNumeric1Foo()
-      @JvmName("setHasUnderbarPrecedingNumeric1Foo")
-      set(value) {
-        _builder.setHasUnderbarPrecedingNumeric1Foo(value)
-      }
-    /**
-     * <code>bool has_underbar_preceding_numeric_1foo = 9;</code>
-     */
-    fun clearHasUnderbarPrecedingNumeric1Foo() {
-      _builder.clearHasUnderbarPrecedingNumeric1Foo()
-    }
-
-    /**
-     * <code>bool has_underbar_preceding_numeric_42bar = 10;</code>
-     */
-    var hasUnderbarPrecedingNumeric42Bar: kotlin.Boolean
-      @JvmName("getHasUnderbarPrecedingNumeric42Bar")
-      get() = _builder.getHasUnderbarPrecedingNumeric42Bar()
-      @JvmName("setHasUnderbarPrecedingNumeric42Bar")
-      set(value) {
-        _builder.setHasUnderbarPrecedingNumeric42Bar(value)
-      }
-    /**
-     * <code>bool has_underbar_preceding_numeric_42bar = 10;</code>
-     */
-    fun clearHasUnderbarPrecedingNumeric42Bar() {
-      _builder.clearHasUnderbarPrecedingNumeric42Bar()
-    }
-
-    /**
-     * <code>bool has_underbar_preceding_numeric_123foo42bar_baz = 11;</code>
-     */
-    var hasUnderbarPrecedingNumeric123Foo42BarBaz: kotlin.Boolean
-      @JvmName("getHasUnderbarPrecedingNumeric123Foo42BarBaz")
-      get() = _builder.getHasUnderbarPrecedingNumeric123Foo42BarBaz()
-      @JvmName("setHasUnderbarPrecedingNumeric123Foo42BarBaz")
-      set(value) {
-        _builder.setHasUnderbarPrecedingNumeric123Foo42BarBaz(value)
-      }
-    /**
-     * <code>bool has_underbar_preceding_numeric_123foo42bar_baz = 11;</code>
-     */
-    fun clearHasUnderbarPrecedingNumeric123Foo42BarBaz() {
-      _builder.clearHasUnderbarPrecedingNumeric123Foo42BarBaz()
-    }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class ExtensionProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @return A list containing the extension.
-     */
-    val extension: com.google.protobuf.kotlin.DslList<kotlin.String, ExtensionProxy>
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getExtensionList()
-      )
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param value The extension to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addExtension")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, ExtensionProxy>.add(value: kotlin.String) {
-      _builder.addExtension(value)
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param value The extension to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignExtension")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, ExtensionProxy>.plusAssign(value: kotlin.String) {
-      add(value)
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param values The extension to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllExtension")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, ExtensionProxy>.addAll(values: kotlin.collections.Iterable<kotlin.String>) {
-      _builder.addAllExtension(values)
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param values The extension to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllExtension")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, ExtensionProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.String>) {
-      addAll(values)
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param index The index to set the value at.
-     * @param value The extension to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setExtension")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.String, ExtensionProxy>.set(index: kotlin.Int, value: kotlin.String) {
-      _builder.setExtension(index, value)
-    }/**
-     * <code>repeated string extension = 12;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearExtension")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, ExtensionProxy>.clear() {
-      _builder.clearExtension()
-    }
-    /**
-     * <code>string class = 13;</code>
-     */
-    var class_: kotlin.String
-      @JvmName("getClass_")
-      get() = _builder.getClass_()
-      @JvmName("setClass_")
-      set(value) {
-        _builder.setClass_(value)
-      }
-    /**
-     * <code>string class = 13;</code>
-     */
-    fun clearClass_() {
-      _builder.clearClass_()
-    }
-
-    /**
-     * <code>double int = 14;</code>
-     */
-    var int: kotlin.Double
-      @JvmName("getInt")
-      get() = _builder.getInt()
-      @JvmName("setInt")
-      set(value) {
-        _builder.setInt(value)
-      }
-    /**
-     * <code>double int = 14;</code>
-     */
-    fun clearInt() {
-      _builder.clearInt()
-    }
-
-    /**
-     * <code>bool long = 15;</code>
-     */
-    var long: kotlin.Boolean
-      @JvmName("getLong")
-      get() = _builder.getLong()
-      @JvmName("setLong")
-      set(value) {
-        _builder.setLong(value)
-      }
-    /**
-     * <code>bool long = 15;</code>
-     */
-    fun clearLong() {
-      _builder.clearLong()
-    }
-
-    /**
-     * <code>int64 boolean = 16;</code>
-     */
-    var boolean: kotlin.Long
-      @JvmName("getBoolean")
-      get() = _builder.getBoolean()
-      @JvmName("setBoolean")
-      set(value) {
-        _builder.setBoolean(value)
-      }
-    /**
-     * <code>int64 boolean = 16;</code>
-     */
-    fun clearBoolean() {
-      _builder.clearBoolean()
-    }
-
-    /**
-     * <code>string sealed = 17;</code>
-     */
-    var sealed: kotlin.String
-      @JvmName("getSealed")
-      get() = _builder.getSealed()
-      @JvmName("setSealed")
-      set(value) {
-        _builder.setSealed(value)
-      }
-    /**
-     * <code>string sealed = 17;</code>
-     */
-    fun clearSealed() {
-      _builder.clearSealed()
-    }
-
-    /**
-     * <code>float interface = 18;</code>
-     */
-    var interface_: kotlin.Float
-      @JvmName("getInterface_")
-      get() = _builder.getInterface()
-      @JvmName("setInterface_")
-      set(value) {
-        _builder.setInterface(value)
-      }
-    /**
-     * <code>float interface = 18;</code>
-     */
-    fun clearInterface_() {
-      _builder.clearInterface()
-    }
-
-    /**
-     * <code>int32 in = 19;</code>
-     */
-    var in_: kotlin.Int
-      @JvmName("getIn_")
-      get() = _builder.getIn()
-      @JvmName("setIn_")
-      set(value) {
-        _builder.setIn(value)
-      }
-    /**
-     * <code>int32 in = 19;</code>
-     */
-    fun clearIn_() {
-      _builder.clearIn()
-    }
-
-    /**
-     * <code>string object = 20;</code>
-     */
-    var object_: kotlin.String
-      @JvmName("getObject_")
-      get() = _builder.getObject()
-      @JvmName("setObject_")
-      set(value) {
-        _builder.setObject(value)
-      }
-    /**
-     * <code>string object = 20;</code>
-     */
-    fun clearObject_() {
-      _builder.clearObject()
-    }
-
-    /**
-     * <code>string cached_size = 21;</code>
-     */
-    var cachedSize_: kotlin.String
-      @JvmName("getCachedSize_")
-      get() = _builder.getCachedSize_()
-      @JvmName("setCachedSize_")
-      set(value) {
-        _builder.setCachedSize_(value)
-      }
-    /**
-     * <code>string cached_size = 21;</code>
-     */
-    fun clearCachedSize_() {
-      _builder.clearCachedSize_()
-    }
-
-    /**
-     * <code>bool serialized_size = 22;</code>
-     */
-    var serializedSize_: kotlin.Boolean
-      @JvmName("getSerializedSize_")
-      get() = _builder.getSerializedSize_()
-      @JvmName("setSerializedSize_")
-      set(value) {
-        _builder.setSerializedSize_(value)
-      }
-    /**
-     * <code>bool serialized_size = 22;</code>
-     */
-    fun clearSerializedSize_() {
-      _builder.clearSerializedSize_()
-    }
-
-    /**
-     * <code>string value = 23;</code>
-     */
-    var value: kotlin.String
-      @JvmName("getValue")
-      get() = _builder.getValue()
-      @JvmName("setValue")
-      set(value) {
-        _builder.setValue(value)
-      }
-    /**
-     * <code>string value = 23;</code>
-     */
-    fun clearValue() {
-      _builder.clearValue()
-    }
-
-    /**
-     * <code>int64 index = 24;</code>
-     */
-    var index: kotlin.Long
-      @JvmName("getIndex")
-      get() = _builder.getIndex()
-      @JvmName("setIndex")
-      set(value) {
-        _builder.setIndex(value)
-      }
-    /**
-     * <code>int64 index = 24;</code>
-     */
-    fun clearIndex() {
-      _builder.clearIndex()
-    }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class ValuesProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated string values = 25;</code>
-     * @return A list containing the values.
-     */
-    val values: com.google.protobuf.kotlin.DslList<kotlin.String, ValuesProxy>
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getValuesList()
-      )
-    /**
-     * <code>repeated string values = 25;</code>
-     * @param value The values to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addValues")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, ValuesProxy>.add(value: kotlin.String) {
-      _builder.addValues(value)
-    }
-    /**
-     * <code>repeated string values = 25;</code>
-     * @param value The values to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignValues")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, ValuesProxy>.plusAssign(value: kotlin.String) {
-      add(value)
-    }
-    /**
-     * <code>repeated string values = 25;</code>
-     * @param values The values to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllValues")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, ValuesProxy>.addAll(values: kotlin.collections.Iterable<kotlin.String>) {
-      _builder.addAllValues(values)
-    }
-    /**
-     * <code>repeated string values = 25;</code>
-     * @param values The values to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllValues")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, ValuesProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.String>) {
-      addAll(values)
-    }
-    /**
-     * <code>repeated string values = 25;</code>
-     * @param index The index to set the value at.
-     * @param value The values to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setValues")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.String, ValuesProxy>.set(index: kotlin.Int, value: kotlin.String) {
-      _builder.setValues(index, value)
-    }/**
-     * <code>repeated string values = 25;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearValues")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, ValuesProxy>.clear() {
-      _builder.clearValues()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class NewValuesProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated string new_values = 26;</code>
-     * @return A list containing the newValues.
-     */
-    val newValues: com.google.protobuf.kotlin.DslList<kotlin.String, NewValuesProxy>
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getNewValuesList()
-      )
-    /**
-     * <code>repeated string new_values = 26;</code>
-     * @param value The newValues to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addNewValues")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, NewValuesProxy>.add(value: kotlin.String) {
-      _builder.addNewValues(value)
-    }
-    /**
-     * <code>repeated string new_values = 26;</code>
-     * @param value The newValues to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignNewValues")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, NewValuesProxy>.plusAssign(value: kotlin.String) {
-      add(value)
-    }
-    /**
-     * <code>repeated string new_values = 26;</code>
-     * @param values The newValues to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllNewValues")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, NewValuesProxy>.addAll(values: kotlin.collections.Iterable<kotlin.String>) {
-      _builder.addAllNewValues(values)
-    }
-    /**
-     * <code>repeated string new_values = 26;</code>
-     * @param values The newValues to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllNewValues")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, NewValuesProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.String>) {
-      addAll(values)
-    }
-    /**
-     * <code>repeated string new_values = 26;</code>
-     * @param index The index to set the value at.
-     * @param value The newValues to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setNewValues")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.String, NewValuesProxy>.set(index: kotlin.Int, value: kotlin.String) {
-      _builder.setNewValues(index, value)
-    }/**
-     * <code>repeated string new_values = 26;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearNewValues")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, NewValuesProxy>.clear() {
-      _builder.clearNewValues()
-    }
-    /**
-     * <code>bool builder = 27;</code>
-     */
-    var builder: kotlin.Boolean
-      @JvmName("getBuilder")
-      get() = _builder.getBuilder()
-      @JvmName("setBuilder")
-      set(value) {
-        _builder.setBuilder(value)
-      }
-    /**
-     * <code>bool builder = 27;</code>
-     */
-    fun clearBuilder() {
-      _builder.clearBuilder()
-    }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class KProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, int32&gt; k = 28;</code>
-     */
-     val k: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, KProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getKMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getKMap()
-      )
-    /**
-     * <code>map&lt;int32, int32&gt; k = 28;</code>
-     */
-    @JvmName("putK")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, KProxy>
-      .put(key: kotlin.Int, value: kotlin.Int) {
-         _builder.putK(key, value)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; k = 28;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setK")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, KProxy>
-      .set(key: kotlin.Int, value: kotlin.Int) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; k = 28;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeK")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, KProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeK(key)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; k = 28;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllK")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, KProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Int>) {
-         _builder.putAllK(map)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; k = 28;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearK")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, KProxy>
-      .clear() {
-         _builder.clearK()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class VProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;string, string&gt; v = 29;</code>
-     */
-     val v: com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, VProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getVMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getVMap()
-      )
-    /**
-     * <code>map&lt;string, string&gt; v = 29;</code>
-     */
-    @JvmName("putV")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, VProxy>
-      .put(key: kotlin.String, value: kotlin.String) {
-         _builder.putV(key, value)
-       }
-    /**
-     * <code>map&lt;string, string&gt; v = 29;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setV")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, VProxy>
-      .set(key: kotlin.String, value: kotlin.String) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;string, string&gt; v = 29;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeV")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, VProxy>
-      .remove(key: kotlin.String) {
-         _builder.removeV(key)
-       }
-    /**
-     * <code>map&lt;string, string&gt; v = 29;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllV")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, VProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.String, kotlin.String>) {
-         _builder.putAllV(map)
-       }
-    /**
-     * <code>map&lt;string, string&gt; v = 29;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearV")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, VProxy>
-      .clear() {
-         _builder.clearV()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class KeyProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;string, int32&gt; key = 30;</code>
-     */
-     val key: com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.Int, KeyProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getKeyMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getKeyMap()
-      )
-    /**
-     * <code>map&lt;string, int32&gt; key = 30;</code>
-     */
-    @JvmName("putKey")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.Int, KeyProxy>
-      .put(key: kotlin.String, value: kotlin.Int) {
-         _builder.putKey(key, value)
-       }
-    /**
-     * <code>map&lt;string, int32&gt; key = 30;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setKey")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.Int, KeyProxy>
-      .set(key: kotlin.String, value: kotlin.Int) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;string, int32&gt; key = 30;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeKey")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.Int, KeyProxy>
-      .remove(key: kotlin.String) {
-         _builder.removeKey(key)
-       }
-    /**
-     * <code>map&lt;string, int32&gt; key = 30;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllKey")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.Int, KeyProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.String, kotlin.Int>) {
-         _builder.putAllKey(map)
-       }
-    /**
-     * <code>map&lt;string, int32&gt; key = 30;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearKey")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.Int, KeyProxy>
-      .clear() {
-         _builder.clearKey()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, string&gt; map = 31;</code>
-     */
-     val map: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.String, MapProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapMap()
-      )
-    /**
-     * <code>map&lt;int32, string&gt; map = 31;</code>
-     */
-    @JvmName("putMap")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.String, MapProxy>
-      .put(key: kotlin.Int, value: kotlin.String) {
-         _builder.putMap(key, value)
-       }
-    /**
-     * <code>map&lt;int32, string&gt; map = 31;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMap")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.String, MapProxy>
-      .set(key: kotlin.Int, value: kotlin.String) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, string&gt; map = 31;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMap")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.String, MapProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMap(key)
-       }
-    /**
-     * <code>map&lt;int32, string&gt; map = 31;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMap")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.String, MapProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.String>) {
-         _builder.putAllMap(map)
-       }
-    /**
-     * <code>map&lt;int32, string&gt; map = 31;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMap")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.String, MapProxy>
-      .clear() {
-         _builder.clearMap()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PairsProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;string, int32&gt; pairs = 32;</code>
-     */
-     val pairs: com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.Int, PairsProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getPairsMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getPairsMap()
-      )
-    /**
-     * <code>map&lt;string, int32&gt; pairs = 32;</code>
-     */
-    @JvmName("putPairs")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.Int, PairsProxy>
-      .put(key: kotlin.String, value: kotlin.Int) {
-         _builder.putPairs(key, value)
-       }
-    /**
-     * <code>map&lt;string, int32&gt; pairs = 32;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setPairs")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.Int, PairsProxy>
-      .set(key: kotlin.String, value: kotlin.Int) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;string, int32&gt; pairs = 32;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removePairs")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.Int, PairsProxy>
-      .remove(key: kotlin.String) {
-         _builder.removePairs(key)
-       }
-    /**
-     * <code>map&lt;string, int32&gt; pairs = 32;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllPairs")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.Int, PairsProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.String, kotlin.Int>) {
-         _builder.putAllPairs(map)
-       }
-    /**
-     * <code>map&lt;string, int32&gt; pairs = 32;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearPairs")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.Int, PairsProxy>
-      .clear() {
-         _builder.clearPairs()
-       }
-
-    /**
-     * <code>string _leading_underscore = 33;</code>
-     */
-    var LeadingUnderscore: kotlin.String
-      @JvmName("getLeadingUnderscore")
-      get() = _builder.getLeadingUnderscore()
-      @JvmName("setLeadingUnderscore")
-      set(value) {
-        _builder.setLeadingUnderscore(value)
-      }
-    /**
-     * <code>string _leading_underscore = 33;</code>
-     */
-    fun clearLeadingUnderscore() {
-      _builder.clearLeadingUnderscore()
-    }
-
-    /**
-     * <code>int32 option = 34;</code>
-     */
-    var option: kotlin.Int
-      @JvmName("getOption")
-      get() = _builder.getOption()
-      @JvmName("setOption")
-      set(value) {
-        _builder.setOption(value)
-      }
-    /**
-     * <code>int32 option = 34;</code>
-     */
-    fun clearOption() {
-      _builder.clearOption()
-    }
-    /**
-     * <code>int32 option = 34;</code>
-     * @return Whether the option field is set.
-     */
-    fun hasOption(): kotlin.Boolean {
-      return _builder.hasOption()
-    }
-    val camelCaseCase: evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3.CamelCaseCase
-      @JvmName("getCamelCaseCase")
-      get() = _builder.getCamelCaseCase()
-
-    fun clearCamelCase() {
-      _builder.clearCamelCase()
-    }
-    val LeadingUnderscoreOneofCase: evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3.LeadingUnderscoreOneofCase
-      @JvmName("getLeadingUnderscoreOneofCase")
-      get() = _builder.getLeadingUnderscoreOneofCase()
-
-    fun clearLeadingUnderscoreOneof() {
-      _builder.clearLeadingUnderscoreOneof()
-    }
-  }
-}
-inline fun evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3.copy(block: evil_names_proto3.EvilNamesProto3Kt.Dsl.() -> Unit): evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3 =
-  evil_names_proto3.EvilNamesProto3Kt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/evil_names_proto3/EvilNamesProto3OuterClass.java b/java/kotlin-lite/target/generated-test-sources/evil_names_proto3/EvilNamesProto3OuterClass.java
deleted file mode 100644
index 3731e81..0000000
--- a/java/kotlin-lite/target/generated-test-sources/evil_names_proto3/EvilNamesProto3OuterClass.java
+++ /dev/null
@@ -1,6631 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: com/google/protobuf/evil_names_proto3.proto
-
-package evil_names_proto3;
-
-public final class EvilNamesProto3OuterClass {
-  private EvilNamesProto3OuterClass() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-  public interface EvilNamesProto3OrBuilder extends
-      // @@protoc_insertion_point(interface_extends:evil_names_proto3.EvilNamesProto3)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>bool initialized = 1;</code>
-     * @return The initialized.
-     */
-    boolean getInitialized();
-
-    /**
-     * <code>bool has_foo = 2;</code>
-     * @return The hasFoo.
-     */
-    boolean getHasFoo();
-
-    /**
-     * <code>string Bar = 3;</code>
-     * @return The bar.
-     */
-    java.lang.String getBar();
-    /**
-     * <code>string Bar = 3;</code>
-     * @return The bytes for bar.
-     */
-    com.google.protobuf.ByteString
-        getBarBytes();
-
-    /**
-     * <code>bool is_initialized = 4;</code>
-     * @return The isInitialized.
-     */
-    boolean getIsInitialized();
-
-    /**
-     * <code>string fooBar = 5;</code>
-     * @return Whether the fooBar field is set.
-     */
-    boolean hasFooBar();
-    /**
-     * <code>string fooBar = 5;</code>
-     * @return The fooBar.
-     */
-    java.lang.String getFooBar();
-    /**
-     * <code>string fooBar = 5;</code>
-     * @return The bytes for fooBar.
-     */
-    com.google.protobuf.ByteString
-        getFooBarBytes();
-
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @return A list containing the aLLCAPS.
-     */
-    java.util.List<java.lang.String>
-        getALLCAPSList();
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @return The count of aLLCAPS.
-     */
-    int getALLCAPSCount();
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param index The index of the element to return.
-     * @return The aLLCAPS at the given index.
-     */
-    java.lang.String getALLCAPS(int index);
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param index The index of the element to return.
-     * @return The aLLCAPS at the given index.
-     */
-    com.google.protobuf.ByteString
-        getALLCAPSBytes(int index);
-
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    int getALLCAPSMAPCount();
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    boolean containsALLCAPSMAP(
-        int key);
-    /**
-     * Use {@link #getALLCAPSMAPMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Boolean>
-    getALLCAPSMAP();
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Boolean>
-    getALLCAPSMAPMap();
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-
-    boolean getALLCAPSMAPOrDefault(
-        int key,
-        boolean defaultValue);
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-
-    boolean getALLCAPSMAPOrThrow(
-        int key);
-
-    /**
-     * <code>bool has_underbar_preceding_numeric_1foo = 9;</code>
-     * @return The hasUnderbarPrecedingNumeric1foo.
-     */
-    boolean getHasUnderbarPrecedingNumeric1Foo();
-
-    /**
-     * <code>bool has_underbar_preceding_numeric_42bar = 10;</code>
-     * @return The hasUnderbarPrecedingNumeric42bar.
-     */
-    boolean getHasUnderbarPrecedingNumeric42Bar();
-
-    /**
-     * <code>bool has_underbar_preceding_numeric_123foo42bar_baz = 11;</code>
-     * @return The hasUnderbarPrecedingNumeric123foo42barBaz.
-     */
-    boolean getHasUnderbarPrecedingNumeric123Foo42BarBaz();
-
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @return A list containing the extension.
-     */
-    java.util.List<java.lang.String>
-        getExtensionList();
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @return The count of extension.
-     */
-    int getExtensionCount();
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param index The index of the element to return.
-     * @return The extension at the given index.
-     */
-    java.lang.String getExtension(int index);
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param index The index of the element to return.
-     * @return The extension at the given index.
-     */
-    com.google.protobuf.ByteString
-        getExtensionBytes(int index);
-
-    /**
-     * <code>string class = 13;</code>
-     * @return The class.
-     */
-    java.lang.String getClass_();
-    /**
-     * <code>string class = 13;</code>
-     * @return The bytes for class.
-     */
-    com.google.protobuf.ByteString
-        getClass_Bytes();
-
-    /**
-     * <code>double int = 14;</code>
-     * @return The int.
-     */
-    double getInt();
-
-    /**
-     * <code>bool long = 15;</code>
-     * @return The long.
-     */
-    boolean getLong();
-
-    /**
-     * <code>int64 boolean = 16;</code>
-     * @return The boolean.
-     */
-    long getBoolean();
-
-    /**
-     * <code>string sealed = 17;</code>
-     * @return The sealed.
-     */
-    java.lang.String getSealed();
-    /**
-     * <code>string sealed = 17;</code>
-     * @return The bytes for sealed.
-     */
-    com.google.protobuf.ByteString
-        getSealedBytes();
-
-    /**
-     * <code>float interface = 18;</code>
-     * @return The interface.
-     */
-    float getInterface();
-
-    /**
-     * <code>int32 in = 19;</code>
-     * @return The in.
-     */
-    int getIn();
-
-    /**
-     * <code>string object = 20;</code>
-     * @return The object.
-     */
-    java.lang.String getObject();
-    /**
-     * <code>string object = 20;</code>
-     * @return The bytes for object.
-     */
-    com.google.protobuf.ByteString
-        getObjectBytes();
-
-    /**
-     * <code>string cached_size = 21;</code>
-     * @return The cachedSize.
-     */
-    java.lang.String getCachedSize_();
-    /**
-     * <code>string cached_size = 21;</code>
-     * @return The bytes for cachedSize.
-     */
-    com.google.protobuf.ByteString
-        getCachedSize_Bytes();
-
-    /**
-     * <code>bool serialized_size = 22;</code>
-     * @return The serializedSize.
-     */
-    boolean getSerializedSize_();
-
-    /**
-     * <code>string value = 23;</code>
-     * @return The value.
-     */
-    java.lang.String getValue();
-    /**
-     * <code>string value = 23;</code>
-     * @return The bytes for value.
-     */
-    com.google.protobuf.ByteString
-        getValueBytes();
-
-    /**
-     * <code>int64 index = 24;</code>
-     * @return The index.
-     */
-    long getIndex();
-
-    /**
-     * <code>repeated string values = 25;</code>
-     * @return A list containing the values.
-     */
-    java.util.List<java.lang.String>
-        getValuesList();
-    /**
-     * <code>repeated string values = 25;</code>
-     * @return The count of values.
-     */
-    int getValuesCount();
-    /**
-     * <code>repeated string values = 25;</code>
-     * @param index The index of the element to return.
-     * @return The values at the given index.
-     */
-    java.lang.String getValues(int index);
-    /**
-     * <code>repeated string values = 25;</code>
-     * @param index The index of the element to return.
-     * @return The values at the given index.
-     */
-    com.google.protobuf.ByteString
-        getValuesBytes(int index);
-
-    /**
-     * <code>repeated string new_values = 26;</code>
-     * @return A list containing the newValues.
-     */
-    java.util.List<java.lang.String>
-        getNewValuesList();
-    /**
-     * <code>repeated string new_values = 26;</code>
-     * @return The count of newValues.
-     */
-    int getNewValuesCount();
-    /**
-     * <code>repeated string new_values = 26;</code>
-     * @param index The index of the element to return.
-     * @return The newValues at the given index.
-     */
-    java.lang.String getNewValues(int index);
-    /**
-     * <code>repeated string new_values = 26;</code>
-     * @param index The index of the element to return.
-     * @return The newValues at the given index.
-     */
-    com.google.protobuf.ByteString
-        getNewValuesBytes(int index);
-
-    /**
-     * <code>bool builder = 27;</code>
-     * @return The builder.
-     */
-    boolean getBuilder();
-
-    /**
-     * <code>map&lt;int32, int32&gt; k = 28;</code>
-     */
-    int getKCount();
-    /**
-     * <code>map&lt;int32, int32&gt; k = 28;</code>
-     */
-    boolean containsK(
-        int key);
-    /**
-     * Use {@link #getKMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getK();
-    /**
-     * <code>map&lt;int32, int32&gt; k = 28;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getKMap();
-    /**
-     * <code>map&lt;int32, int32&gt; k = 28;</code>
-     */
-
-    int getKOrDefault(
-        int key,
-        int defaultValue);
-    /**
-     * <code>map&lt;int32, int32&gt; k = 28;</code>
-     */
-
-    int getKOrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;string, string&gt; v = 29;</code>
-     */
-    int getVCount();
-    /**
-     * <code>map&lt;string, string&gt; v = 29;</code>
-     */
-    boolean containsV(
-        java.lang.String key);
-    /**
-     * Use {@link #getVMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.String, java.lang.String>
-    getV();
-    /**
-     * <code>map&lt;string, string&gt; v = 29;</code>
-     */
-    java.util.Map<java.lang.String, java.lang.String>
-    getVMap();
-    /**
-     * <code>map&lt;string, string&gt; v = 29;</code>
-     */
-
-    java.lang.String getVOrDefault(
-        java.lang.String key,
-        java.lang.String defaultValue);
-    /**
-     * <code>map&lt;string, string&gt; v = 29;</code>
-     */
-
-    java.lang.String getVOrThrow(
-        java.lang.String key);
-
-    /**
-     * <code>map&lt;string, int32&gt; key = 30;</code>
-     */
-    int getKeyCount();
-    /**
-     * <code>map&lt;string, int32&gt; key = 30;</code>
-     */
-    boolean containsKey(
-        java.lang.String key);
-    /**
-     * Use {@link #getKeyMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.String, java.lang.Integer>
-    getKey();
-    /**
-     * <code>map&lt;string, int32&gt; key = 30;</code>
-     */
-    java.util.Map<java.lang.String, java.lang.Integer>
-    getKeyMap();
-    /**
-     * <code>map&lt;string, int32&gt; key = 30;</code>
-     */
-
-    int getKeyOrDefault(
-        java.lang.String key,
-        int defaultValue);
-    /**
-     * <code>map&lt;string, int32&gt; key = 30;</code>
-     */
-
-    int getKeyOrThrow(
-        java.lang.String key);
-
-    /**
-     * <code>map&lt;int32, string&gt; map = 31;</code>
-     */
-    int getMapCount();
-    /**
-     * <code>map&lt;int32, string&gt; map = 31;</code>
-     */
-    boolean containsMap(
-        int key);
-    /**
-     * Use {@link #getMapMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.String>
-    getMap();
-    /**
-     * <code>map&lt;int32, string&gt; map = 31;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.String>
-    getMapMap();
-    /**
-     * <code>map&lt;int32, string&gt; map = 31;</code>
-     */
-
-    java.lang.String getMapOrDefault(
-        int key,
-        java.lang.String defaultValue);
-    /**
-     * <code>map&lt;int32, string&gt; map = 31;</code>
-     */
-
-    java.lang.String getMapOrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;string, int32&gt; pairs = 32;</code>
-     */
-    int getPairsCount();
-    /**
-     * <code>map&lt;string, int32&gt; pairs = 32;</code>
-     */
-    boolean containsPairs(
-        java.lang.String key);
-    /**
-     * Use {@link #getPairsMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.String, java.lang.Integer>
-    getPairs();
-    /**
-     * <code>map&lt;string, int32&gt; pairs = 32;</code>
-     */
-    java.util.Map<java.lang.String, java.lang.Integer>
-    getPairsMap();
-    /**
-     * <code>map&lt;string, int32&gt; pairs = 32;</code>
-     */
-
-    int getPairsOrDefault(
-        java.lang.String key,
-        int defaultValue);
-    /**
-     * <code>map&lt;string, int32&gt; pairs = 32;</code>
-     */
-
-    int getPairsOrThrow(
-        java.lang.String key);
-
-    /**
-     * <code>string _leading_underscore = 33;</code>
-     * @return The leadingUnderscore.
-     */
-    java.lang.String getLeadingUnderscore();
-    /**
-     * <code>string _leading_underscore = 33;</code>
-     * @return The bytes for leadingUnderscore.
-     */
-    com.google.protobuf.ByteString
-        getLeadingUnderscoreBytes();
-
-    /**
-     * <code>int32 option = 34;</code>
-     * @return Whether the option field is set.
-     */
-    boolean hasOption();
-    /**
-     * <code>int32 option = 34;</code>
-     * @return The option.
-     */
-    int getOption();
-
-    public evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3.CamelCaseCase getCamelCaseCase();
-
-    public evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3.LeadingUnderscoreOneofCase getLeadingUnderscoreOneofCase();
-  }
-  /**
-   * Protobuf type {@code evil_names_proto3.EvilNamesProto3}
-   */
-  public  static final class EvilNamesProto3 extends
-      com.google.protobuf.GeneratedMessageLite<
-          EvilNamesProto3, EvilNamesProto3.Builder> implements
-      // @@protoc_insertion_point(message_implements:evil_names_proto3.EvilNamesProto3)
-      EvilNamesProto3OrBuilder {
-    private EvilNamesProto3() {
-      bar_ = "";
-      aLLCAPS_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      extension_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      class__ = "";
-      sealed_ = "";
-      object_ = "";
-      cachedSize__ = "";
-      value_ = "";
-      values_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      newValues_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      LeadingUnderscore_ = "";
-    }
-    private int camelCaseCase_ = 0;
-    private java.lang.Object camelCase_;
-    public enum CamelCaseCase {
-      FOOBAR(5),
-      CAMELCASE_NOT_SET(0);
-      private final int value;
-      private CamelCaseCase(int value) {
-        this.value = value;
-      }
-      /**
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static CamelCaseCase valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static CamelCaseCase forNumber(int value) {
-        switch (value) {
-          case 5: return FOOBAR;
-          case 0: return CAMELCASE_NOT_SET;
-          default: return null;
-        }
-      }
-      public int getNumber() {
-        return this.value;
-      }
-    };
-
-    @java.lang.Override
-    public CamelCaseCase
-    getCamelCaseCase() {
-      return CamelCaseCase.forNumber(
-          camelCaseCase_);
-    }
-
-    private void clearCamelCase() {
-      camelCaseCase_ = 0;
-      camelCase_ = null;
-    }
-
-    private int LeadingUnderscoreOneofCase_ = 0;
-    private java.lang.Object LeadingUnderscoreOneof_;
-    public enum LeadingUnderscoreOneofCase {
-      OPTION(34),
-      LEADINGUNDERSCOREONEOF_NOT_SET(0);
-      private final int value;
-      private LeadingUnderscoreOneofCase(int value) {
-        this.value = value;
-      }
-      /**
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static LeadingUnderscoreOneofCase valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static LeadingUnderscoreOneofCase forNumber(int value) {
-        switch (value) {
-          case 34: return OPTION;
-          case 0: return LEADINGUNDERSCOREONEOF_NOT_SET;
-          default: return null;
-        }
-      }
-      public int getNumber() {
-        return this.value;
-      }
-    };
-
-    @java.lang.Override
-    public LeadingUnderscoreOneofCase
-    getLeadingUnderscoreOneofCase() {
-      return LeadingUnderscoreOneofCase.forNumber(
-          LeadingUnderscoreOneofCase_);
-    }
-
-    private void clearLeadingUnderscoreOneof() {
-      LeadingUnderscoreOneofCase_ = 0;
-      LeadingUnderscoreOneof_ = null;
-    }
-
-    public static final int INITIALIZED_FIELD_NUMBER = 1;
-    private boolean initialized_;
-    /**
-     * <code>bool initialized = 1;</code>
-     * @return The initialized.
-     */
-    @java.lang.Override
-    public boolean getInitialized() {
-      return initialized_;
-    }
-    /**
-     * <code>bool initialized = 1;</code>
-     * @param value The initialized to set.
-     */
-    private void setInitialized(boolean value) {
-      
-      initialized_ = value;
-    }
-    /**
-     * <code>bool initialized = 1;</code>
-     */
-    private void clearInitialized() {
-      
-      initialized_ = false;
-    }
-
-    public static final int HAS_FOO_FIELD_NUMBER = 2;
-    private boolean hasFoo_;
-    /**
-     * <code>bool has_foo = 2;</code>
-     * @return The hasFoo.
-     */
-    @java.lang.Override
-    public boolean getHasFoo() {
-      return hasFoo_;
-    }
-    /**
-     * <code>bool has_foo = 2;</code>
-     * @param value The hasFoo to set.
-     */
-    private void setHasFoo(boolean value) {
-      
-      hasFoo_ = value;
-    }
-    /**
-     * <code>bool has_foo = 2;</code>
-     */
-    private void clearHasFoo() {
-      
-      hasFoo_ = false;
-    }
-
-    public static final int BAR_FIELD_NUMBER = 3;
-    private java.lang.String bar_;
-    /**
-     * <code>string Bar = 3;</code>
-     * @return The bar.
-     */
-    @java.lang.Override
-    public java.lang.String getBar() {
-      return bar_;
-    }
-    /**
-     * <code>string Bar = 3;</code>
-     * @return The bytes for bar.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getBarBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(bar_);
-    }
-    /**
-     * <code>string Bar = 3;</code>
-     * @param value The bar to set.
-     */
-    private void setBar(
-        java.lang.String value) {
-      value.getClass();
-  
-      bar_ = value;
-    }
-    /**
-     * <code>string Bar = 3;</code>
-     */
-    private void clearBar() {
-      
-      bar_ = getDefaultInstance().getBar();
-    }
-    /**
-     * <code>string Bar = 3;</code>
-     * @param value The bytes for bar to set.
-     */
-    private void setBarBytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      bar_ = value.toStringUtf8();
-      
-    }
-
-    public static final int IS_INITIALIZED_FIELD_NUMBER = 4;
-    private boolean isInitialized_;
-    /**
-     * <code>bool is_initialized = 4;</code>
-     * @return The isInitialized.
-     */
-    @java.lang.Override
-    public boolean getIsInitialized() {
-      return isInitialized_;
-    }
-    /**
-     * <code>bool is_initialized = 4;</code>
-     * @param value The isInitialized to set.
-     */
-    private void setIsInitialized(boolean value) {
-      
-      isInitialized_ = value;
-    }
-    /**
-     * <code>bool is_initialized = 4;</code>
-     */
-    private void clearIsInitialized() {
-      
-      isInitialized_ = false;
-    }
-
-    public static final int FOOBAR_FIELD_NUMBER = 5;
-    /**
-     * <code>string fooBar = 5;</code>
-     * @return Whether the fooBar field is set.
-     */
-    @java.lang.Override
-    public boolean hasFooBar() {
-      return camelCaseCase_ == 5;
-    }
-    /**
-     * <code>string fooBar = 5;</code>
-     * @return The fooBar.
-     */
-    @java.lang.Override
-    public java.lang.String getFooBar() {
-      java.lang.String ref = "";
-      if (camelCaseCase_ == 5) {
-        ref = (java.lang.String) camelCase_;
-      }
-      return ref;
-    }
-    /**
-     * <code>string fooBar = 5;</code>
-     * @return The bytes for fooBar.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getFooBarBytes() {
-      java.lang.String ref = "";
-      if (camelCaseCase_ == 5) {
-        ref = (java.lang.String) camelCase_;
-      }
-      return com.google.protobuf.ByteString.copyFromUtf8(ref);
-    }
-    /**
-     * <code>string fooBar = 5;</code>
-     * @param value The fooBar to set.
-     */
-    private void setFooBar(
-        java.lang.String value) {
-      value.getClass();
-  camelCaseCase_ = 5;
-      camelCase_ = value;
-    }
-    /**
-     * <code>string fooBar = 5;</code>
-     */
-    private void clearFooBar() {
-      if (camelCaseCase_ == 5) {
-        camelCaseCase_ = 0;
-        camelCase_ = null;
-      }
-    }
-    /**
-     * <code>string fooBar = 5;</code>
-     * @param value The bytes for fooBar to set.
-     */
-    private void setFooBarBytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      camelCase_ = value.toStringUtf8();
-      camelCaseCase_ = 5;
-    }
-
-    public static final int ALL_CAPS_FIELD_NUMBER = 7;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> aLLCAPS_;
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @return A list containing the aLLCAPS.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getALLCAPSList() {
-      return aLLCAPS_;
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @return The count of aLLCAPS.
-     */
-    @java.lang.Override
-    public int getALLCAPSCount() {
-      return aLLCAPS_.size();
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param index The index of the element to return.
-     * @return The aLLCAPS at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getALLCAPS(int index) {
-      return aLLCAPS_.get(index);
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the aLLCAPS at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getALLCAPSBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          aLLCAPS_.get(index));
-    }
-    private void ensureALLCAPSIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          aLLCAPS_;  if (!tmp.isModifiable()) {
-        aLLCAPS_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param index The index to set the value at.
-     * @param value The aLLCAPS to set.
-     */
-    private void setALLCAPS(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureALLCAPSIsMutable();
-      aLLCAPS_.set(index, value);
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param value The aLLCAPS to add.
-     */
-    private void addALLCAPS(
-        java.lang.String value) {
-      value.getClass();
-  ensureALLCAPSIsMutable();
-      aLLCAPS_.add(value);
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param values The aLLCAPS to add.
-     */
-    private void addAllALLCAPS(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureALLCAPSIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, aLLCAPS_);
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     */
-    private void clearALLCAPS() {
-      aLLCAPS_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string ALL_CAPS = 7;</code>
-     * @param value The bytes of the aLLCAPS to add.
-     */
-    private void addALLCAPSBytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      ensureALLCAPSIsMutable();
-      aLLCAPS_.add(value.toStringUtf8());
-    }
-
-    public static final int ALL_CAPS_MAP_FIELD_NUMBER = 8;
-    private static final class ALLCAPSMAPDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Boolean> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Boolean>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.BOOL,
-                  false);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Boolean> aLLCAPSMAP_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Boolean>
-    internalGetALLCAPSMAP() {
-      return aLLCAPSMAP_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Boolean>
-    internalGetMutableALLCAPSMAP() {
-      if (!aLLCAPSMAP_.isMutable()) {
-        aLLCAPSMAP_ = aLLCAPSMAP_.mutableCopy();
-      }
-      return aLLCAPSMAP_;
-    }
-    @java.lang.Override
-
-    public int getALLCAPSMAPCount() {
-      return internalGetALLCAPSMAP().size();
-    }
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsALLCAPSMAP(
-        int key) {
-      
-      return internalGetALLCAPSMAP().containsKey(key);
-    }
-    /**
-     * Use {@link #getALLCAPSMAPMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Boolean> getALLCAPSMAP() {
-      return getALLCAPSMAPMap();
-    }
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Boolean> getALLCAPSMAPMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetALLCAPSMAP());
-    }
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    @java.lang.Override
-
-    public boolean getALLCAPSMAPOrDefault(
-        int key,
-        boolean defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Boolean> map =
-          internalGetALLCAPSMAP();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    @java.lang.Override
-
-    public boolean getALLCAPSMAPOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Boolean> map =
-          internalGetALLCAPSMAP();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Boolean>
-    getMutableALLCAPSMAPMap() {
-      return internalGetMutableALLCAPSMAP();
-    }
-
-    public static final int HAS_UNDERBAR_PRECEDING_NUMERIC_1FOO_FIELD_NUMBER = 9;
-    private boolean hasUnderbarPrecedingNumeric1Foo_;
-    /**
-     * <code>bool has_underbar_preceding_numeric_1foo = 9;</code>
-     * @return The hasUnderbarPrecedingNumeric1foo.
-     */
-    @java.lang.Override
-    public boolean getHasUnderbarPrecedingNumeric1Foo() {
-      return hasUnderbarPrecedingNumeric1Foo_;
-    }
-    /**
-     * <code>bool has_underbar_preceding_numeric_1foo = 9;</code>
-     * @param value The hasUnderbarPrecedingNumeric1foo to set.
-     */
-    private void setHasUnderbarPrecedingNumeric1Foo(boolean value) {
-      
-      hasUnderbarPrecedingNumeric1Foo_ = value;
-    }
-    /**
-     * <code>bool has_underbar_preceding_numeric_1foo = 9;</code>
-     */
-    private void clearHasUnderbarPrecedingNumeric1Foo() {
-      
-      hasUnderbarPrecedingNumeric1Foo_ = false;
-    }
-
-    public static final int HAS_UNDERBAR_PRECEDING_NUMERIC_42BAR_FIELD_NUMBER = 10;
-    private boolean hasUnderbarPrecedingNumeric42Bar_;
-    /**
-     * <code>bool has_underbar_preceding_numeric_42bar = 10;</code>
-     * @return The hasUnderbarPrecedingNumeric42bar.
-     */
-    @java.lang.Override
-    public boolean getHasUnderbarPrecedingNumeric42Bar() {
-      return hasUnderbarPrecedingNumeric42Bar_;
-    }
-    /**
-     * <code>bool has_underbar_preceding_numeric_42bar = 10;</code>
-     * @param value The hasUnderbarPrecedingNumeric42bar to set.
-     */
-    private void setHasUnderbarPrecedingNumeric42Bar(boolean value) {
-      
-      hasUnderbarPrecedingNumeric42Bar_ = value;
-    }
-    /**
-     * <code>bool has_underbar_preceding_numeric_42bar = 10;</code>
-     */
-    private void clearHasUnderbarPrecedingNumeric42Bar() {
-      
-      hasUnderbarPrecedingNumeric42Bar_ = false;
-    }
-
-    public static final int HAS_UNDERBAR_PRECEDING_NUMERIC_123FOO42BAR_BAZ_FIELD_NUMBER = 11;
-    private boolean hasUnderbarPrecedingNumeric123Foo42BarBaz_;
-    /**
-     * <code>bool has_underbar_preceding_numeric_123foo42bar_baz = 11;</code>
-     * @return The hasUnderbarPrecedingNumeric123foo42barBaz.
-     */
-    @java.lang.Override
-    public boolean getHasUnderbarPrecedingNumeric123Foo42BarBaz() {
-      return hasUnderbarPrecedingNumeric123Foo42BarBaz_;
-    }
-    /**
-     * <code>bool has_underbar_preceding_numeric_123foo42bar_baz = 11;</code>
-     * @param value The hasUnderbarPrecedingNumeric123foo42barBaz to set.
-     */
-    private void setHasUnderbarPrecedingNumeric123Foo42BarBaz(boolean value) {
-      
-      hasUnderbarPrecedingNumeric123Foo42BarBaz_ = value;
-    }
-    /**
-     * <code>bool has_underbar_preceding_numeric_123foo42bar_baz = 11;</code>
-     */
-    private void clearHasUnderbarPrecedingNumeric123Foo42BarBaz() {
-      
-      hasUnderbarPrecedingNumeric123Foo42BarBaz_ = false;
-    }
-
-    public static final int EXTENSION_FIELD_NUMBER = 12;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> extension_;
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @return A list containing the extension.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getExtensionList() {
-      return extension_;
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @return The count of extension.
-     */
-    @java.lang.Override
-    public int getExtensionCount() {
-      return extension_.size();
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param index The index of the element to return.
-     * @return The extension at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getExtension(int index) {
-      return extension_.get(index);
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the extension at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getExtensionBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          extension_.get(index));
-    }
-    private void ensureExtensionIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          extension_;  if (!tmp.isModifiable()) {
-        extension_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param index The index to set the value at.
-     * @param value The extension to set.
-     */
-    private void setExtension(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureExtensionIsMutable();
-      extension_.set(index, value);
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param value The extension to add.
-     */
-    private void addExtension(
-        java.lang.String value) {
-      value.getClass();
-  ensureExtensionIsMutable();
-      extension_.add(value);
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param values The extension to add.
-     */
-    private void addAllExtension(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureExtensionIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, extension_);
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     */
-    private void clearExtension() {
-      extension_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string extension = 12;</code>
-     * @param value The bytes of the extension to add.
-     */
-    private void addExtensionBytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      ensureExtensionIsMutable();
-      extension_.add(value.toStringUtf8());
-    }
-
-    public static final int CLASS_FIELD_NUMBER = 13;
-    private java.lang.String class__;
-    /**
-     * <code>string class = 13;</code>
-     * @return The class.
-     */
-    @java.lang.Override
-    public java.lang.String getClass_() {
-      return class__;
-    }
-    /**
-     * <code>string class = 13;</code>
-     * @return The bytes for class.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getClass_Bytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(class__);
-    }
-    /**
-     * <code>string class = 13;</code>
-     * @param value The class to set.
-     */
-    private void setClass_(
-        java.lang.String value) {
-      value.getClass();
-  
-      class__ = value;
-    }
-    /**
-     * <code>string class = 13;</code>
-     */
-    private void clearClass_() {
-      
-      class__ = getDefaultInstance().getClass_();
-    }
-    /**
-     * <code>string class = 13;</code>
-     * @param value The bytes for class to set.
-     */
-    private void setClass_Bytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      class__ = value.toStringUtf8();
-      
-    }
-
-    public static final int INT_FIELD_NUMBER = 14;
-    private double int_;
-    /**
-     * <code>double int = 14;</code>
-     * @return The int.
-     */
-    @java.lang.Override
-    public double getInt() {
-      return int_;
-    }
-    /**
-     * <code>double int = 14;</code>
-     * @param value The int to set.
-     */
-    private void setInt(double value) {
-      
-      int_ = value;
-    }
-    /**
-     * <code>double int = 14;</code>
-     */
-    private void clearInt() {
-      
-      int_ = 0D;
-    }
-
-    public static final int LONG_FIELD_NUMBER = 15;
-    private boolean long_;
-    /**
-     * <code>bool long = 15;</code>
-     * @return The long.
-     */
-    @java.lang.Override
-    public boolean getLong() {
-      return long_;
-    }
-    /**
-     * <code>bool long = 15;</code>
-     * @param value The long to set.
-     */
-    private void setLong(boolean value) {
-      
-      long_ = value;
-    }
-    /**
-     * <code>bool long = 15;</code>
-     */
-    private void clearLong() {
-      
-      long_ = false;
-    }
-
-    public static final int BOOLEAN_FIELD_NUMBER = 16;
-    private long boolean_;
-    /**
-     * <code>int64 boolean = 16;</code>
-     * @return The boolean.
-     */
-    @java.lang.Override
-    public long getBoolean() {
-      return boolean_;
-    }
-    /**
-     * <code>int64 boolean = 16;</code>
-     * @param value The boolean to set.
-     */
-    private void setBoolean(long value) {
-      
-      boolean_ = value;
-    }
-    /**
-     * <code>int64 boolean = 16;</code>
-     */
-    private void clearBoolean() {
-      
-      boolean_ = 0L;
-    }
-
-    public static final int SEALED_FIELD_NUMBER = 17;
-    private java.lang.String sealed_;
-    /**
-     * <code>string sealed = 17;</code>
-     * @return The sealed.
-     */
-    @java.lang.Override
-    public java.lang.String getSealed() {
-      return sealed_;
-    }
-    /**
-     * <code>string sealed = 17;</code>
-     * @return The bytes for sealed.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getSealedBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(sealed_);
-    }
-    /**
-     * <code>string sealed = 17;</code>
-     * @param value The sealed to set.
-     */
-    private void setSealed(
-        java.lang.String value) {
-      value.getClass();
-  
-      sealed_ = value;
-    }
-    /**
-     * <code>string sealed = 17;</code>
-     */
-    private void clearSealed() {
-      
-      sealed_ = getDefaultInstance().getSealed();
-    }
-    /**
-     * <code>string sealed = 17;</code>
-     * @param value The bytes for sealed to set.
-     */
-    private void setSealedBytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      sealed_ = value.toStringUtf8();
-      
-    }
-
-    public static final int INTERFACE_FIELD_NUMBER = 18;
-    private float interface_;
-    /**
-     * <code>float interface = 18;</code>
-     * @return The interface.
-     */
-    @java.lang.Override
-    public float getInterface() {
-      return interface_;
-    }
-    /**
-     * <code>float interface = 18;</code>
-     * @param value The interface to set.
-     */
-    private void setInterface(float value) {
-      
-      interface_ = value;
-    }
-    /**
-     * <code>float interface = 18;</code>
-     */
-    private void clearInterface() {
-      
-      interface_ = 0F;
-    }
-
-    public static final int IN_FIELD_NUMBER = 19;
-    private int in_;
-    /**
-     * <code>int32 in = 19;</code>
-     * @return The in.
-     */
-    @java.lang.Override
-    public int getIn() {
-      return in_;
-    }
-    /**
-     * <code>int32 in = 19;</code>
-     * @param value The in to set.
-     */
-    private void setIn(int value) {
-      
-      in_ = value;
-    }
-    /**
-     * <code>int32 in = 19;</code>
-     */
-    private void clearIn() {
-      
-      in_ = 0;
-    }
-
-    public static final int OBJECT_FIELD_NUMBER = 20;
-    private java.lang.String object_;
-    /**
-     * <code>string object = 20;</code>
-     * @return The object.
-     */
-    @java.lang.Override
-    public java.lang.String getObject() {
-      return object_;
-    }
-    /**
-     * <code>string object = 20;</code>
-     * @return The bytes for object.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getObjectBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(object_);
-    }
-    /**
-     * <code>string object = 20;</code>
-     * @param value The object to set.
-     */
-    private void setObject(
-        java.lang.String value) {
-      value.getClass();
-  
-      object_ = value;
-    }
-    /**
-     * <code>string object = 20;</code>
-     */
-    private void clearObject() {
-      
-      object_ = getDefaultInstance().getObject();
-    }
-    /**
-     * <code>string object = 20;</code>
-     * @param value The bytes for object to set.
-     */
-    private void setObjectBytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      object_ = value.toStringUtf8();
-      
-    }
-
-    public static final int CACHED_SIZE_FIELD_NUMBER = 21;
-    private java.lang.String cachedSize__;
-    /**
-     * <code>string cached_size = 21;</code>
-     * @return The cachedSize.
-     */
-    @java.lang.Override
-    public java.lang.String getCachedSize_() {
-      return cachedSize__;
-    }
-    /**
-     * <code>string cached_size = 21;</code>
-     * @return The bytes for cachedSize.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getCachedSize_Bytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(cachedSize__);
-    }
-    /**
-     * <code>string cached_size = 21;</code>
-     * @param value The cachedSize to set.
-     */
-    private void setCachedSize_(
-        java.lang.String value) {
-      value.getClass();
-  
-      cachedSize__ = value;
-    }
-    /**
-     * <code>string cached_size = 21;</code>
-     */
-    private void clearCachedSize_() {
-      
-      cachedSize__ = getDefaultInstance().getCachedSize_();
-    }
-    /**
-     * <code>string cached_size = 21;</code>
-     * @param value The bytes for cachedSize to set.
-     */
-    private void setCachedSize_Bytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      cachedSize__ = value.toStringUtf8();
-      
-    }
-
-    public static final int SERIALIZED_SIZE_FIELD_NUMBER = 22;
-    private boolean serializedSize__;
-    /**
-     * <code>bool serialized_size = 22;</code>
-     * @return The serializedSize.
-     */
-    @java.lang.Override
-    public boolean getSerializedSize_() {
-      return serializedSize__;
-    }
-    /**
-     * <code>bool serialized_size = 22;</code>
-     * @param value The serializedSize to set.
-     */
-    private void setSerializedSize_(boolean value) {
-      
-      serializedSize__ = value;
-    }
-    /**
-     * <code>bool serialized_size = 22;</code>
-     */
-    private void clearSerializedSize_() {
-      
-      serializedSize__ = false;
-    }
-
-    public static final int VALUE_FIELD_NUMBER = 23;
-    private java.lang.String value_;
-    /**
-     * <code>string value = 23;</code>
-     * @return The value.
-     */
-    @java.lang.Override
-    public java.lang.String getValue() {
-      return value_;
-    }
-    /**
-     * <code>string value = 23;</code>
-     * @return The bytes for value.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getValueBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(value_);
-    }
-    /**
-     * <code>string value = 23;</code>
-     * @param value The value to set.
-     */
-    private void setValue(
-        java.lang.String value) {
-      value.getClass();
-  
-      value_ = value;
-    }
-    /**
-     * <code>string value = 23;</code>
-     */
-    private void clearValue() {
-      
-      value_ = getDefaultInstance().getValue();
-    }
-    /**
-     * <code>string value = 23;</code>
-     * @param value The bytes for value to set.
-     */
-    private void setValueBytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      value_ = value.toStringUtf8();
-      
-    }
-
-    public static final int INDEX_FIELD_NUMBER = 24;
-    private long index_;
-    /**
-     * <code>int64 index = 24;</code>
-     * @return The index.
-     */
-    @java.lang.Override
-    public long getIndex() {
-      return index_;
-    }
-    /**
-     * <code>int64 index = 24;</code>
-     * @param value The index to set.
-     */
-    private void setIndex(long value) {
-      
-      index_ = value;
-    }
-    /**
-     * <code>int64 index = 24;</code>
-     */
-    private void clearIndex() {
-      
-      index_ = 0L;
-    }
-
-    public static final int VALUES_FIELD_NUMBER = 25;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> values_;
-    /**
-     * <code>repeated string values = 25;</code>
-     * @return A list containing the values.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getValuesList() {
-      return values_;
-    }
-    /**
-     * <code>repeated string values = 25;</code>
-     * @return The count of values.
-     */
-    @java.lang.Override
-    public int getValuesCount() {
-      return values_.size();
-    }
-    /**
-     * <code>repeated string values = 25;</code>
-     * @param index The index of the element to return.
-     * @return The values at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getValues(int index) {
-      return values_.get(index);
-    }
-    /**
-     * <code>repeated string values = 25;</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the values at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getValuesBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          values_.get(index));
-    }
-    private void ensureValuesIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          values_;  if (!tmp.isModifiable()) {
-        values_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string values = 25;</code>
-     * @param index The index to set the value at.
-     * @param value The values to set.
-     */
-    private void setValues(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureValuesIsMutable();
-      values_.set(index, value);
-    }
-    /**
-     * <code>repeated string values = 25;</code>
-     * @param value The values to add.
-     */
-    private void addValues(
-        java.lang.String value) {
-      value.getClass();
-  ensureValuesIsMutable();
-      values_.add(value);
-    }
-    /**
-     * <code>repeated string values = 25;</code>
-     * @param values The values to add.
-     */
-    private void addAllValues(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureValuesIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, values_);
-    }
-    /**
-     * <code>repeated string values = 25;</code>
-     */
-    private void clearValues() {
-      values_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string values = 25;</code>
-     * @param value The bytes of the values to add.
-     */
-    private void addValuesBytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      ensureValuesIsMutable();
-      values_.add(value.toStringUtf8());
-    }
-
-    public static final int NEW_VALUES_FIELD_NUMBER = 26;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> newValues_;
-    /**
-     * <code>repeated string new_values = 26;</code>
-     * @return A list containing the newValues.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getNewValuesList() {
-      return newValues_;
-    }
-    /**
-     * <code>repeated string new_values = 26;</code>
-     * @return The count of newValues.
-     */
-    @java.lang.Override
-    public int getNewValuesCount() {
-      return newValues_.size();
-    }
-    /**
-     * <code>repeated string new_values = 26;</code>
-     * @param index The index of the element to return.
-     * @return The newValues at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getNewValues(int index) {
-      return newValues_.get(index);
-    }
-    /**
-     * <code>repeated string new_values = 26;</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the newValues at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getNewValuesBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          newValues_.get(index));
-    }
-    private void ensureNewValuesIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          newValues_;  if (!tmp.isModifiable()) {
-        newValues_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string new_values = 26;</code>
-     * @param index The index to set the value at.
-     * @param value The newValues to set.
-     */
-    private void setNewValues(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureNewValuesIsMutable();
-      newValues_.set(index, value);
-    }
-    /**
-     * <code>repeated string new_values = 26;</code>
-     * @param value The newValues to add.
-     */
-    private void addNewValues(
-        java.lang.String value) {
-      value.getClass();
-  ensureNewValuesIsMutable();
-      newValues_.add(value);
-    }
-    /**
-     * <code>repeated string new_values = 26;</code>
-     * @param values The newValues to add.
-     */
-    private void addAllNewValues(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureNewValuesIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, newValues_);
-    }
-    /**
-     * <code>repeated string new_values = 26;</code>
-     */
-    private void clearNewValues() {
-      newValues_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string new_values = 26;</code>
-     * @param value The bytes of the newValues to add.
-     */
-    private void addNewValuesBytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      ensureNewValuesIsMutable();
-      newValues_.add(value.toStringUtf8());
-    }
-
-    public static final int BUILDER_FIELD_NUMBER = 27;
-    private boolean builder_;
-    /**
-     * <code>bool builder = 27;</code>
-     * @return The builder.
-     */
-    @java.lang.Override
-    public boolean getBuilder() {
-      return builder_;
-    }
-    /**
-     * <code>bool builder = 27;</code>
-     * @param value The builder to set.
-     */
-    private void setBuilder(boolean value) {
-      
-      builder_ = value;
-    }
-    /**
-     * <code>bool builder = 27;</code>
-     */
-    private void clearBuilder() {
-      
-      builder_ = false;
-    }
-
-    public static final int K_FIELD_NUMBER = 28;
-    private static final class KDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> k_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetK() {
-      return k_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableK() {
-      if (!k_.isMutable()) {
-        k_ = k_.mutableCopy();
-      }
-      return k_;
-    }
-    @java.lang.Override
-
-    public int getKCount() {
-      return internalGetK().size();
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; k = 28;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsK(
-        int key) {
-      
-      return internalGetK().containsKey(key);
-    }
-    /**
-     * Use {@link #getKMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getK() {
-      return getKMap();
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; k = 28;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getKMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetK());
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; k = 28;</code>
-     */
-    @java.lang.Override
-
-    public int getKOrDefault(
-        int key,
-        int defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetK();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; k = 28;</code>
-     */
-    @java.lang.Override
-
-    public int getKOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetK();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; k = 28;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMutableKMap() {
-      return internalGetMutableK();
-    }
-
-    public static final int V_FIELD_NUMBER = 29;
-    private static final class VDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.String, java.lang.String> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.String, java.lang.String>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.STRING,
-                  "",
-                  com.google.protobuf.WireFormat.FieldType.STRING,
-                  "");
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.String, java.lang.String> v_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.String, java.lang.String>
-    internalGetV() {
-      return v_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.String, java.lang.String>
-    internalGetMutableV() {
-      if (!v_.isMutable()) {
-        v_ = v_.mutableCopy();
-      }
-      return v_;
-    }
-    @java.lang.Override
-
-    public int getVCount() {
-      return internalGetV().size();
-    }
-    /**
-     * <code>map&lt;string, string&gt; v = 29;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsV(
-        java.lang.String key) {
-      key.getClass();
-      return internalGetV().containsKey(key);
-    }
-    /**
-     * Use {@link #getVMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.String, java.lang.String> getV() {
-      return getVMap();
-    }
-    /**
-     * <code>map&lt;string, string&gt; v = 29;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.String, java.lang.String> getVMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetV());
-    }
-    /**
-     * <code>map&lt;string, string&gt; v = 29;</code>
-     */
-    @java.lang.Override
-
-    public java.lang.String getVOrDefault(
-        java.lang.String key,
-        java.lang.String defaultValue) {
-      key.getClass();
-      java.util.Map<java.lang.String, java.lang.String> map =
-          internalGetV();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;string, string&gt; v = 29;</code>
-     */
-    @java.lang.Override
-
-    public java.lang.String getVOrThrow(
-        java.lang.String key) {
-      key.getClass();
-      java.util.Map<java.lang.String, java.lang.String> map =
-          internalGetV();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;string, string&gt; v = 29;</code>
-     */
-    private java.util.Map<java.lang.String, java.lang.String>
-    getMutableVMap() {
-      return internalGetMutableV();
-    }
-
-    public static final int KEY_FIELD_NUMBER = 30;
-    private static final class KeyDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.String, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.String, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.STRING,
-                  "",
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.String, java.lang.Integer> key_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.String, java.lang.Integer>
-    internalGetKey() {
-      return key_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.String, java.lang.Integer>
-    internalGetMutableKey() {
-      if (!key_.isMutable()) {
-        key_ = key_.mutableCopy();
-      }
-      return key_;
-    }
-    @java.lang.Override
-
-    public int getKeyCount() {
-      return internalGetKey().size();
-    }
-    /**
-     * <code>map&lt;string, int32&gt; key = 30;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsKey(
-        java.lang.String key) {
-      key.getClass();
-      return internalGetKey().containsKey(key);
-    }
-    /**
-     * Use {@link #getKeyMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.String, java.lang.Integer> getKey() {
-      return getKeyMap();
-    }
-    /**
-     * <code>map&lt;string, int32&gt; key = 30;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.String, java.lang.Integer> getKeyMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetKey());
-    }
-    /**
-     * <code>map&lt;string, int32&gt; key = 30;</code>
-     */
-    @java.lang.Override
-
-    public int getKeyOrDefault(
-        java.lang.String key,
-        int defaultValue) {
-      key.getClass();
-      java.util.Map<java.lang.String, java.lang.Integer> map =
-          internalGetKey();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;string, int32&gt; key = 30;</code>
-     */
-    @java.lang.Override
-
-    public int getKeyOrThrow(
-        java.lang.String key) {
-      key.getClass();
-      java.util.Map<java.lang.String, java.lang.Integer> map =
-          internalGetKey();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;string, int32&gt; key = 30;</code>
-     */
-    private java.util.Map<java.lang.String, java.lang.Integer>
-    getMutableKeyMap() {
-      return internalGetMutableKey();
-    }
-
-    public static final int MAP_FIELD_NUMBER = 31;
-    private static final class MapDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.String> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.String>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.STRING,
-                  "");
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.String> map_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.String>
-    internalGetMap() {
-      return map_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.String>
-    internalGetMutableMap() {
-      if (!map_.isMutable()) {
-        map_ = map_.mutableCopy();
-      }
-      return map_;
-    }
-    @java.lang.Override
-
-    public int getMapCount() {
-      return internalGetMap().size();
-    }
-    /**
-     * <code>map&lt;int32, string&gt; map = 31;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMap(
-        int key) {
-      
-      return internalGetMap().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.String> getMap() {
-      return getMapMap();
-    }
-    /**
-     * <code>map&lt;int32, string&gt; map = 31;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.String> getMapMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMap());
-    }
-    /**
-     * <code>map&lt;int32, string&gt; map = 31;</code>
-     */
-    @java.lang.Override
-
-    public java.lang.String getMapOrDefault(
-        int key,
-        java.lang.String defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.String> map =
-          internalGetMap();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, string&gt; map = 31;</code>
-     */
-    @java.lang.Override
-
-    public java.lang.String getMapOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.String> map =
-          internalGetMap();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int32, string&gt; map = 31;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.String>
-    getMutableMapMap() {
-      return internalGetMutableMap();
-    }
-
-    public static final int PAIRS_FIELD_NUMBER = 32;
-    private static final class PairsDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.String, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.String, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.STRING,
-                  "",
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.String, java.lang.Integer> pairs_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.String, java.lang.Integer>
-    internalGetPairs() {
-      return pairs_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.String, java.lang.Integer>
-    internalGetMutablePairs() {
-      if (!pairs_.isMutable()) {
-        pairs_ = pairs_.mutableCopy();
-      }
-      return pairs_;
-    }
-    @java.lang.Override
-
-    public int getPairsCount() {
-      return internalGetPairs().size();
-    }
-    /**
-     * <code>map&lt;string, int32&gt; pairs = 32;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsPairs(
-        java.lang.String key) {
-      key.getClass();
-      return internalGetPairs().containsKey(key);
-    }
-    /**
-     * Use {@link #getPairsMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.String, java.lang.Integer> getPairs() {
-      return getPairsMap();
-    }
-    /**
-     * <code>map&lt;string, int32&gt; pairs = 32;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.String, java.lang.Integer> getPairsMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetPairs());
-    }
-    /**
-     * <code>map&lt;string, int32&gt; pairs = 32;</code>
-     */
-    @java.lang.Override
-
-    public int getPairsOrDefault(
-        java.lang.String key,
-        int defaultValue) {
-      key.getClass();
-      java.util.Map<java.lang.String, java.lang.Integer> map =
-          internalGetPairs();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;string, int32&gt; pairs = 32;</code>
-     */
-    @java.lang.Override
-
-    public int getPairsOrThrow(
-        java.lang.String key) {
-      key.getClass();
-      java.util.Map<java.lang.String, java.lang.Integer> map =
-          internalGetPairs();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;string, int32&gt; pairs = 32;</code>
-     */
-    private java.util.Map<java.lang.String, java.lang.Integer>
-    getMutablePairsMap() {
-      return internalGetMutablePairs();
-    }
-
-    public static final int _LEADING_UNDERSCORE_FIELD_NUMBER = 33;
-    private java.lang.String LeadingUnderscore_;
-    /**
-     * <code>string _leading_underscore = 33;</code>
-     * @return The leadingUnderscore.
-     */
-    @java.lang.Override
-    public java.lang.String getLeadingUnderscore() {
-      return LeadingUnderscore_;
-    }
-    /**
-     * <code>string _leading_underscore = 33;</code>
-     * @return The bytes for leadingUnderscore.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getLeadingUnderscoreBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(LeadingUnderscore_);
-    }
-    /**
-     * <code>string _leading_underscore = 33;</code>
-     * @param value The leadingUnderscore to set.
-     */
-    private void setLeadingUnderscore(
-        java.lang.String value) {
-      value.getClass();
-  
-      LeadingUnderscore_ = value;
-    }
-    /**
-     * <code>string _leading_underscore = 33;</code>
-     */
-    private void clearLeadingUnderscore() {
-      
-      LeadingUnderscore_ = getDefaultInstance().getLeadingUnderscore();
-    }
-    /**
-     * <code>string _leading_underscore = 33;</code>
-     * @param value The bytes for leadingUnderscore to set.
-     */
-    private void setLeadingUnderscoreBytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      LeadingUnderscore_ = value.toStringUtf8();
-      
-    }
-
-    public static final int OPTION_FIELD_NUMBER = 34;
-    /**
-     * <code>int32 option = 34;</code>
-     * @return Whether the option field is set.
-     */
-    @java.lang.Override
-    public boolean hasOption() {
-      return LeadingUnderscoreOneofCase_ == 34;
-    }
-    /**
-     * <code>int32 option = 34;</code>
-     * @return The option.
-     */
-    @java.lang.Override
-    public int getOption() {
-      if (LeadingUnderscoreOneofCase_ == 34) {
-        return (java.lang.Integer) LeadingUnderscoreOneof_;
-      }
-      return 0;
-    }
-    /**
-     * <code>int32 option = 34;</code>
-     * @param value The option to set.
-     */
-    private void setOption(int value) {
-      LeadingUnderscoreOneofCase_ = 34;
-      LeadingUnderscoreOneof_ = value;
-    }
-    /**
-     * <code>int32 option = 34;</code>
-     */
-    private void clearOption() {
-      if (LeadingUnderscoreOneofCase_ == 34) {
-        LeadingUnderscoreOneofCase_ = 0;
-        LeadingUnderscoreOneof_ = null;
-      }
-    }
-
-    public static evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3 parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3 parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3 parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3 parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3 parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3 parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3 parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3 parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3 parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3 parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3 parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3 parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3 prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code evil_names_proto3.EvilNamesProto3}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3, Builder> implements
-        // @@protoc_insertion_point(builder_implements:evil_names_proto3.EvilNamesProto3)
-        evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3OrBuilder {
-      // Construct using evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-      @java.lang.Override
-      public CamelCaseCase
-          getCamelCaseCase() {
-        return instance.getCamelCaseCase();
-      }
-
-      public Builder clearCamelCase() {
-        copyOnWrite();
-        instance.clearCamelCase();
-        return this;
-      }
-
-      @java.lang.Override
-      public LeadingUnderscoreOneofCase
-          getLeadingUnderscoreOneofCase() {
-        return instance.getLeadingUnderscoreOneofCase();
-      }
-
-      public Builder clearLeadingUnderscoreOneof() {
-        copyOnWrite();
-        instance.clearLeadingUnderscoreOneof();
-        return this;
-      }
-
-
-      /**
-       * <code>bool initialized = 1;</code>
-       * @return The initialized.
-       */
-      @java.lang.Override
-      public boolean getInitialized() {
-        return instance.getInitialized();
-      }
-      /**
-       * <code>bool initialized = 1;</code>
-       * @param value The initialized to set.
-       * @return This builder for chaining.
-       */
-      public Builder setInitialized(boolean value) {
-        copyOnWrite();
-        instance.setInitialized(value);
-        return this;
-      }
-      /**
-       * <code>bool initialized = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearInitialized() {
-        copyOnWrite();
-        instance.clearInitialized();
-        return this;
-      }
-
-      /**
-       * <code>bool has_foo = 2;</code>
-       * @return The hasFoo.
-       */
-      @java.lang.Override
-      public boolean getHasFoo() {
-        return instance.getHasFoo();
-      }
-      /**
-       * <code>bool has_foo = 2;</code>
-       * @param value The hasFoo to set.
-       * @return This builder for chaining.
-       */
-      public Builder setHasFoo(boolean value) {
-        copyOnWrite();
-        instance.setHasFoo(value);
-        return this;
-      }
-      /**
-       * <code>bool has_foo = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearHasFoo() {
-        copyOnWrite();
-        instance.clearHasFoo();
-        return this;
-      }
-
-      /**
-       * <code>string Bar = 3;</code>
-       * @return The bar.
-       */
-      @java.lang.Override
-      public java.lang.String getBar() {
-        return instance.getBar();
-      }
-      /**
-       * <code>string Bar = 3;</code>
-       * @return The bytes for bar.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getBarBytes() {
-        return instance.getBarBytes();
-      }
-      /**
-       * <code>string Bar = 3;</code>
-       * @param value The bar to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBar(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setBar(value);
-        return this;
-      }
-      /**
-       * <code>string Bar = 3;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearBar() {
-        copyOnWrite();
-        instance.clearBar();
-        return this;
-      }
-      /**
-       * <code>string Bar = 3;</code>
-       * @param value The bytes for bar to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBarBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setBarBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>bool is_initialized = 4;</code>
-       * @return The isInitialized.
-       */
-      @java.lang.Override
-      public boolean getIsInitialized() {
-        return instance.getIsInitialized();
-      }
-      /**
-       * <code>bool is_initialized = 4;</code>
-       * @param value The isInitialized to set.
-       * @return This builder for chaining.
-       */
-      public Builder setIsInitialized(boolean value) {
-        copyOnWrite();
-        instance.setIsInitialized(value);
-        return this;
-      }
-      /**
-       * <code>bool is_initialized = 4;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearIsInitialized() {
-        copyOnWrite();
-        instance.clearIsInitialized();
-        return this;
-      }
-
-      /**
-       * <code>string fooBar = 5;</code>
-       * @return Whether the fooBar field is set.
-       */
-      @java.lang.Override
-      public boolean hasFooBar() {
-        return instance.hasFooBar();
-      }
-      /**
-       * <code>string fooBar = 5;</code>
-       * @return The fooBar.
-       */
-      @java.lang.Override
-      public java.lang.String getFooBar() {
-        return instance.getFooBar();
-      }
-      /**
-       * <code>string fooBar = 5;</code>
-       * @return The bytes for fooBar.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getFooBarBytes() {
-        return instance.getFooBarBytes();
-      }
-      /**
-       * <code>string fooBar = 5;</code>
-       * @param value The fooBar to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooBar(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setFooBar(value);
-        return this;
-      }
-      /**
-       * <code>string fooBar = 5;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFooBar() {
-        copyOnWrite();
-        instance.clearFooBar();
-        return this;
-      }
-      /**
-       * <code>string fooBar = 5;</code>
-       * @param value The bytes for fooBar to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooBarBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setFooBarBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>repeated string ALL_CAPS = 7;</code>
-       * @return A list containing the aLLCAPS.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getALLCAPSList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getALLCAPSList());
-      }
-      /**
-       * <code>repeated string ALL_CAPS = 7;</code>
-       * @return The count of aLLCAPS.
-       */
-      @java.lang.Override
-      public int getALLCAPSCount() {
-        return instance.getALLCAPSCount();
-      }
-      /**
-       * <code>repeated string ALL_CAPS = 7;</code>
-       * @param index The index of the element to return.
-       * @return The aLLCAPS at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getALLCAPS(int index) {
-        return instance.getALLCAPS(index);
-      }
-      /**
-       * <code>repeated string ALL_CAPS = 7;</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the aLLCAPS at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getALLCAPSBytes(int index) {
-        return instance.getALLCAPSBytes(index);
-      }
-      /**
-       * <code>repeated string ALL_CAPS = 7;</code>
-       * @param index The index to set the value at.
-       * @param value The aLLCAPS to set.
-       * @return This builder for chaining.
-       */
-      public Builder setALLCAPS(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setALLCAPS(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string ALL_CAPS = 7;</code>
-       * @param value The aLLCAPS to add.
-       * @return This builder for chaining.
-       */
-      public Builder addALLCAPS(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addALLCAPS(value);
-        return this;
-      }
-      /**
-       * <code>repeated string ALL_CAPS = 7;</code>
-       * @param values The aLLCAPS to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllALLCAPS(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllALLCAPS(values);
-        return this;
-      }
-      /**
-       * <code>repeated string ALL_CAPS = 7;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearALLCAPS() {
-        copyOnWrite();
-        instance.clearALLCAPS();
-        return this;
-      }
-      /**
-       * <code>repeated string ALL_CAPS = 7;</code>
-       * @param value The bytes of the aLLCAPS to add.
-       * @return This builder for chaining.
-       */
-      public Builder addALLCAPSBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addALLCAPSBytes(value);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getALLCAPSMAPCount() {
-        return instance.getALLCAPSMAPMap().size();
-      }
-      /**
-       * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsALLCAPSMAP(
-          int key) {
-        
-        return instance.getALLCAPSMAPMap().containsKey(key);
-      }
-
-      public Builder clearALLCAPSMAP() {
-        copyOnWrite();
-        instance.getMutableALLCAPSMAPMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-       */
-
-      public Builder removeALLCAPSMAP(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableALLCAPSMAPMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getALLCAPSMAPMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Boolean> getALLCAPSMAP() {
-        return getALLCAPSMAPMap();
-      }
-      /**
-       * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Boolean> getALLCAPSMAPMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getALLCAPSMAPMap());
-      }
-      /**
-       * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-       */
-      @java.lang.Override
-
-      public boolean getALLCAPSMAPOrDefault(
-          int key,
-          boolean defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Boolean> map =
-            instance.getALLCAPSMAPMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-       */
-      @java.lang.Override
-
-      public boolean getALLCAPSMAPOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Boolean> map =
-            instance.getALLCAPSMAPMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-       */
-      public Builder putALLCAPSMAP(
-          int key,
-          boolean value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableALLCAPSMAPMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, bool&gt; ALL_CAPS_MAP = 8;</code>
-       */
-      public Builder putAllALLCAPSMAP(
-          java.util.Map<java.lang.Integer, java.lang.Boolean> values) {
-        copyOnWrite();
-        instance.getMutableALLCAPSMAPMap().putAll(values);
-        return this;
-      }
-
-      /**
-       * <code>bool has_underbar_preceding_numeric_1foo = 9;</code>
-       * @return The hasUnderbarPrecedingNumeric1foo.
-       */
-      @java.lang.Override
-      public boolean getHasUnderbarPrecedingNumeric1Foo() {
-        return instance.getHasUnderbarPrecedingNumeric1Foo();
-      }
-      /**
-       * <code>bool has_underbar_preceding_numeric_1foo = 9;</code>
-       * @param value The hasUnderbarPrecedingNumeric1foo to set.
-       * @return This builder for chaining.
-       */
-      public Builder setHasUnderbarPrecedingNumeric1Foo(boolean value) {
-        copyOnWrite();
-        instance.setHasUnderbarPrecedingNumeric1Foo(value);
-        return this;
-      }
-      /**
-       * <code>bool has_underbar_preceding_numeric_1foo = 9;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearHasUnderbarPrecedingNumeric1Foo() {
-        copyOnWrite();
-        instance.clearHasUnderbarPrecedingNumeric1Foo();
-        return this;
-      }
-
-      /**
-       * <code>bool has_underbar_preceding_numeric_42bar = 10;</code>
-       * @return The hasUnderbarPrecedingNumeric42bar.
-       */
-      @java.lang.Override
-      public boolean getHasUnderbarPrecedingNumeric42Bar() {
-        return instance.getHasUnderbarPrecedingNumeric42Bar();
-      }
-      /**
-       * <code>bool has_underbar_preceding_numeric_42bar = 10;</code>
-       * @param value The hasUnderbarPrecedingNumeric42bar to set.
-       * @return This builder for chaining.
-       */
-      public Builder setHasUnderbarPrecedingNumeric42Bar(boolean value) {
-        copyOnWrite();
-        instance.setHasUnderbarPrecedingNumeric42Bar(value);
-        return this;
-      }
-      /**
-       * <code>bool has_underbar_preceding_numeric_42bar = 10;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearHasUnderbarPrecedingNumeric42Bar() {
-        copyOnWrite();
-        instance.clearHasUnderbarPrecedingNumeric42Bar();
-        return this;
-      }
-
-      /**
-       * <code>bool has_underbar_preceding_numeric_123foo42bar_baz = 11;</code>
-       * @return The hasUnderbarPrecedingNumeric123foo42barBaz.
-       */
-      @java.lang.Override
-      public boolean getHasUnderbarPrecedingNumeric123Foo42BarBaz() {
-        return instance.getHasUnderbarPrecedingNumeric123Foo42BarBaz();
-      }
-      /**
-       * <code>bool has_underbar_preceding_numeric_123foo42bar_baz = 11;</code>
-       * @param value The hasUnderbarPrecedingNumeric123foo42barBaz to set.
-       * @return This builder for chaining.
-       */
-      public Builder setHasUnderbarPrecedingNumeric123Foo42BarBaz(boolean value) {
-        copyOnWrite();
-        instance.setHasUnderbarPrecedingNumeric123Foo42BarBaz(value);
-        return this;
-      }
-      /**
-       * <code>bool has_underbar_preceding_numeric_123foo42bar_baz = 11;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearHasUnderbarPrecedingNumeric123Foo42BarBaz() {
-        copyOnWrite();
-        instance.clearHasUnderbarPrecedingNumeric123Foo42BarBaz();
-        return this;
-      }
-
-      /**
-       * <code>repeated string extension = 12;</code>
-       * @return A list containing the extension.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getExtensionList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getExtensionList());
-      }
-      /**
-       * <code>repeated string extension = 12;</code>
-       * @return The count of extension.
-       */
-      @java.lang.Override
-      public int getExtensionCount() {
-        return instance.getExtensionCount();
-      }
-      /**
-       * <code>repeated string extension = 12;</code>
-       * @param index The index of the element to return.
-       * @return The extension at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getExtension(int index) {
-        return instance.getExtension(index);
-      }
-      /**
-       * <code>repeated string extension = 12;</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the extension at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getExtensionBytes(int index) {
-        return instance.getExtensionBytes(index);
-      }
-      /**
-       * <code>repeated string extension = 12;</code>
-       * @param index The index to set the value at.
-       * @param value The extension to set.
-       * @return This builder for chaining.
-       */
-      public Builder setExtension(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setExtension(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string extension = 12;</code>
-       * @param value The extension to add.
-       * @return This builder for chaining.
-       */
-      public Builder addExtension(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addExtension(value);
-        return this;
-      }
-      /**
-       * <code>repeated string extension = 12;</code>
-       * @param values The extension to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllExtension(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllExtension(values);
-        return this;
-      }
-      /**
-       * <code>repeated string extension = 12;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearExtension() {
-        copyOnWrite();
-        instance.clearExtension();
-        return this;
-      }
-      /**
-       * <code>repeated string extension = 12;</code>
-       * @param value The bytes of the extension to add.
-       * @return This builder for chaining.
-       */
-      public Builder addExtensionBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addExtensionBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>string class = 13;</code>
-       * @return The class.
-       */
-      @java.lang.Override
-      public java.lang.String getClass_() {
-        return instance.getClass_();
-      }
-      /**
-       * <code>string class = 13;</code>
-       * @return The bytes for class.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getClass_Bytes() {
-        return instance.getClass_Bytes();
-      }
-      /**
-       * <code>string class = 13;</code>
-       * @param value The class to set.
-       * @return This builder for chaining.
-       */
-      public Builder setClass_(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setClass_(value);
-        return this;
-      }
-      /**
-       * <code>string class = 13;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearClass_() {
-        copyOnWrite();
-        instance.clearClass_();
-        return this;
-      }
-      /**
-       * <code>string class = 13;</code>
-       * @param value The bytes for class to set.
-       * @return This builder for chaining.
-       */
-      public Builder setClass_Bytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setClass_Bytes(value);
-        return this;
-      }
-
-      /**
-       * <code>double int = 14;</code>
-       * @return The int.
-       */
-      @java.lang.Override
-      public double getInt() {
-        return instance.getInt();
-      }
-      /**
-       * <code>double int = 14;</code>
-       * @param value The int to set.
-       * @return This builder for chaining.
-       */
-      public Builder setInt(double value) {
-        copyOnWrite();
-        instance.setInt(value);
-        return this;
-      }
-      /**
-       * <code>double int = 14;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearInt() {
-        copyOnWrite();
-        instance.clearInt();
-        return this;
-      }
-
-      /**
-       * <code>bool long = 15;</code>
-       * @return The long.
-       */
-      @java.lang.Override
-      public boolean getLong() {
-        return instance.getLong();
-      }
-      /**
-       * <code>bool long = 15;</code>
-       * @param value The long to set.
-       * @return This builder for chaining.
-       */
-      public Builder setLong(boolean value) {
-        copyOnWrite();
-        instance.setLong(value);
-        return this;
-      }
-      /**
-       * <code>bool long = 15;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearLong() {
-        copyOnWrite();
-        instance.clearLong();
-        return this;
-      }
-
-      /**
-       * <code>int64 boolean = 16;</code>
-       * @return The boolean.
-       */
-      @java.lang.Override
-      public long getBoolean() {
-        return instance.getBoolean();
-      }
-      /**
-       * <code>int64 boolean = 16;</code>
-       * @param value The boolean to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBoolean(long value) {
-        copyOnWrite();
-        instance.setBoolean(value);
-        return this;
-      }
-      /**
-       * <code>int64 boolean = 16;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearBoolean() {
-        copyOnWrite();
-        instance.clearBoolean();
-        return this;
-      }
-
-      /**
-       * <code>string sealed = 17;</code>
-       * @return The sealed.
-       */
-      @java.lang.Override
-      public java.lang.String getSealed() {
-        return instance.getSealed();
-      }
-      /**
-       * <code>string sealed = 17;</code>
-       * @return The bytes for sealed.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getSealedBytes() {
-        return instance.getSealedBytes();
-      }
-      /**
-       * <code>string sealed = 17;</code>
-       * @param value The sealed to set.
-       * @return This builder for chaining.
-       */
-      public Builder setSealed(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setSealed(value);
-        return this;
-      }
-      /**
-       * <code>string sealed = 17;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearSealed() {
-        copyOnWrite();
-        instance.clearSealed();
-        return this;
-      }
-      /**
-       * <code>string sealed = 17;</code>
-       * @param value The bytes for sealed to set.
-       * @return This builder for chaining.
-       */
-      public Builder setSealedBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setSealedBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>float interface = 18;</code>
-       * @return The interface.
-       */
-      @java.lang.Override
-      public float getInterface() {
-        return instance.getInterface();
-      }
-      /**
-       * <code>float interface = 18;</code>
-       * @param value The interface to set.
-       * @return This builder for chaining.
-       */
-      public Builder setInterface(float value) {
-        copyOnWrite();
-        instance.setInterface(value);
-        return this;
-      }
-      /**
-       * <code>float interface = 18;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearInterface() {
-        copyOnWrite();
-        instance.clearInterface();
-        return this;
-      }
-
-      /**
-       * <code>int32 in = 19;</code>
-       * @return The in.
-       */
-      @java.lang.Override
-      public int getIn() {
-        return instance.getIn();
-      }
-      /**
-       * <code>int32 in = 19;</code>
-       * @param value The in to set.
-       * @return This builder for chaining.
-       */
-      public Builder setIn(int value) {
-        copyOnWrite();
-        instance.setIn(value);
-        return this;
-      }
-      /**
-       * <code>int32 in = 19;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearIn() {
-        copyOnWrite();
-        instance.clearIn();
-        return this;
-      }
-
-      /**
-       * <code>string object = 20;</code>
-       * @return The object.
-       */
-      @java.lang.Override
-      public java.lang.String getObject() {
-        return instance.getObject();
-      }
-      /**
-       * <code>string object = 20;</code>
-       * @return The bytes for object.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getObjectBytes() {
-        return instance.getObjectBytes();
-      }
-      /**
-       * <code>string object = 20;</code>
-       * @param value The object to set.
-       * @return This builder for chaining.
-       */
-      public Builder setObject(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setObject(value);
-        return this;
-      }
-      /**
-       * <code>string object = 20;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearObject() {
-        copyOnWrite();
-        instance.clearObject();
-        return this;
-      }
-      /**
-       * <code>string object = 20;</code>
-       * @param value The bytes for object to set.
-       * @return This builder for chaining.
-       */
-      public Builder setObjectBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setObjectBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>string cached_size = 21;</code>
-       * @return The cachedSize.
-       */
-      @java.lang.Override
-      public java.lang.String getCachedSize_() {
-        return instance.getCachedSize_();
-      }
-      /**
-       * <code>string cached_size = 21;</code>
-       * @return The bytes for cachedSize.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getCachedSize_Bytes() {
-        return instance.getCachedSize_Bytes();
-      }
-      /**
-       * <code>string cached_size = 21;</code>
-       * @param value The cachedSize to set.
-       * @return This builder for chaining.
-       */
-      public Builder setCachedSize_(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setCachedSize_(value);
-        return this;
-      }
-      /**
-       * <code>string cached_size = 21;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearCachedSize_() {
-        copyOnWrite();
-        instance.clearCachedSize_();
-        return this;
-      }
-      /**
-       * <code>string cached_size = 21;</code>
-       * @param value The bytes for cachedSize to set.
-       * @return This builder for chaining.
-       */
-      public Builder setCachedSize_Bytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setCachedSize_Bytes(value);
-        return this;
-      }
-
-      /**
-       * <code>bool serialized_size = 22;</code>
-       * @return The serializedSize.
-       */
-      @java.lang.Override
-      public boolean getSerializedSize_() {
-        return instance.getSerializedSize_();
-      }
-      /**
-       * <code>bool serialized_size = 22;</code>
-       * @param value The serializedSize to set.
-       * @return This builder for chaining.
-       */
-      public Builder setSerializedSize_(boolean value) {
-        copyOnWrite();
-        instance.setSerializedSize_(value);
-        return this;
-      }
-      /**
-       * <code>bool serialized_size = 22;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearSerializedSize_() {
-        copyOnWrite();
-        instance.clearSerializedSize_();
-        return this;
-      }
-
-      /**
-       * <code>string value = 23;</code>
-       * @return The value.
-       */
-      @java.lang.Override
-      public java.lang.String getValue() {
-        return instance.getValue();
-      }
-      /**
-       * <code>string value = 23;</code>
-       * @return The bytes for value.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getValueBytes() {
-        return instance.getValueBytes();
-      }
-      /**
-       * <code>string value = 23;</code>
-       * @param value The value to set.
-       * @return This builder for chaining.
-       */
-      public Builder setValue(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setValue(value);
-        return this;
-      }
-      /**
-       * <code>string value = 23;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearValue() {
-        copyOnWrite();
-        instance.clearValue();
-        return this;
-      }
-      /**
-       * <code>string value = 23;</code>
-       * @param value The bytes for value to set.
-       * @return This builder for chaining.
-       */
-      public Builder setValueBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setValueBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>int64 index = 24;</code>
-       * @return The index.
-       */
-      @java.lang.Override
-      public long getIndex() {
-        return instance.getIndex();
-      }
-      /**
-       * <code>int64 index = 24;</code>
-       * @param value The index to set.
-       * @return This builder for chaining.
-       */
-      public Builder setIndex(long value) {
-        copyOnWrite();
-        instance.setIndex(value);
-        return this;
-      }
-      /**
-       * <code>int64 index = 24;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearIndex() {
-        copyOnWrite();
-        instance.clearIndex();
-        return this;
-      }
-
-      /**
-       * <code>repeated string values = 25;</code>
-       * @return A list containing the values.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getValuesList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getValuesList());
-      }
-      /**
-       * <code>repeated string values = 25;</code>
-       * @return The count of values.
-       */
-      @java.lang.Override
-      public int getValuesCount() {
-        return instance.getValuesCount();
-      }
-      /**
-       * <code>repeated string values = 25;</code>
-       * @param index The index of the element to return.
-       * @return The values at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getValues(int index) {
-        return instance.getValues(index);
-      }
-      /**
-       * <code>repeated string values = 25;</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the values at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getValuesBytes(int index) {
-        return instance.getValuesBytes(index);
-      }
-      /**
-       * <code>repeated string values = 25;</code>
-       * @param index The index to set the value at.
-       * @param value The values to set.
-       * @return This builder for chaining.
-       */
-      public Builder setValues(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setValues(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string values = 25;</code>
-       * @param value The values to add.
-       * @return This builder for chaining.
-       */
-      public Builder addValues(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addValues(value);
-        return this;
-      }
-      /**
-       * <code>repeated string values = 25;</code>
-       * @param values The values to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllValues(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllValues(values);
-        return this;
-      }
-      /**
-       * <code>repeated string values = 25;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearValues() {
-        copyOnWrite();
-        instance.clearValues();
-        return this;
-      }
-      /**
-       * <code>repeated string values = 25;</code>
-       * @param value The bytes of the values to add.
-       * @return This builder for chaining.
-       */
-      public Builder addValuesBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addValuesBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>repeated string new_values = 26;</code>
-       * @return A list containing the newValues.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getNewValuesList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getNewValuesList());
-      }
-      /**
-       * <code>repeated string new_values = 26;</code>
-       * @return The count of newValues.
-       */
-      @java.lang.Override
-      public int getNewValuesCount() {
-        return instance.getNewValuesCount();
-      }
-      /**
-       * <code>repeated string new_values = 26;</code>
-       * @param index The index of the element to return.
-       * @return The newValues at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getNewValues(int index) {
-        return instance.getNewValues(index);
-      }
-      /**
-       * <code>repeated string new_values = 26;</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the newValues at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getNewValuesBytes(int index) {
-        return instance.getNewValuesBytes(index);
-      }
-      /**
-       * <code>repeated string new_values = 26;</code>
-       * @param index The index to set the value at.
-       * @param value The newValues to set.
-       * @return This builder for chaining.
-       */
-      public Builder setNewValues(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setNewValues(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string new_values = 26;</code>
-       * @param value The newValues to add.
-       * @return This builder for chaining.
-       */
-      public Builder addNewValues(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addNewValues(value);
-        return this;
-      }
-      /**
-       * <code>repeated string new_values = 26;</code>
-       * @param values The newValues to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllNewValues(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllNewValues(values);
-        return this;
-      }
-      /**
-       * <code>repeated string new_values = 26;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearNewValues() {
-        copyOnWrite();
-        instance.clearNewValues();
-        return this;
-      }
-      /**
-       * <code>repeated string new_values = 26;</code>
-       * @param value The bytes of the newValues to add.
-       * @return This builder for chaining.
-       */
-      public Builder addNewValuesBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addNewValuesBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>bool builder = 27;</code>
-       * @return The builder.
-       */
-      @java.lang.Override
-      public boolean getBuilder() {
-        return instance.getBuilder();
-      }
-      /**
-       * <code>bool builder = 27;</code>
-       * @param value The builder to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBuilder(boolean value) {
-        copyOnWrite();
-        instance.setBuilder(value);
-        return this;
-      }
-      /**
-       * <code>bool builder = 27;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearBuilder() {
-        copyOnWrite();
-        instance.clearBuilder();
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getKCount() {
-        return instance.getKMap().size();
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; k = 28;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsK(
-          int key) {
-        
-        return instance.getKMap().containsKey(key);
-      }
-
-      public Builder clearK() {
-        copyOnWrite();
-        instance.getMutableKMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; k = 28;</code>
-       */
-
-      public Builder removeK(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableKMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getKMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getK() {
-        return getKMap();
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; k = 28;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getKMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getKMap());
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; k = 28;</code>
-       */
-      @java.lang.Override
-
-      public int getKOrDefault(
-          int key,
-          int defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getKMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; k = 28;</code>
-       */
-      @java.lang.Override
-
-      public int getKOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getKMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; k = 28;</code>
-       */
-      public Builder putK(
-          int key,
-          int value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableKMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; k = 28;</code>
-       */
-      public Builder putAllK(
-          java.util.Map<java.lang.Integer, java.lang.Integer> values) {
-        copyOnWrite();
-        instance.getMutableKMap().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getVCount() {
-        return instance.getVMap().size();
-      }
-      /**
-       * <code>map&lt;string, string&gt; v = 29;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsV(
-          java.lang.String key) {
-        key.getClass();
-        return instance.getVMap().containsKey(key);
-      }
-
-      public Builder clearV() {
-        copyOnWrite();
-        instance.getMutableVMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;string, string&gt; v = 29;</code>
-       */
-
-      public Builder removeV(
-          java.lang.String key) {
-        key.getClass();
-        copyOnWrite();
-        instance.getMutableVMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getVMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.String, java.lang.String> getV() {
-        return getVMap();
-      }
-      /**
-       * <code>map&lt;string, string&gt; v = 29;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.String, java.lang.String> getVMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getVMap());
-      }
-      /**
-       * <code>map&lt;string, string&gt; v = 29;</code>
-       */
-      @java.lang.Override
-
-      public java.lang.String getVOrDefault(
-          java.lang.String key,
-          java.lang.String defaultValue) {
-        key.getClass();
-        java.util.Map<java.lang.String, java.lang.String> map =
-            instance.getVMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;string, string&gt; v = 29;</code>
-       */
-      @java.lang.Override
-
-      public java.lang.String getVOrThrow(
-          java.lang.String key) {
-        key.getClass();
-        java.util.Map<java.lang.String, java.lang.String> map =
-            instance.getVMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;string, string&gt; v = 29;</code>
-       */
-      public Builder putV(
-          java.lang.String key,
-          java.lang.String value) {
-        key.getClass();
-        value.getClass();
-        copyOnWrite();
-        instance.getMutableVMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;string, string&gt; v = 29;</code>
-       */
-      public Builder putAllV(
-          java.util.Map<java.lang.String, java.lang.String> values) {
-        copyOnWrite();
-        instance.getMutableVMap().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getKeyCount() {
-        return instance.getKeyMap().size();
-      }
-      /**
-       * <code>map&lt;string, int32&gt; key = 30;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsKey(
-          java.lang.String key) {
-        key.getClass();
-        return instance.getKeyMap().containsKey(key);
-      }
-
-      public Builder clearKey() {
-        copyOnWrite();
-        instance.getMutableKeyMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;string, int32&gt; key = 30;</code>
-       */
-
-      public Builder removeKey(
-          java.lang.String key) {
-        key.getClass();
-        copyOnWrite();
-        instance.getMutableKeyMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getKeyMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.String, java.lang.Integer> getKey() {
-        return getKeyMap();
-      }
-      /**
-       * <code>map&lt;string, int32&gt; key = 30;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.String, java.lang.Integer> getKeyMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getKeyMap());
-      }
-      /**
-       * <code>map&lt;string, int32&gt; key = 30;</code>
-       */
-      @java.lang.Override
-
-      public int getKeyOrDefault(
-          java.lang.String key,
-          int defaultValue) {
-        key.getClass();
-        java.util.Map<java.lang.String, java.lang.Integer> map =
-            instance.getKeyMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;string, int32&gt; key = 30;</code>
-       */
-      @java.lang.Override
-
-      public int getKeyOrThrow(
-          java.lang.String key) {
-        key.getClass();
-        java.util.Map<java.lang.String, java.lang.Integer> map =
-            instance.getKeyMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;string, int32&gt; key = 30;</code>
-       */
-      public Builder putKey(
-          java.lang.String key,
-          int value) {
-        key.getClass();
-        
-        copyOnWrite();
-        instance.getMutableKeyMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;string, int32&gt; key = 30;</code>
-       */
-      public Builder putAllKey(
-          java.util.Map<java.lang.String, java.lang.Integer> values) {
-        copyOnWrite();
-        instance.getMutableKeyMap().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapCount() {
-        return instance.getMapMap().size();
-      }
-      /**
-       * <code>map&lt;int32, string&gt; map = 31;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMap(
-          int key) {
-        
-        return instance.getMapMap().containsKey(key);
-      }
-
-      public Builder clearMap() {
-        copyOnWrite();
-        instance.getMutableMapMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, string&gt; map = 31;</code>
-       */
-
-      public Builder removeMap(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.String> getMap() {
-        return getMapMap();
-      }
-      /**
-       * <code>map&lt;int32, string&gt; map = 31;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.String> getMapMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapMap());
-      }
-      /**
-       * <code>map&lt;int32, string&gt; map = 31;</code>
-       */
-      @java.lang.Override
-
-      public java.lang.String getMapOrDefault(
-          int key,
-          java.lang.String defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.String> map =
-            instance.getMapMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, string&gt; map = 31;</code>
-       */
-      @java.lang.Override
-
-      public java.lang.String getMapOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.String> map =
-            instance.getMapMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, string&gt; map = 31;</code>
-       */
-      public Builder putMap(
-          int key,
-          java.lang.String value) {
-        
-        value.getClass();
-        copyOnWrite();
-        instance.getMutableMapMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, string&gt; map = 31;</code>
-       */
-      public Builder putAllMap(
-          java.util.Map<java.lang.Integer, java.lang.String> values) {
-        copyOnWrite();
-        instance.getMutableMapMap().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getPairsCount() {
-        return instance.getPairsMap().size();
-      }
-      /**
-       * <code>map&lt;string, int32&gt; pairs = 32;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsPairs(
-          java.lang.String key) {
-        key.getClass();
-        return instance.getPairsMap().containsKey(key);
-      }
-
-      public Builder clearPairs() {
-        copyOnWrite();
-        instance.getMutablePairsMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;string, int32&gt; pairs = 32;</code>
-       */
-
-      public Builder removePairs(
-          java.lang.String key) {
-        key.getClass();
-        copyOnWrite();
-        instance.getMutablePairsMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getPairsMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.String, java.lang.Integer> getPairs() {
-        return getPairsMap();
-      }
-      /**
-       * <code>map&lt;string, int32&gt; pairs = 32;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.String, java.lang.Integer> getPairsMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getPairsMap());
-      }
-      /**
-       * <code>map&lt;string, int32&gt; pairs = 32;</code>
-       */
-      @java.lang.Override
-
-      public int getPairsOrDefault(
-          java.lang.String key,
-          int defaultValue) {
-        key.getClass();
-        java.util.Map<java.lang.String, java.lang.Integer> map =
-            instance.getPairsMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;string, int32&gt; pairs = 32;</code>
-       */
-      @java.lang.Override
-
-      public int getPairsOrThrow(
-          java.lang.String key) {
-        key.getClass();
-        java.util.Map<java.lang.String, java.lang.Integer> map =
-            instance.getPairsMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;string, int32&gt; pairs = 32;</code>
-       */
-      public Builder putPairs(
-          java.lang.String key,
-          int value) {
-        key.getClass();
-        
-        copyOnWrite();
-        instance.getMutablePairsMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;string, int32&gt; pairs = 32;</code>
-       */
-      public Builder putAllPairs(
-          java.util.Map<java.lang.String, java.lang.Integer> values) {
-        copyOnWrite();
-        instance.getMutablePairsMap().putAll(values);
-        return this;
-      }
-
-      /**
-       * <code>string _leading_underscore = 33;</code>
-       * @return The leadingUnderscore.
-       */
-      @java.lang.Override
-      public java.lang.String getLeadingUnderscore() {
-        return instance.getLeadingUnderscore();
-      }
-      /**
-       * <code>string _leading_underscore = 33;</code>
-       * @return The bytes for leadingUnderscore.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getLeadingUnderscoreBytes() {
-        return instance.getLeadingUnderscoreBytes();
-      }
-      /**
-       * <code>string _leading_underscore = 33;</code>
-       * @param value The leadingUnderscore to set.
-       * @return This builder for chaining.
-       */
-      public Builder setLeadingUnderscore(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setLeadingUnderscore(value);
-        return this;
-      }
-      /**
-       * <code>string _leading_underscore = 33;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearLeadingUnderscore() {
-        copyOnWrite();
-        instance.clearLeadingUnderscore();
-        return this;
-      }
-      /**
-       * <code>string _leading_underscore = 33;</code>
-       * @param value The bytes for leadingUnderscore to set.
-       * @return This builder for chaining.
-       */
-      public Builder setLeadingUnderscoreBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setLeadingUnderscoreBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>int32 option = 34;</code>
-       * @return Whether the option field is set.
-       */
-      @java.lang.Override
-      public boolean hasOption() {
-        return instance.hasOption();
-      }
-      /**
-       * <code>int32 option = 34;</code>
-       * @return The option.
-       */
-      @java.lang.Override
-      public int getOption() {
-        return instance.getOption();
-      }
-      /**
-       * <code>int32 option = 34;</code>
-       * @param value The option to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOption(int value) {
-        copyOnWrite();
-        instance.setOption(value);
-        return this;
-      }
-      /**
-       * <code>int32 option = 34;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOption() {
-        copyOnWrite();
-        instance.clearOption();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:evil_names_proto3.EvilNamesProto3)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "camelCase_",
-              "camelCaseCase_",
-              "LeadingUnderscoreOneof_",
-              "LeadingUnderscoreOneofCase_",
-              "initialized_",
-              "hasFoo_",
-              "bar_",
-              "isInitialized_",
-              "aLLCAPS_",
-              "aLLCAPSMAP_",
-              ALLCAPSMAPDefaultEntryHolder.defaultEntry,
-              "hasUnderbarPrecedingNumeric1Foo_",
-              "hasUnderbarPrecedingNumeric42Bar_",
-              "hasUnderbarPrecedingNumeric123Foo42BarBaz_",
-              "extension_",
-              "class__",
-              "int_",
-              "long_",
-              "boolean_",
-              "sealed_",
-              "interface_",
-              "in_",
-              "object_",
-              "cachedSize__",
-              "serializedSize__",
-              "value_",
-              "index_",
-              "values_",
-              "newValues_",
-              "builder_",
-              "k_",
-              KDefaultEntryHolder.defaultEntry,
-              "v_",
-              VDefaultEntryHolder.defaultEntry,
-              "key_",
-              KeyDefaultEntryHolder.defaultEntry,
-              "map_",
-              MapDefaultEntryHolder.defaultEntry,
-              "pairs_",
-              PairsDefaultEntryHolder.defaultEntry,
-              "LeadingUnderscore_",
-            };
-            java.lang.String info =
-                "\u0000!\u0002\u0000\u0001\"!\u0006\u0004\u0000\u0001\u0007\u0002\u0007\u0003\u0208" +
-                "\u0004\u0007\u0005\u023b\u0000\u0007\u021a\b2\t\u0007\n\u0007\u000b\u0007\f\u021a" +
-                "\r\u0208\u000e\u0000\u000f\u0007\u0010\u0002\u0011\u0208\u0012\u0001\u0013\u0004" +
-                "\u0014\u0208\u0015\u0208\u0016\u0007\u0017\u0208\u0018\u0002\u0019\u021a\u001a\u021a" +
-                "\u001b\u0007\u001c2\u001d2\u001e2\u001f2 2!\u0208\"7\u0001";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3> parser = PARSER;
-          if (parser == null) {
-            synchronized (evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:evil_names_proto3.EvilNamesProto3)
-    private static final evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3 DEFAULT_INSTANCE;
-    static {
-      EvilNamesProto3 defaultInstance = new EvilNamesProto3();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        EvilNamesProto3.class, defaultInstance);
-    }
-
-    public static evil_names_proto3.EvilNamesProto3OuterClass.EvilNamesProto3 getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<EvilNamesProto3> PARSER;
-
-    public static com.google.protobuf.Parser<EvilNamesProto3> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface HardKeywordsAllTypesOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:evil_names_proto3.HardKeywordsAllTypes)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>int32 as = 1;</code>
-     * @return Whether the as field is set.
-     */
-    boolean hasAs();
-    /**
-     * <code>int32 as = 1;</code>
-     * @return The as.
-     */
-    int getAs();
-
-    /**
-     * <code>string in = 2;</code>
-     * @return Whether the in field is set.
-     */
-    boolean hasIn();
-    /**
-     * <code>string in = 2;</code>
-     * @return The in.
-     */
-    java.lang.String getIn();
-    /**
-     * <code>string in = 2;</code>
-     * @return The bytes for in.
-     */
-    com.google.protobuf.ByteString
-        getInBytes();
-
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     * @return Whether the break field is set.
-     */
-    boolean hasBreak();
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     * @return The enum numeric value on the wire for break.
-     */
-    int getBreakValue();
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     * @return The break.
-     */
-    evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum getBreak();
-
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    int getContinueCount();
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    boolean containsContinue(
-        int key);
-    /**
-     * Use {@link #getContinueMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getContinue();
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getContinueMap();
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-
-    int getContinueOrDefault(
-        int key,
-        int defaultValue);
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-
-    int getContinueOrThrow(
-        int key);
-
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     * @return Whether the do field is set.
-     */
-    boolean hasDo();
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     * @return The do.
-     */
-    evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage getDo();
-
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @return A list containing the else.
-     */
-    java.util.List<java.lang.Integer> getElseList();
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @return The count of else.
-     */
-    int getElseCount();
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @param index The index of the element to return.
-     * @return The else at the given index.
-     */
-    int getElse(int index);
-
-    /**
-     * <code>repeated string for = 7;</code>
-     * @return A list containing the for.
-     */
-    java.util.List<java.lang.String>
-        getForList();
-    /**
-     * <code>repeated string for = 7;</code>
-     * @return The count of for.
-     */
-    int getForCount();
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param index The index of the element to return.
-     * @return The for at the given index.
-     */
-    java.lang.String getFor(int index);
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param index The index of the element to return.
-     * @return The for at the given index.
-     */
-    com.google.protobuf.ByteString
-        getForBytes(int index);
-
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @return A list containing the fun.
-     */
-    java.util.List<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum> getFunList();
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @return The count of fun.
-     */
-    int getFunCount();
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param index The index of the element to return.
-     * @return The fun at the given index.
-     */
-    evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum getFun(int index);
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @return A list containing the enum numeric values on the wire for fun.
-     */
-    java.util.List<java.lang.Integer>
-    getFunValueList();
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param index The index of the value to return.
-     * @return The enum numeric value on the wire of fun at the given index.
-     */
-    int getFunValue(int index);
-
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    java.util.List<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage> 
-        getIfList();
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage getIf(int index);
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    int getIfCount();
-  }
-  /**
-   * Protobuf type {@code evil_names_proto3.HardKeywordsAllTypes}
-   */
-  public  static final class HardKeywordsAllTypes extends
-      com.google.protobuf.GeneratedMessageLite<
-          HardKeywordsAllTypes, HardKeywordsAllTypes.Builder> implements
-      // @@protoc_insertion_point(message_implements:evil_names_proto3.HardKeywordsAllTypes)
-      HardKeywordsAllTypesOrBuilder {
-    private HardKeywordsAllTypes() {
-      in_ = "";
-      else_ = emptyIntList();
-      for_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      fun_ = emptyIntList();
-      if_ = emptyProtobufList();
-    }
-    /**
-     * Protobuf enum {@code evil_names_proto3.HardKeywordsAllTypes.NestedEnum}
-     */
-    public enum NestedEnum
-        implements com.google.protobuf.Internal.EnumLite {
-      /**
-       * <code>ZERO = 0;</code>
-       */
-      ZERO(0),
-      /**
-       * <code>FOO = 1;</code>
-       */
-      FOO(1),
-      /**
-       * <code>BAR = 2;</code>
-       */
-      BAR(2),
-      UNRECOGNIZED(-1),
-      ;
-
-      /**
-       * <code>ZERO = 0;</code>
-       */
-      public static final int ZERO_VALUE = 0;
-      /**
-       * <code>FOO = 1;</code>
-       */
-      public static final int FOO_VALUE = 1;
-      /**
-       * <code>BAR = 2;</code>
-       */
-      public static final int BAR_VALUE = 2;
-
-
-      @java.lang.Override
-      public final int getNumber() {
-        if (this == UNRECOGNIZED) {
-          throw new java.lang.IllegalArgumentException(
-              "Can't get the number of an unknown enum value.");
-        }
-        return value;
-      }
-
-      /**
-       * @param value The number of the enum to look for.
-       * @return The enum associated with the given number.
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static NestedEnum valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static NestedEnum forNumber(int value) {
-        switch (value) {
-          case 0: return ZERO;
-          case 1: return FOO;
-          case 2: return BAR;
-          default: return null;
-        }
-      }
-
-      public static com.google.protobuf.Internal.EnumLiteMap<NestedEnum>
-          internalGetValueMap() {
-        return internalValueMap;
-      }
-      private static final com.google.protobuf.Internal.EnumLiteMap<
-          NestedEnum> internalValueMap =
-            new com.google.protobuf.Internal.EnumLiteMap<NestedEnum>() {
-              @java.lang.Override
-              public NestedEnum findValueByNumber(int number) {
-                return NestedEnum.forNumber(number);
-              }
-            };
-
-      public static com.google.protobuf.Internal.EnumVerifier 
-          internalGetVerifier() {
-        return NestedEnumVerifier.INSTANCE;
-      }
-
-      private static final class NestedEnumVerifier implements 
-           com.google.protobuf.Internal.EnumVerifier { 
-              static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new NestedEnumVerifier();
-              @java.lang.Override
-              public boolean isInRange(int number) {
-                return NestedEnum.forNumber(number) != null;
-              }
-            };
-
-      private final int value;
-
-      private NestedEnum(int value) {
-        this.value = value;
-      }
-
-      // @@protoc_insertion_point(enum_scope:evil_names_proto3.HardKeywordsAllTypes.NestedEnum)
-    }
-
-    public interface NestedMessageOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:evil_names_proto3.HardKeywordsAllTypes.NestedMessage)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>int32 while = 1;</code>
-       * @return Whether the while field is set.
-       */
-      boolean hasWhile();
-      /**
-       * <code>int32 while = 1;</code>
-       * @return The while.
-       */
-      int getWhile();
-    }
-    /**
-     * Protobuf type {@code evil_names_proto3.HardKeywordsAllTypes.NestedMessage}
-     */
-    public  static final class NestedMessage extends
-        com.google.protobuf.GeneratedMessageLite<
-            NestedMessage, NestedMessage.Builder> implements
-        // @@protoc_insertion_point(message_implements:evil_names_proto3.HardKeywordsAllTypes.NestedMessage)
-        NestedMessageOrBuilder {
-      private NestedMessage() {
-      }
-      private int bitField0_;
-      public static final int WHILE_FIELD_NUMBER = 1;
-      private int while_;
-      /**
-       * <code>int32 while = 1;</code>
-       * @return Whether the while field is set.
-       */
-      @java.lang.Override
-      public boolean hasWhile() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>int32 while = 1;</code>
-       * @return The while.
-       */
-      @java.lang.Override
-      public int getWhile() {
-        return while_;
-      }
-      /**
-       * <code>int32 while = 1;</code>
-       * @param value The while to set.
-       */
-      private void setWhile(int value) {
-        bitField0_ |= 0x00000001;
-        while_ = value;
-      }
-      /**
-       * <code>int32 while = 1;</code>
-       */
-      private void clearWhile() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        while_ = 0;
-      }
-
-      public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code evil_names_proto3.HardKeywordsAllTypes.NestedMessage}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage, Builder> implements
-          // @@protoc_insertion_point(builder_implements:evil_names_proto3.HardKeywordsAllTypes.NestedMessage)
-          evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessageOrBuilder {
-        // Construct using evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>int32 while = 1;</code>
-         * @return Whether the while field is set.
-         */
-        @java.lang.Override
-        public boolean hasWhile() {
-          return instance.hasWhile();
-        }
-        /**
-         * <code>int32 while = 1;</code>
-         * @return The while.
-         */
-        @java.lang.Override
-        public int getWhile() {
-          return instance.getWhile();
-        }
-        /**
-         * <code>int32 while = 1;</code>
-         * @param value The while to set.
-         * @return This builder for chaining.
-         */
-        public Builder setWhile(int value) {
-          copyOnWrite();
-          instance.setWhile(value);
-          return this;
-        }
-        /**
-         * <code>int32 while = 1;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearWhile() {
-          copyOnWrite();
-          instance.clearWhile();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:evil_names_proto3.HardKeywordsAllTypes.NestedMessage)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "while_",
-              };
-              java.lang.String info =
-                  "\u0000\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1004\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage> parser = PARSER;
-            if (parser == null) {
-              synchronized (evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:evil_names_proto3.HardKeywordsAllTypes.NestedMessage)
-      private static final evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage DEFAULT_INSTANCE;
-      static {
-        NestedMessage defaultInstance = new NestedMessage();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          NestedMessage.class, defaultInstance);
-      }
-
-      public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<NestedMessage> PARSER;
-
-      public static com.google.protobuf.Parser<NestedMessage> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int bitField0_;
-    public static final int AS_FIELD_NUMBER = 1;
-    private int as_;
-    /**
-     * <code>int32 as = 1;</code>
-     * @return Whether the as field is set.
-     */
-    @java.lang.Override
-    public boolean hasAs() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>int32 as = 1;</code>
-     * @return The as.
-     */
-    @java.lang.Override
-    public int getAs() {
-      return as_;
-    }
-    /**
-     * <code>int32 as = 1;</code>
-     * @param value The as to set.
-     */
-    private void setAs(int value) {
-      bitField0_ |= 0x00000001;
-      as_ = value;
-    }
-    /**
-     * <code>int32 as = 1;</code>
-     */
-    private void clearAs() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      as_ = 0;
-    }
-
-    public static final int IN_FIELD_NUMBER = 2;
-    private java.lang.String in_;
-    /**
-     * <code>string in = 2;</code>
-     * @return Whether the in field is set.
-     */
-    @java.lang.Override
-    public boolean hasIn() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>string in = 2;</code>
-     * @return The in.
-     */
-    @java.lang.Override
-    public java.lang.String getIn() {
-      return in_;
-    }
-    /**
-     * <code>string in = 2;</code>
-     * @return The bytes for in.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getInBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(in_);
-    }
-    /**
-     * <code>string in = 2;</code>
-     * @param value The in to set.
-     */
-    private void setIn(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00000002;
-      in_ = value;
-    }
-    /**
-     * <code>string in = 2;</code>
-     */
-    private void clearIn() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      in_ = getDefaultInstance().getIn();
-    }
-    /**
-     * <code>string in = 2;</code>
-     * @param value The bytes for in to set.
-     */
-    private void setInBytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      in_ = value.toStringUtf8();
-      bitField0_ |= 0x00000002;
-    }
-
-    public static final int BREAK_FIELD_NUMBER = 3;
-    private int break_;
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     * @return Whether the break field is set.
-     */
-    @java.lang.Override
-    public boolean hasBreak() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     * @return The enum numeric value on the wire for break.
-     */
-    @java.lang.Override
-    public int getBreakValue() {
-      return break_;
-    }
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     * @return The break.
-     */
-    @java.lang.Override
-    public evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum getBreak() {
-      evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum result = evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum.forNumber(break_);
-      return result == null ? evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum.UNRECOGNIZED : result;
-    }
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     * @param value The enum numeric value on the wire for break to set.
-     */
-    private void setBreakValue(int value) {
-      bitField0_ |= 0x00000004;  break_ = value;
-    }
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     * @param value The break to set.
-     */
-    private void setBreak(evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum value) {
-      break_ = value.getNumber();
-      bitField0_ |= 0x00000004;
-    }
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     */
-    private void clearBreak() {
-      bitField0_ = (bitField0_ & ~0x00000004);
-      break_ = 0;
-    }
-
-    public static final int CONTINUE_FIELD_NUMBER = 4;
-    private static final class ContinueDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> continue_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetContinue() {
-      return continue_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableContinue() {
-      if (!continue_.isMutable()) {
-        continue_ = continue_.mutableCopy();
-      }
-      return continue_;
-    }
-    @java.lang.Override
-
-    public int getContinueCount() {
-      return internalGetContinue().size();
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsContinue(
-        int key) {
-      
-      return internalGetContinue().containsKey(key);
-    }
-    /**
-     * Use {@link #getContinueMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getContinue() {
-      return getContinueMap();
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getContinueMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetContinue());
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    @java.lang.Override
-
-    public int getContinueOrDefault(
-        int key,
-        int defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetContinue();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    @java.lang.Override
-
-    public int getContinueOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetContinue();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMutableContinueMap() {
-      return internalGetMutableContinue();
-    }
-
-    public static final int DO_FIELD_NUMBER = 5;
-    private evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage do_;
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     */
-    @java.lang.Override
-    public boolean hasDo() {
-      return ((bitField0_ & 0x00000008) != 0);
-    }
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     */
-    @java.lang.Override
-    public evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage getDo() {
-      return do_ == null ? evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage.getDefaultInstance() : do_;
-    }
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     */
-    private void setDo(evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-      value.getClass();
-  do_ = value;
-      bitField0_ |= 0x00000008;
-      }
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeDo(evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-      value.getClass();
-  if (do_ != null &&
-          do_ != evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage.getDefaultInstance()) {
-        do_ =
-          evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage.newBuilder(do_).mergeFrom(value).buildPartial();
-      } else {
-        do_ = value;
-      }
-      bitField0_ |= 0x00000008;
-    }
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     */
-    private void clearDo() {  do_ = null;
-      bitField0_ = (bitField0_ & ~0x00000008);
-    }
-
-    public static final int ELSE_FIELD_NUMBER = 6;
-    private com.google.protobuf.Internal.IntList else_;
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @return A list containing the else.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getElseList() {
-      return else_;
-    }
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @return The count of else.
-     */
-    @java.lang.Override
-    public int getElseCount() {
-      return else_.size();
-    }
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @param index The index of the element to return.
-     * @return The else at the given index.
-     */
-    @java.lang.Override
-    public int getElse(int index) {
-      return else_.getInt(index);
-    }
-    private int elseMemoizedSerializedSize = -1;
-    private void ensureElseIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = else_;
-      if (!tmp.isModifiable()) {
-        else_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @param index The index to set the value at.
-     * @param value The else to set.
-     */
-    private void setElse(
-        int index, int value) {
-      ensureElseIsMutable();
-      else_.setInt(index, value);
-    }
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @param value The else to add.
-     */
-    private void addElse(int value) {
-      ensureElseIsMutable();
-      else_.addInt(value);
-    }
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @param values The else to add.
-     */
-    private void addAllElse(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureElseIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, else_);
-    }
-    /**
-     * <code>repeated int32 else = 6;</code>
-     */
-    private void clearElse() {
-      else_ = emptyIntList();
-    }
-
-    public static final int FOR_FIELD_NUMBER = 7;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> for_;
-    /**
-     * <code>repeated string for = 7;</code>
-     * @return A list containing the for.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getForList() {
-      return for_;
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @return The count of for.
-     */
-    @java.lang.Override
-    public int getForCount() {
-      return for_.size();
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param index The index of the element to return.
-     * @return The for at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getFor(int index) {
-      return for_.get(index);
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the for at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getForBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          for_.get(index));
-    }
-    private void ensureForIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          for_;  if (!tmp.isModifiable()) {
-        for_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param index The index to set the value at.
-     * @param value The for to set.
-     */
-    private void setFor(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureForIsMutable();
-      for_.set(index, value);
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param value The for to add.
-     */
-    private void addFor(
-        java.lang.String value) {
-      value.getClass();
-  ensureForIsMutable();
-      for_.add(value);
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param values The for to add.
-     */
-    private void addAllFor(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureForIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, for_);
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     */
-    private void clearFor() {
-      for_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param value The bytes of the for to add.
-     */
-    private void addForBytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      ensureForIsMutable();
-      for_.add(value.toStringUtf8());
-    }
-
-    public static final int FUN_FIELD_NUMBER = 8;
-    private com.google.protobuf.Internal.IntList fun_;
-    private static final com.google.protobuf.Internal.ListAdapter.Converter<
-        java.lang.Integer, evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum> fun_converter_ =
-            new com.google.protobuf.Internal.ListAdapter.Converter<
-                java.lang.Integer, evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum>() {
-              @java.lang.Override
-              public evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum convert(java.lang.Integer from) {
-                evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum result = evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum.forNumber(from);
-                return result == null ? evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum.UNRECOGNIZED : result;
-              }
-            };
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @return A list containing the fun.
-     */
-    @java.lang.Override
-    public java.util.List<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum> getFunList() {
-      return new com.google.protobuf.Internal.ListAdapter<
-          java.lang.Integer, evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum>(fun_, fun_converter_);
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @return The count of fun.
-     */
-    @java.lang.Override
-    public int getFunCount() {
-      return fun_.size();
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param index The index of the element to return.
-     * @return The fun at the given index.
-     */
-    @java.lang.Override
-    public evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum getFun(int index) {
-      return fun_converter_.convert(fun_.getInt(index));
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @return A list containing the enum numeric values on the wire for fun.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-    getFunValueList() {
-      return fun_;
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param index The index of the value to return.
-     * @return The enum numeric value on the wire of fun at the given index.
-     */
-    @java.lang.Override
-    public int getFunValue(int index) {
-      return fun_.getInt(index);
-    }
-    private int funMemoizedSerializedSize;
-    private void ensureFunIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = fun_;
-      if (!tmp.isModifiable()) {
-        fun_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-      }
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param index The index to set the value at.
-     * @param value The fun to set.
-     */
-    private void setFun(
-        int index, evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum value) {
-      value.getClass();
-  ensureFunIsMutable();
-      fun_.setInt(index, value.getNumber());
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param value The fun to add.
-     */
-    private void addFun(evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum value) {
-      value.getClass();
-  ensureFunIsMutable();
-      fun_.addInt(value.getNumber());
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param values The fun to add.
-     */
-    private void addAllFun(
-        java.lang.Iterable<? extends evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum> values) {
-      ensureFunIsMutable();
-      for (evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum value : values) {
-        fun_.addInt(value.getNumber());
-      }
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     */
-    private void clearFun() {
-      fun_ = emptyIntList();
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param value The enum numeric value on the wire for fun to set.
-     */
-    private void setFunValue(
-        int index, int value) {
-      ensureFunIsMutable();
-      fun_.setInt(index, value);
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param value The enum numeric value on the wire for fun to add.
-     */
-    private void addFunValue(int value) {
-      ensureFunIsMutable();
-      fun_.addInt(value);
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param values The enum numeric values on the wire for fun to add.
-     */
-    private void addAllFunValue(
-        java.lang.Iterable<java.lang.Integer> values) {
-      ensureFunIsMutable();
-      for (int value : values) {
-        fun_.addInt(value);
-      }
-    }
-
-    public static final int IF_FIELD_NUMBER = 9;
-    private com.google.protobuf.Internal.ProtobufList<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage> if_;
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    @java.lang.Override
-    public java.util.List<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage> getIfList() {
-      return if_;
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    public java.util.List<? extends evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessageOrBuilder> 
-        getIfOrBuilderList() {
-      return if_;
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    @java.lang.Override
-    public int getIfCount() {
-      return if_.size();
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    @java.lang.Override
-    public evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage getIf(int index) {
-      return if_.get(index);
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    public evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessageOrBuilder getIfOrBuilder(
-        int index) {
-      return if_.get(index);
-    }
-    private void ensureIfIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage> tmp = if_;
-      if (!tmp.isModifiable()) {
-        if_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    private void setIf(
-        int index, evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-      value.getClass();
-  ensureIfIsMutable();
-      if_.set(index, value);
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    private void addIf(evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-      value.getClass();
-  ensureIfIsMutable();
-      if_.add(value);
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    private void addIf(
-        int index, evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-      value.getClass();
-  ensureIfIsMutable();
-      if_.add(index, value);
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    private void addAllIf(
-        java.lang.Iterable<? extends evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage> values) {
-      ensureIfIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, if_);
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    private void clearIf() {
-      if_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    private void removeIf(int index) {
-      ensureIfIsMutable();
-      if_.remove(index);
-    }
-
-    public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code evil_names_proto3.HardKeywordsAllTypes}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes, Builder> implements
-        // @@protoc_insertion_point(builder_implements:evil_names_proto3.HardKeywordsAllTypes)
-        evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypesOrBuilder {
-      // Construct using evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>int32 as = 1;</code>
-       * @return Whether the as field is set.
-       */
-      @java.lang.Override
-      public boolean hasAs() {
-        return instance.hasAs();
-      }
-      /**
-       * <code>int32 as = 1;</code>
-       * @return The as.
-       */
-      @java.lang.Override
-      public int getAs() {
-        return instance.getAs();
-      }
-      /**
-       * <code>int32 as = 1;</code>
-       * @param value The as to set.
-       * @return This builder for chaining.
-       */
-      public Builder setAs(int value) {
-        copyOnWrite();
-        instance.setAs(value);
-        return this;
-      }
-      /**
-       * <code>int32 as = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearAs() {
-        copyOnWrite();
-        instance.clearAs();
-        return this;
-      }
-
-      /**
-       * <code>string in = 2;</code>
-       * @return Whether the in field is set.
-       */
-      @java.lang.Override
-      public boolean hasIn() {
-        return instance.hasIn();
-      }
-      /**
-       * <code>string in = 2;</code>
-       * @return The in.
-       */
-      @java.lang.Override
-      public java.lang.String getIn() {
-        return instance.getIn();
-      }
-      /**
-       * <code>string in = 2;</code>
-       * @return The bytes for in.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getInBytes() {
-        return instance.getInBytes();
-      }
-      /**
-       * <code>string in = 2;</code>
-       * @param value The in to set.
-       * @return This builder for chaining.
-       */
-      public Builder setIn(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setIn(value);
-        return this;
-      }
-      /**
-       * <code>string in = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearIn() {
-        copyOnWrite();
-        instance.clearIn();
-        return this;
-      }
-      /**
-       * <code>string in = 2;</code>
-       * @param value The bytes for in to set.
-       * @return This builder for chaining.
-       */
-      public Builder setInBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setInBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-       * @return Whether the break field is set.
-       */
-      @java.lang.Override
-      public boolean hasBreak() {
-        return instance.hasBreak();
-      }
-      /**
-       * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-       * @return The enum numeric value on the wire for break.
-       */
-      @java.lang.Override
-      public int getBreakValue() {
-        return instance.getBreakValue();
-      }
-      /**
-       * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-       * @param value The break to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBreakValue(int value) {
-        copyOnWrite();
-        instance.setBreakValue(value);
-        return this;
-      }
-      /**
-       * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-       * @return The break.
-       */
-      @java.lang.Override
-      public evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum getBreak() {
-        return instance.getBreak();
-      }
-      /**
-       * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-       * @param value The enum numeric value on the wire for break to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBreak(evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum value) {
-        copyOnWrite();
-        instance.setBreak(value);
-        return this;
-      }
-      /**
-       * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearBreak() {
-        copyOnWrite();
-        instance.clearBreak();
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getContinueCount() {
-        return instance.getContinueMap().size();
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; continue = 4;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsContinue(
-          int key) {
-        
-        return instance.getContinueMap().containsKey(key);
-      }
-
-      public Builder clearContinue() {
-        copyOnWrite();
-        instance.getMutableContinueMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; continue = 4;</code>
-       */
-
-      public Builder removeContinue(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableContinueMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getContinueMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getContinue() {
-        return getContinueMap();
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; continue = 4;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getContinueMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getContinueMap());
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; continue = 4;</code>
-       */
-      @java.lang.Override
-
-      public int getContinueOrDefault(
-          int key,
-          int defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getContinueMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; continue = 4;</code>
-       */
-      @java.lang.Override
-
-      public int getContinueOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getContinueMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; continue = 4;</code>
-       */
-      public Builder putContinue(
-          int key,
-          int value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableContinueMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; continue = 4;</code>
-       */
-      public Builder putAllContinue(
-          java.util.Map<java.lang.Integer, java.lang.Integer> values) {
-        copyOnWrite();
-        instance.getMutableContinueMap().putAll(values);
-        return this;
-      }
-
-      /**
-       * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-       */
-      @java.lang.Override
-      public boolean hasDo() {
-        return instance.hasDo();
-      }
-      /**
-       * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-       */
-      @java.lang.Override
-      public evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage getDo() {
-        return instance.getDo();
-      }
-      /**
-       * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-       */
-      public Builder setDo(evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.setDo(value);
-        return this;
-        }
-      /**
-       * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-       */
-      public Builder setDo(
-          evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setDo(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-       */
-      public Builder mergeDo(evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.mergeDo(value);
-        return this;
-      }
-      /**
-       * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-       */
-      public Builder clearDo() {  copyOnWrite();
-        instance.clearDo();
-        return this;
-      }
-
-      /**
-       * <code>repeated int32 else = 6;</code>
-       * @return A list containing the else.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getElseList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getElseList());
-      }
-      /**
-       * <code>repeated int32 else = 6;</code>
-       * @return The count of else.
-       */
-      @java.lang.Override
-      public int getElseCount() {
-        return instance.getElseCount();
-      }
-      /**
-       * <code>repeated int32 else = 6;</code>
-       * @param index The index of the element to return.
-       * @return The else at the given index.
-       */
-      @java.lang.Override
-      public int getElse(int index) {
-        return instance.getElse(index);
-      }
-      /**
-       * <code>repeated int32 else = 6;</code>
-       * @param value The else to set.
-       * @return This builder for chaining.
-       */
-      public Builder setElse(
-          int index, int value) {
-        copyOnWrite();
-        instance.setElse(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 else = 6;</code>
-       * @param value The else to add.
-       * @return This builder for chaining.
-       */
-      public Builder addElse(int value) {
-        copyOnWrite();
-        instance.addElse(value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 else = 6;</code>
-       * @param values The else to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllElse(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllElse(values);
-        return this;
-      }
-      /**
-       * <code>repeated int32 else = 6;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearElse() {
-        copyOnWrite();
-        instance.clearElse();
-        return this;
-      }
-
-      /**
-       * <code>repeated string for = 7;</code>
-       * @return A list containing the for.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getForList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getForList());
-      }
-      /**
-       * <code>repeated string for = 7;</code>
-       * @return The count of for.
-       */
-      @java.lang.Override
-      public int getForCount() {
-        return instance.getForCount();
-      }
-      /**
-       * <code>repeated string for = 7;</code>
-       * @param index The index of the element to return.
-       * @return The for at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getFor(int index) {
-        return instance.getFor(index);
-      }
-      /**
-       * <code>repeated string for = 7;</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the for at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getForBytes(int index) {
-        return instance.getForBytes(index);
-      }
-      /**
-       * <code>repeated string for = 7;</code>
-       * @param index The index to set the value at.
-       * @param value The for to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFor(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setFor(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string for = 7;</code>
-       * @param value The for to add.
-       * @return This builder for chaining.
-       */
-      public Builder addFor(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addFor(value);
-        return this;
-      }
-      /**
-       * <code>repeated string for = 7;</code>
-       * @param values The for to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllFor(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllFor(values);
-        return this;
-      }
-      /**
-       * <code>repeated string for = 7;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFor() {
-        copyOnWrite();
-        instance.clearFor();
-        return this;
-      }
-      /**
-       * <code>repeated string for = 7;</code>
-       * @param value The bytes of the for to add.
-       * @return This builder for chaining.
-       */
-      public Builder addForBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addForBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-       * @return A list containing the fun.
-       */
-      @java.lang.Override
-      public java.util.List<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum> getFunList() {
-        return instance.getFunList();
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-       * @return The count of fun.
-       */
-      @java.lang.Override
-      public int getFunCount() {
-        return instance.getFunCount();
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-       * @param index The index of the element to return.
-       * @return The fun at the given index.
-       */
-      @java.lang.Override
-      public evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum getFun(int index) {
-        return instance.getFun(index);
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-       * @param index The index to set the value at.
-       * @param value The fun to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFun(
-          int index, evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum value) {
-        copyOnWrite();
-        instance.setFun(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-       * @param value The fun to add.
-       * @return This builder for chaining.
-       */
-      public Builder addFun(evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum value) {
-        copyOnWrite();
-        instance.addFun(value);
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-       * @param values The fun to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllFun(
-          java.lang.Iterable<? extends evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum> values) {
-        copyOnWrite();
-        instance.addAllFun(values);  return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFun() {
-        copyOnWrite();
-        instance.clearFun();
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-       * @return A list containing the enum numeric values on the wire for fun.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-      getFunValueList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getFunValueList());
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-       * @param index The index of the value to return.
-       * @return The enum numeric value on the wire of fun at the given index.
-       */
-      @java.lang.Override
-      public int getFunValue(int index) {
-        return instance.getFunValue(index);
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-       * @param index The index to set the value at.
-       * @param value The enum numeric value on the wire for fun to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFunValue(
-          int index, int value) {
-        copyOnWrite();
-        instance.setFunValue(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-       * @param value The enum numeric value on the wire for fun to add.
-       * @return This builder for chaining.
-       */
-      public Builder addFunValue(int value) {
-        instance.addFunValue(value);
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-       * @param values The enum numeric values on the wire for fun to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllFunValue(
-          java.lang.Iterable<java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllFunValue(values);
-        return this;
-      }
-
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      @java.lang.Override
-      public java.util.List<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage> getIfList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getIfList());
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      @java.lang.Override
-      public int getIfCount() {
-        return instance.getIfCount();
-      }/**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      @java.lang.Override
-      public evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage getIf(int index) {
-        return instance.getIf(index);
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      public Builder setIf(
-          int index, evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.setIf(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      public Builder setIf(
-          int index, evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setIf(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      public Builder addIf(evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.addIf(value);
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      public Builder addIf(
-          int index, evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.addIf(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      public Builder addIf(
-          evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addIf(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      public Builder addIf(
-          int index, evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addIf(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      public Builder addAllIf(
-          java.lang.Iterable<? extends evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage> values) {
-        copyOnWrite();
-        instance.addAllIf(values);
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      public Builder clearIf() {
-        copyOnWrite();
-        instance.clearIf();
-        return this;
-      }
-      /**
-       * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-       */
-      public Builder removeIf(int index) {
-        copyOnWrite();
-        instance.removeIf(index);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:evil_names_proto3.HardKeywordsAllTypes)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "as_",
-              "in_",
-              "break_",
-              "continue_",
-              ContinueDefaultEntryHolder.defaultEntry,
-              "do_",
-              "else_",
-              "for_",
-              "fun_",
-              "if_",
-              evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage.class,
-            };
-            java.lang.String info =
-                "\u0000\t\u0000\u0001\u0001\t\t\u0001\u0004\u0000\u0001\u1004\u0000\u0002\u1208\u0001" +
-                "\u0003\u100c\u0002\u00042\u0005\u1009\u0003\u0006\'\u0007\u021a\b,\t\u001b";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes> parser = PARSER;
-          if (parser == null) {
-            synchronized (evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:evil_names_proto3.HardKeywordsAllTypes)
-    private static final evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes DEFAULT_INSTANCE;
-    static {
-      HardKeywordsAllTypes defaultInstance = new HardKeywordsAllTypes();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        HardKeywordsAllTypes.class, defaultInstance);
-    }
-
-    public static evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<HardKeywordsAllTypes> PARSER;
-
-    public static com.google.protobuf.Parser<HardKeywordsAllTypes> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface ClassOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:evil_names_proto3.Class)
-      com.google.protobuf.MessageLiteOrBuilder {
-  }
-  /**
-   * Protobuf type {@code evil_names_proto3.Class}
-   */
-  public  static final class Class extends
-      com.google.protobuf.GeneratedMessageLite<
-          Class, Class.Builder> implements
-      // @@protoc_insertion_point(message_implements:evil_names_proto3.Class)
-      ClassOrBuilder {
-    private Class() {
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.Class parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.Class parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.Class parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.Class parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.Class parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.Class parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.Class parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.Class parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.Class parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.Class parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.Class parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static evil_names_proto3.EvilNamesProto3OuterClass.Class parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(evil_names_proto3.EvilNamesProto3OuterClass.Class prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code evil_names_proto3.Class}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          evil_names_proto3.EvilNamesProto3OuterClass.Class, Builder> implements
-        // @@protoc_insertion_point(builder_implements:evil_names_proto3.Class)
-        evil_names_proto3.EvilNamesProto3OuterClass.ClassOrBuilder {
-      // Construct using evil_names_proto3.EvilNamesProto3OuterClass.Class.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:evil_names_proto3.Class)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new evil_names_proto3.EvilNamesProto3OuterClass.Class();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0000\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<evil_names_proto3.EvilNamesProto3OuterClass.Class> parser = PARSER;
-          if (parser == null) {
-            synchronized (evil_names_proto3.EvilNamesProto3OuterClass.Class.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<evil_names_proto3.EvilNamesProto3OuterClass.Class>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:evil_names_proto3.Class)
-    private static final evil_names_proto3.EvilNamesProto3OuterClass.Class DEFAULT_INSTANCE;
-    static {
-      Class defaultInstance = new Class();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        Class.class, defaultInstance);
-    }
-
-    public static evil_names_proto3.EvilNamesProto3OuterClass.Class getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<Class> PARSER;
-
-    public static com.google.protobuf.Parser<Class> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/evil_names_proto3/EvilNamesProto3OuterClassKt.kt b/java/kotlin-lite/target/generated-test-sources/evil_names_proto3/EvilNamesProto3OuterClassKt.kt
deleted file mode 100644
index e69de29..0000000
--- a/java/kotlin-lite/target/generated-test-sources/evil_names_proto3/EvilNamesProto3OuterClassKt.kt
+++ /dev/null
diff --git a/java/kotlin-lite/target/generated-test-sources/evil_names_proto3/HardKeywordsAllTypesKt.kt b/java/kotlin-lite/target/generated-test-sources/evil_names_proto3/HardKeywordsAllTypesKt.kt
deleted file mode 100644
index e0a2239..0000000
--- a/java/kotlin-lite/target/generated-test-sources/evil_names_proto3/HardKeywordsAllTypesKt.kt
+++ /dev/null
@@ -1,486 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: com/google/protobuf/evil_names_proto3.proto
-
-package evil_names_proto3;
-
-@kotlin.jvm.JvmSynthetic
-inline fun hardKeywordsAllTypes(block: evil_names_proto3.HardKeywordsAllTypesKt.Dsl.() -> Unit): evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes =
-  evil_names_proto3.HardKeywordsAllTypesKt.Dsl._create(evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.newBuilder()).apply { block() }._build()
-object HardKeywordsAllTypesKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes = _builder.build()
-
-    /**
-     * <code>int32 as = 1;</code>
-     */
-    var as_: kotlin.Int
-      @JvmName("getAs_")
-      get() = _builder.getAs()
-      @JvmName("setAs_")
-      set(value) {
-        _builder.setAs(value)
-      }
-    /**
-     * <code>int32 as = 1;</code>
-     */
-    fun clearAs_() {
-      _builder.clearAs()
-    }
-    /**
-     * <code>int32 as = 1;</code>
-     * @return Whether the as field is set.
-     */
-    fun hasAs_(): kotlin.Boolean {
-      return _builder.hasAs()
-    }
-
-    /**
-     * <code>string in = 2;</code>
-     */
-    var in_: kotlin.String
-      @JvmName("getIn_")
-      get() = _builder.getIn()
-      @JvmName("setIn_")
-      set(value) {
-        _builder.setIn(value)
-      }
-    /**
-     * <code>string in = 2;</code>
-     */
-    fun clearIn_() {
-      _builder.clearIn()
-    }
-    /**
-     * <code>string in = 2;</code>
-     * @return Whether the in field is set.
-     */
-    fun hasIn_(): kotlin.Boolean {
-      return _builder.hasIn()
-    }
-
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     */
-    var break_: evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum
-      @JvmName("getBreak_")
-      get() = _builder.getBreak()
-      @JvmName("setBreak_")
-      set(value) {
-        _builder.setBreak(value)
-      }
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     */
-    fun clearBreak_() {
-      _builder.clearBreak()
-    }
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedEnum break = 3;</code>
-     * @return Whether the break field is set.
-     */
-    fun hasBreak_(): kotlin.Boolean {
-      return _builder.hasBreak()
-    }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class Continue_Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-     val continue_: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, Continue_Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getContinue_Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getContinueMap()
-      )
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    @JvmName("putContinue_")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, Continue_Proxy>
-      .put(key: kotlin.Int, value: kotlin.Int) {
-         _builder.putContinue(key, value)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setContinue_")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, Continue_Proxy>
-      .set(key: kotlin.Int, value: kotlin.Int) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeContinue_")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, Continue_Proxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeContinue(key)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllContinue_")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, Continue_Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Int>) {
-         _builder.putAllContinue(map)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; continue = 4;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearContinue_")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, Continue_Proxy>
-      .clear() {
-         _builder.clearContinue()
-       }
-
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     */
-    var do_: evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage
-      @JvmName("getDo_")
-      get() = _builder.getDo()
-      @JvmName("setDo_")
-      set(value) {
-        _builder.setDo(value)
-      }
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     */
-    fun clearDo_() {
-      _builder.clearDo()
-    }
-    /**
-     * <code>.evil_names_proto3.HardKeywordsAllTypes.NestedMessage do = 5;</code>
-     * @return Whether the do field is set.
-     */
-    fun hasDo_(): kotlin.Boolean {
-      return _builder.hasDo()
-    }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class Else_Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated int32 else = 6;</code>
-     */
-     val else_: com.google.protobuf.kotlin.DslList<kotlin.Int, Else_Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getElseList()
-      )
-    /**
-     * <code>repeated int32 else = 6;</code>
-     * @param value The else to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addElse_")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, Else_Proxy>.add(value: kotlin.Int) {
-      _builder.addElse(value)
-    }/**
-     * <code>repeated int32 else = 6;</code>
-     * @param value The else to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignElse_")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, Else_Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated int32 else = 6;</code>
-     * @param values The else to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllElse_")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, Else_Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllElse(values)
-    }/**
-     * <code>repeated int32 else = 6;</code>
-     * @param values The else to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllElse_")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, Else_Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated int32 else = 6;</code>
-     * @param index The index to set the value at.
-     * @param value The else to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setElse_")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, Else_Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setElse(index, value)
-    }/**
-     * <code>repeated int32 else = 6;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearElse_")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, Else_Proxy>.clear() {
-      _builder.clearElse()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class For_Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated string for = 7;</code>
-     * @return A list containing the for.
-     */
-    val for_: com.google.protobuf.kotlin.DslList<kotlin.String, For_Proxy>
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getForList()
-      )
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param value The for to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addFor_")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, For_Proxy>.add(value: kotlin.String) {
-      _builder.addFor(value)
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param value The for to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignFor_")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, For_Proxy>.plusAssign(value: kotlin.String) {
-      add(value)
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param values The for to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllFor_")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, For_Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.String>) {
-      _builder.addAllFor(values)
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param values The for to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllFor_")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, For_Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.String>) {
-      addAll(values)
-    }
-    /**
-     * <code>repeated string for = 7;</code>
-     * @param index The index to set the value at.
-     * @param value The for to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setFor_")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.String, For_Proxy>.set(index: kotlin.Int, value: kotlin.String) {
-      _builder.setFor(index, value)
-    }/**
-     * <code>repeated string for = 7;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearFor_")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, For_Proxy>.clear() {
-      _builder.clearFor()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class Fun_Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     */
-     val fun_: com.google.protobuf.kotlin.DslList<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum, Fun_Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getFunList()
-      )
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param value The fun to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addFun_")
-    fun com.google.protobuf.kotlin.DslList<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum, Fun_Proxy>.add(value: evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum) {
-      _builder.addFun(value)
-    }/**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param value The fun to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignFun_")
-    inline operator fun com.google.protobuf.kotlin.DslList<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum, Fun_Proxy>.plusAssign(value: evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum) {
-      add(value)
-    }/**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param values The fun to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllFun_")
-    fun com.google.protobuf.kotlin.DslList<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum, Fun_Proxy>.addAll(values: kotlin.collections.Iterable<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum>) {
-      _builder.addAllFun(values)
-    }/**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param values The fun to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllFun_")
-    inline operator fun com.google.protobuf.kotlin.DslList<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum, Fun_Proxy>.plusAssign(values: kotlin.collections.Iterable<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum>) {
-      addAll(values)
-    }/**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     * @param index The index to set the value at.
-     * @param value The fun to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setFun_")
-    operator fun com.google.protobuf.kotlin.DslList<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum, Fun_Proxy>.set(index: kotlin.Int, value: evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum) {
-      _builder.setFun(index, value)
-    }/**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedEnum fun = 8;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearFun_")
-    fun com.google.protobuf.kotlin.DslList<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedEnum, Fun_Proxy>.clear() {
-      _builder.clearFun()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class If_Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-     val if_: com.google.protobuf.kotlin.DslList<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage, If_Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getIfList()
-      )
-    /**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     * @param value The if to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addIf_")
-    fun com.google.protobuf.kotlin.DslList<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage, If_Proxy>.add(value: evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage) {
-      _builder.addIf(value)
-    }/**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     * @param value The if to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignIf_")
-    inline operator fun com.google.protobuf.kotlin.DslList<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage, If_Proxy>.plusAssign(value: evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage) {
-      add(value)
-    }/**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     * @param values The if to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllIf_")
-    fun com.google.protobuf.kotlin.DslList<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage, If_Proxy>.addAll(values: kotlin.collections.Iterable<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage>) {
-      _builder.addAllIf(values)
-    }/**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     * @param values The if to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllIf_")
-    inline operator fun com.google.protobuf.kotlin.DslList<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage, If_Proxy>.plusAssign(values: kotlin.collections.Iterable<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage>) {
-      addAll(values)
-    }/**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     * @param index The index to set the value at.
-     * @param value The if to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setIf_")
-    operator fun com.google.protobuf.kotlin.DslList<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage, If_Proxy>.set(index: kotlin.Int, value: evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage) {
-      _builder.setIf(index, value)
-    }/**
-     * <code>repeated .evil_names_proto3.HardKeywordsAllTypes.NestedMessage if = 9;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearIf_")
-    fun com.google.protobuf.kotlin.DslList<evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage, If_Proxy>.clear() {
-      _builder.clearIf()
-    }}
-  @kotlin.jvm.JvmSynthetic
-  inline fun nestedMessage(block: evil_names_proto3.HardKeywordsAllTypesKt.NestedMessageKt.Dsl.() -> Unit): evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage =
-    evil_names_proto3.HardKeywordsAllTypesKt.NestedMessageKt.Dsl._create(evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage.newBuilder()).apply { block() }._build()
-  object NestedMessageKt {
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    @com.google.protobuf.kotlin.ProtoDslMarker
-    class Dsl private constructor(
-      @kotlin.jvm.JvmField private val _builder: evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage.Builder
-    ) {
-      companion object {
-        @kotlin.jvm.JvmSynthetic
-        @kotlin.PublishedApi
-        internal fun _create(builder: evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage.Builder): Dsl = Dsl(builder)
-      }
-
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _build(): evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage = _builder.build()
-
-      /**
-       * <code>int32 while = 1;</code>
-       */
-      var while_: kotlin.Int
-        @JvmName("getWhile_")
-        get() = _builder.getWhile()
-        @JvmName("setWhile_")
-        set(value) {
-          _builder.setWhile(value)
-        }
-      /**
-       * <code>int32 while = 1;</code>
-       */
-      fun clearWhile_() {
-        _builder.clearWhile()
-      }
-      /**
-       * <code>int32 while = 1;</code>
-       * @return Whether the while field is set.
-       */
-      fun hasWhile_(): kotlin.Boolean {
-        return _builder.hasWhile()
-      }
-    }
-  }
-}
-inline fun evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.copy(block: evil_names_proto3.HardKeywordsAllTypesKt.Dsl.() -> Unit): evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes =
-  evil_names_proto3.HardKeywordsAllTypesKt.Dsl._create(this.toBuilder()).apply { block() }._build()
-inline fun evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage.copy(block: evil_names_proto3.HardKeywordsAllTypesKt.NestedMessageKt.Dsl.() -> Unit): evil_names_proto3.EvilNamesProto3OuterClass.HardKeywordsAllTypes.NestedMessage =
-  evil_names_proto3.HardKeywordsAllTypesKt.NestedMessageKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/example_extensible_message/ExampleExtensibleMessage.java b/java/kotlin-lite/target/generated-test-sources/example_extensible_message/ExampleExtensibleMessage.java
deleted file mode 100644
index 8ee15cc..0000000
--- a/java/kotlin-lite/target/generated-test-sources/example_extensible_message/ExampleExtensibleMessage.java
+++ /dev/null
@@ -1,183 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: com/google/protobuf/example_extensible_message.proto
-
-package example_extensible_message;
-
-/**
- * Protobuf type {@code example_extensible_message.ExampleExtensibleMessage}
- */
-public  final class ExampleExtensibleMessage extends
-    com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
-      ExampleExtensibleMessage, ExampleExtensibleMessage.Builder> implements
-    // @@protoc_insertion_point(message_implements:example_extensible_message.ExampleExtensibleMessage)
-    ExampleExtensibleMessageOrBuilder {
-  private ExampleExtensibleMessage() {
-  }
-  public static example_extensible_message.ExampleExtensibleMessage parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static example_extensible_message.ExampleExtensibleMessage parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static example_extensible_message.ExampleExtensibleMessage parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static example_extensible_message.ExampleExtensibleMessage parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static example_extensible_message.ExampleExtensibleMessage parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static example_extensible_message.ExampleExtensibleMessage parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static example_extensible_message.ExampleExtensibleMessage parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static example_extensible_message.ExampleExtensibleMessage parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static example_extensible_message.ExampleExtensibleMessage parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static example_extensible_message.ExampleExtensibleMessage parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static example_extensible_message.ExampleExtensibleMessage parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static example_extensible_message.ExampleExtensibleMessage parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(example_extensible_message.ExampleExtensibleMessage prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * Protobuf type {@code example_extensible_message.ExampleExtensibleMessage}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
-        example_extensible_message.ExampleExtensibleMessage, Builder> implements
-      // @@protoc_insertion_point(builder_implements:example_extensible_message.ExampleExtensibleMessage)
-      example_extensible_message.ExampleExtensibleMessageOrBuilder {
-    // Construct using example_extensible_message.ExampleExtensibleMessage.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    // @@protoc_insertion_point(builder_scope:example_extensible_message.ExampleExtensibleMessage)
-  }
-  private byte memoizedIsInitialized = 2;
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new example_extensible_message.ExampleExtensibleMessage();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = null;java.lang.String info =
-              "\u0001\u0000";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<example_extensible_message.ExampleExtensibleMessage> parser = PARSER;
-        if (parser == null) {
-          synchronized (example_extensible_message.ExampleExtensibleMessage.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<example_extensible_message.ExampleExtensibleMessage>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return memoizedIsInitialized;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:example_extensible_message.ExampleExtensibleMessage)
-  private static final example_extensible_message.ExampleExtensibleMessage DEFAULT_INSTANCE;
-  static {
-    ExampleExtensibleMessage defaultInstance = new ExampleExtensibleMessage();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      ExampleExtensibleMessage.class, defaultInstance);
-  }
-
-  public static example_extensible_message.ExampleExtensibleMessage getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<ExampleExtensibleMessage> PARSER;
-
-  public static com.google.protobuf.Parser<ExampleExtensibleMessage> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-test-sources/example_extensible_message/ExampleExtensibleMessageKt.kt b/java/kotlin-lite/target/generated-test-sources/example_extensible_message/ExampleExtensibleMessageKt.kt
deleted file mode 100644
index 6f40977..0000000
--- a/java/kotlin-lite/target/generated-test-sources/example_extensible_message/ExampleExtensibleMessageKt.kt
+++ /dev/null
@@ -1,118 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: com/google/protobuf/example_extensible_message.proto
-
-package example_extensible_message;
-
-@kotlin.jvm.JvmSynthetic
-inline fun exampleExtensibleMessage(block: example_extensible_message.ExampleExtensibleMessageKt.Dsl.() -> Unit): example_extensible_message.ExampleExtensibleMessage =
-  example_extensible_message.ExampleExtensibleMessageKt.Dsl._create(example_extensible_message.ExampleExtensibleMessage.newBuilder()).apply { block() }._build()
-object ExampleExtensibleMessageKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: example_extensible_message.ExampleExtensibleMessage.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: example_extensible_message.ExampleExtensibleMessage.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): example_extensible_message.ExampleExtensibleMessage = _builder.build()
-    @Suppress("UNCHECKED_CAST")
-    @kotlin.jvm.JvmSynthetic
-    operator fun <T> get(extension: com.google.protobuf.ExtensionLite<example_extensible_message.ExampleExtensibleMessage, T>): T {
-      return if (extension.isRepeated) {
-        get(extension as com.google.protobuf.ExtensionLite<example_extensible_message.ExampleExtensibleMessage, List<*>>) as T
-      } else {
-        _builder.getExtension(extension)
-      }
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    @kotlin.jvm.JvmName("-getRepeatedExtension")
-    operator fun <E> get(
-      extension: com.google.protobuf.ExtensionLite<example_extensible_message.ExampleExtensibleMessage, List<E>>
-    ): com.google.protobuf.kotlin.ExtensionList<E, example_extensible_message.ExampleExtensibleMessage> {
-      return com.google.protobuf.kotlin.ExtensionList(extension, _builder.getExtension(extension))
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    operator fun contains(extension: com.google.protobuf.ExtensionLite<example_extensible_message.ExampleExtensibleMessage, *>): Boolean {
-      return _builder.hasExtension(extension)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun clear(extension: com.google.protobuf.ExtensionLite<example_extensible_message.ExampleExtensibleMessage, *>) {
-      _builder.clearExtension(extension)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun <T> setExtension(extension: com.google.protobuf.ExtensionLite<example_extensible_message.ExampleExtensibleMessage, T>, value: T) {
-      _builder.setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <T : Comparable<T>> set(
-      extension: com.google.protobuf.ExtensionLite<example_extensible_message.ExampleExtensibleMessage, T>,
-      value: T
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun set(
-      extension: com.google.protobuf.ExtensionLite<example_extensible_message.ExampleExtensibleMessage, com.google.protobuf.ByteString>,
-      value: com.google.protobuf.ByteString
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <T : com.google.protobuf.MessageLite> set(
-      extension: com.google.protobuf.ExtensionLite<example_extensible_message.ExampleExtensibleMessage, T>,
-      value: T
-    ) {
-      setExtension(extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun <E> com.google.protobuf.kotlin.ExtensionList<E, example_extensible_message.ExampleExtensibleMessage>.add(value: E) {
-      _builder.addExtension(this.extension, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, example_extensible_message.ExampleExtensibleMessage>.plusAssign(value: E) {
-      add(value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    fun <E> com.google.protobuf.kotlin.ExtensionList<E, example_extensible_message.ExampleExtensibleMessage>.addAll(values: Iterable<E>) {
-      for (value in values) {
-        add(value)
-      }
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, example_extensible_message.ExampleExtensibleMessage>.plusAssign(values: Iterable<E>) {
-      addAll(values)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, example_extensible_message.ExampleExtensibleMessage>.set(index: Int, value: E) {
-      _builder.setExtension(this.extension, index, value)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    inline fun com.google.protobuf.kotlin.ExtensionList<*, example_extensible_message.ExampleExtensibleMessage>.clear() {
-      clear(extension)
-    }
-
-  }
-}
-inline fun example_extensible_message.ExampleExtensibleMessage.copy(block: example_extensible_message.ExampleExtensibleMessageKt.Dsl.() -> Unit): example_extensible_message.ExampleExtensibleMessage =
-  example_extensible_message.ExampleExtensibleMessageKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/example_extensible_message/ExampleExtensibleMessageOrBuilder.java b/java/kotlin-lite/target/generated-test-sources/example_extensible_message/ExampleExtensibleMessageOrBuilder.java
deleted file mode 100644
index 525cdc3..0000000
--- a/java/kotlin-lite/target/generated-test-sources/example_extensible_message/ExampleExtensibleMessageOrBuilder.java
+++ /dev/null
@@ -1,11 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: com/google/protobuf/example_extensible_message.proto
-
-package example_extensible_message;
-
-public interface ExampleExtensibleMessageOrBuilder extends 
-    // @@protoc_insertion_point(interface_extends:example_extensible_message.ExampleExtensibleMessage)
-     com.google.protobuf.GeneratedMessageLite.
-          ExtendableMessageOrBuilder<
-              ExampleExtensibleMessage, ExampleExtensibleMessage.Builder> {
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/example_extensible_message/ExampleExtensibleMessageOuterClass.java b/java/kotlin-lite/target/generated-test-sources/example_extensible_message/ExampleExtensibleMessageOuterClass.java
deleted file mode 100644
index 6437761..0000000
--- a/java/kotlin-lite/target/generated-test-sources/example_extensible_message/ExampleExtensibleMessageOuterClass.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: com/google/protobuf/example_extensible_message.proto
-
-package example_extensible_message;
-
-public final class ExampleExtensibleMessageOuterClass {
-  private ExampleExtensibleMessageOuterClass() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-    registry.add(example_extensible_message.ExampleExtensibleMessageOuterClass.repeatedExtension);
-    registry.add(example_extensible_message.ExampleExtensibleMessageOuterClass.differentExtension);
-    registry.add(example_extensible_message.ExampleExtensibleMessageOuterClass.int32Extension);
-  }
-  public static final int REPEATED_EXTENSION_FIELD_NUMBER = 10;
-  /**
-   * <code>extend .example_extensible_message.ExampleExtensibleMessage { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      example_extensible_message.ExampleExtensibleMessage,
-      java.util.List<java.lang.Integer>> repeatedExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        example_extensible_message.ExampleExtensibleMessage.getDefaultInstance(),
-        null,
-        null,
-        10,
-        com.google.protobuf.WireFormat.FieldType.INT32,
-        false,
-        java.lang.Integer.class);
-  public static final int DIFFERENT_EXTENSION_FIELD_NUMBER = 11;
-  /**
-   * <code>extend .example_extensible_message.ExampleExtensibleMessage { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      example_extensible_message.ExampleExtensibleMessage,
-      java.util.List<java.lang.Integer>> differentExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        example_extensible_message.ExampleExtensibleMessage.getDefaultInstance(),
-        null,
-        null,
-        11,
-        com.google.protobuf.WireFormat.FieldType.INT32,
-        false,
-        java.lang.Integer.class);
-  public static final int INT32_EXTENSION_FIELD_NUMBER = 12;
-  /**
-   * <code>extend .example_extensible_message.ExampleExtensibleMessage { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      example_extensible_message.ExampleExtensibleMessage,
-      java.lang.Integer> int32Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        example_extensible_message.ExampleExtensibleMessage.getDefaultInstance(),
-        0,
-        null,
-        null,
-        12,
-        com.google.protobuf.WireFormat.FieldType.INT32,
-        java.lang.Integer.class);
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/example_extensible_message/ExampleExtensibleMessageOuterClassKt.kt b/java/kotlin-lite/target/generated-test-sources/example_extensible_message/ExampleExtensibleMessageOuterClassKt.kt
deleted file mode 100644
index e69de29..0000000
--- a/java/kotlin-lite/target/generated-test-sources/example_extensible_message/ExampleExtensibleMessageOuterClassKt.kt
+++ /dev/null
diff --git a/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageA.java b/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageA.java
deleted file mode 100644
index 613ecca..0000000
--- a/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageA.java
+++ /dev/null
@@ -1,181 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: com/google/protobuf/multiple_files_proto3.proto
-
-package multiple_files_proto3;
-
-/**
- * Protobuf type {@code multiple_files_proto3.MultipleFilesMessageA}
- */
-public  final class MultipleFilesMessageA extends
-    com.google.protobuf.GeneratedMessageLite<
-        MultipleFilesMessageA, MultipleFilesMessageA.Builder> implements
-    // @@protoc_insertion_point(message_implements:multiple_files_proto3.MultipleFilesMessageA)
-    MultipleFilesMessageAOrBuilder {
-  private MultipleFilesMessageA() {
-  }
-  public static multiple_files_proto3.MultipleFilesMessageA parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageA parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageA parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageA parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageA parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageA parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageA parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageA parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageA parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageA parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageA parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageA parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(multiple_files_proto3.MultipleFilesMessageA prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * Protobuf type {@code multiple_files_proto3.MultipleFilesMessageA}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        multiple_files_proto3.MultipleFilesMessageA, Builder> implements
-      // @@protoc_insertion_point(builder_implements:multiple_files_proto3.MultipleFilesMessageA)
-      multiple_files_proto3.MultipleFilesMessageAOrBuilder {
-    // Construct using multiple_files_proto3.MultipleFilesMessageA.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    // @@protoc_insertion_point(builder_scope:multiple_files_proto3.MultipleFilesMessageA)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new multiple_files_proto3.MultipleFilesMessageA();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = null;java.lang.String info =
-              "\u0000\u0000";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<multiple_files_proto3.MultipleFilesMessageA> parser = PARSER;
-        if (parser == null) {
-          synchronized (multiple_files_proto3.MultipleFilesMessageA.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<multiple_files_proto3.MultipleFilesMessageA>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:multiple_files_proto3.MultipleFilesMessageA)
-  private static final multiple_files_proto3.MultipleFilesMessageA DEFAULT_INSTANCE;
-  static {
-    MultipleFilesMessageA defaultInstance = new MultipleFilesMessageA();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      MultipleFilesMessageA.class, defaultInstance);
-  }
-
-  public static multiple_files_proto3.MultipleFilesMessageA getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<MultipleFilesMessageA> PARSER;
-
-  public static com.google.protobuf.Parser<MultipleFilesMessageA> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageAKt.kt b/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageAKt.kt
deleted file mode 100644
index 6e3e86c..0000000
--- a/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageAKt.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: com/google/protobuf/multiple_files_proto3.proto
-
-package multiple_files_proto3;
-
-@kotlin.jvm.JvmSynthetic
-inline fun multipleFilesMessageA(block: multiple_files_proto3.MultipleFilesMessageAKt.Dsl.() -> Unit): multiple_files_proto3.MultipleFilesMessageA =
-  multiple_files_proto3.MultipleFilesMessageAKt.Dsl._create(multiple_files_proto3.MultipleFilesMessageA.newBuilder()).apply { block() }._build()
-object MultipleFilesMessageAKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: multiple_files_proto3.MultipleFilesMessageA.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: multiple_files_proto3.MultipleFilesMessageA.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): multiple_files_proto3.MultipleFilesMessageA = _builder.build()
-  }
-}
-inline fun multiple_files_proto3.MultipleFilesMessageA.copy(block: multiple_files_proto3.MultipleFilesMessageAKt.Dsl.() -> Unit): multiple_files_proto3.MultipleFilesMessageA =
-  multiple_files_proto3.MultipleFilesMessageAKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageAOrBuilder.java b/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageAOrBuilder.java
deleted file mode 100644
index 3ebba77..0000000
--- a/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageAOrBuilder.java
+++ /dev/null
@@ -1,9 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: com/google/protobuf/multiple_files_proto3.proto
-
-package multiple_files_proto3;
-
-public interface MultipleFilesMessageAOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:multiple_files_proto3.MultipleFilesMessageA)
-    com.google.protobuf.MessageLiteOrBuilder {
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageB.java b/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageB.java
deleted file mode 100644
index 68fc7dc..0000000
--- a/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageB.java
+++ /dev/null
@@ -1,181 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: com/google/protobuf/multiple_files_proto3.proto
-
-package multiple_files_proto3;
-
-/**
- * Protobuf type {@code multiple_files_proto3.MultipleFilesMessageB}
- */
-public  final class MultipleFilesMessageB extends
-    com.google.protobuf.GeneratedMessageLite<
-        MultipleFilesMessageB, MultipleFilesMessageB.Builder> implements
-    // @@protoc_insertion_point(message_implements:multiple_files_proto3.MultipleFilesMessageB)
-    MultipleFilesMessageBOrBuilder {
-  private MultipleFilesMessageB() {
-  }
-  public static multiple_files_proto3.MultipleFilesMessageB parseFrom(
-      java.nio.ByteBuffer data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageB parseFrom(
-      java.nio.ByteBuffer data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageB parseFrom(
-      com.google.protobuf.ByteString data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageB parseFrom(
-      com.google.protobuf.ByteString data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageB parseFrom(byte[] data)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageB parseFrom(
-      byte[] data,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws com.google.protobuf.InvalidProtocolBufferException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, data, extensionRegistry);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageB parseFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageB parseFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageB parseDelimitedFrom(java.io.InputStream input)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageB parseDelimitedFrom(
-      java.io.InputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageB parseFrom(
-      com.google.protobuf.CodedInputStream input)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input);
-  }
-  public static multiple_files_proto3.MultipleFilesMessageB parseFrom(
-      com.google.protobuf.CodedInputStream input,
-      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-      throws java.io.IOException {
-    return com.google.protobuf.GeneratedMessageLite.parseFrom(
-        DEFAULT_INSTANCE, input, extensionRegistry);
-  }
-
-  public static Builder newBuilder() {
-    return (Builder) DEFAULT_INSTANCE.createBuilder();
-  }
-  public static Builder newBuilder(multiple_files_proto3.MultipleFilesMessageB prototype) {
-    return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-  }
-
-  /**
-   * Protobuf type {@code multiple_files_proto3.MultipleFilesMessageB}
-   */
-  public static final class Builder extends
-      com.google.protobuf.GeneratedMessageLite.Builder<
-        multiple_files_proto3.MultipleFilesMessageB, Builder> implements
-      // @@protoc_insertion_point(builder_implements:multiple_files_proto3.MultipleFilesMessageB)
-      multiple_files_proto3.MultipleFilesMessageBOrBuilder {
-    // Construct using multiple_files_proto3.MultipleFilesMessageB.newBuilder()
-    private Builder() {
-      super(DEFAULT_INSTANCE);
-    }
-
-
-    // @@protoc_insertion_point(builder_scope:multiple_files_proto3.MultipleFilesMessageB)
-  }
-  @java.lang.Override
-  @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-  protected final java.lang.Object dynamicMethod(
-      com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-      java.lang.Object arg0, java.lang.Object arg1) {
-    switch (method) {
-      case NEW_MUTABLE_INSTANCE: {
-        return new multiple_files_proto3.MultipleFilesMessageB();
-      }
-      case NEW_BUILDER: {
-        return new Builder();
-      }
-      case BUILD_MESSAGE_INFO: {
-          java.lang.Object[] objects = null;java.lang.String info =
-              "\u0000\u0000";
-          return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-      }
-      // fall through
-      case GET_DEFAULT_INSTANCE: {
-        return DEFAULT_INSTANCE;
-      }
-      case GET_PARSER: {
-        com.google.protobuf.Parser<multiple_files_proto3.MultipleFilesMessageB> parser = PARSER;
-        if (parser == null) {
-          synchronized (multiple_files_proto3.MultipleFilesMessageB.class) {
-            parser = PARSER;
-            if (parser == null) {
-              parser =
-                  new DefaultInstanceBasedParser<multiple_files_proto3.MultipleFilesMessageB>(
-                      DEFAULT_INSTANCE);
-              PARSER = parser;
-            }
-          }
-        }
-        return parser;
-    }
-    case GET_MEMOIZED_IS_INITIALIZED: {
-      return (byte) 1;
-    }
-    case SET_MEMOIZED_IS_INITIALIZED: {
-      return null;
-    }
-    }
-    throw new UnsupportedOperationException();
-  }
-
-
-  // @@protoc_insertion_point(class_scope:multiple_files_proto3.MultipleFilesMessageB)
-  private static final multiple_files_proto3.MultipleFilesMessageB DEFAULT_INSTANCE;
-  static {
-    MultipleFilesMessageB defaultInstance = new MultipleFilesMessageB();
-    // New instances are implicitly immutable so no need to make
-    // immutable.
-    DEFAULT_INSTANCE = defaultInstance;
-    com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-      MultipleFilesMessageB.class, defaultInstance);
-  }
-
-  public static multiple_files_proto3.MultipleFilesMessageB getDefaultInstance() {
-    return DEFAULT_INSTANCE;
-  }
-
-  private static volatile com.google.protobuf.Parser<MultipleFilesMessageB> PARSER;
-
-  public static com.google.protobuf.Parser<MultipleFilesMessageB> parser() {
-    return DEFAULT_INSTANCE.getParserForType();
-  }
-}
-
diff --git a/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageBKt.kt b/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageBKt.kt
deleted file mode 100644
index 06c5a93..0000000
--- a/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageBKt.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: com/google/protobuf/multiple_files_proto3.proto
-
-package multiple_files_proto3;
-
-@kotlin.jvm.JvmSynthetic
-inline fun multipleFilesMessageB(block: multiple_files_proto3.MultipleFilesMessageBKt.Dsl.() -> Unit): multiple_files_proto3.MultipleFilesMessageB =
-  multiple_files_proto3.MultipleFilesMessageBKt.Dsl._create(multiple_files_proto3.MultipleFilesMessageB.newBuilder()).apply { block() }._build()
-object MultipleFilesMessageBKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: multiple_files_proto3.MultipleFilesMessageB.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: multiple_files_proto3.MultipleFilesMessageB.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): multiple_files_proto3.MultipleFilesMessageB = _builder.build()
-  }
-}
-inline fun multiple_files_proto3.MultipleFilesMessageB.copy(block: multiple_files_proto3.MultipleFilesMessageBKt.Dsl.() -> Unit): multiple_files_proto3.MultipleFilesMessageB =
-  multiple_files_proto3.MultipleFilesMessageBKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageBOrBuilder.java b/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageBOrBuilder.java
deleted file mode 100644
index 3c92c20..0000000
--- a/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageBOrBuilder.java
+++ /dev/null
@@ -1,9 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: com/google/protobuf/multiple_files_proto3.proto
-
-package multiple_files_proto3;
-
-public interface MultipleFilesMessageBOrBuilder extends
-    // @@protoc_insertion_point(interface_extends:multiple_files_proto3.MultipleFilesMessageB)
-    com.google.protobuf.MessageLiteOrBuilder {
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesProto3.java b/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesProto3.java
deleted file mode 100644
index e244c9c..0000000
--- a/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesProto3.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: com/google/protobuf/multiple_files_proto3.proto
-
-package multiple_files_proto3;
-
-public final class MultipleFilesProto3 {
-  private MultipleFilesProto3() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesProto3Kt.kt b/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesProto3Kt.kt
deleted file mode 100644
index e69de29..0000000
--- a/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesProto3Kt.kt
+++ /dev/null
diff --git a/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/NestedEnum.java b/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/NestedEnum.java
deleted file mode 100644
index d2c46b2..0000000
--- a/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/NestedEnum.java
+++ /dev/null
@@ -1,85 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: com/google/protobuf/multiple_files_proto3.proto
-
-package multiple_files_proto3;
-
-/**
- * Protobuf enum {@code multiple_files_proto3.NestedEnum}
- */
-public enum NestedEnum
-    implements com.google.protobuf.Internal.EnumLite {
-  /**
-   * <code>FOO = 0;</code>
-   */
-  FOO(0),
-  UNRECOGNIZED(-1),
-  ;
-
-  /**
-   * <code>FOO = 0;</code>
-   */
-  public static final int FOO_VALUE = 0;
-
-
-  @java.lang.Override
-  public final int getNumber() {
-    if (this == UNRECOGNIZED) {
-      throw new java.lang.IllegalArgumentException(
-          "Can't get the number of an unknown enum value.");
-    }
-    return value;
-  }
-
-  /**
-   * @param value The number of the enum to look for.
-   * @return The enum associated with the given number.
-   * @deprecated Use {@link #forNumber(int)} instead.
-   */
-  @java.lang.Deprecated
-  public static NestedEnum valueOf(int value) {
-    return forNumber(value);
-  }
-
-  public static NestedEnum forNumber(int value) {
-    switch (value) {
-      case 0: return FOO;
-      default: return null;
-    }
-  }
-
-  public static com.google.protobuf.Internal.EnumLiteMap<NestedEnum>
-      internalGetValueMap() {
-    return internalValueMap;
-  }
-  private static final com.google.protobuf.Internal.EnumLiteMap<
-      NestedEnum> internalValueMap =
-        new com.google.protobuf.Internal.EnumLiteMap<NestedEnum>() {
-          @java.lang.Override
-          public NestedEnum findValueByNumber(int number) {
-            return NestedEnum.forNumber(number);
-          }
-        };
-
-  public static com.google.protobuf.Internal.EnumVerifier 
-      internalGetVerifier() {
-    return NestedEnumVerifier.INSTANCE;
-  }
-
-  private static final class NestedEnumVerifier implements 
-       com.google.protobuf.Internal.EnumVerifier { 
-          static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new NestedEnumVerifier();
-          @java.lang.Override
-          public boolean isInRange(int number) {
-            return NestedEnum.forNumber(number) != null;
-          }
-        };
-
-  private final int value;
-
-  private NestedEnum(int value) {
-    this.value = value;
-  }
-
-  // @@protoc_insertion_point(enum_scope:multiple_files_proto3.NestedEnum)
-}
-
diff --git a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/ForeignMessageKt.kt b/java/kotlin-lite/target/generated-test-sources/proto3_unittest/ForeignMessageKt.kt
deleted file mode 100644
index 5e022f3..0000000
--- a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/ForeignMessageKt.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_proto3.proto
-
-package proto3_unittest;
-
-@kotlin.jvm.JvmSynthetic
-inline fun foreignMessage(block: proto3_unittest.ForeignMessageKt.Dsl.() -> Unit): proto3_unittest.UnittestProto3.ForeignMessage =
-  proto3_unittest.ForeignMessageKt.Dsl._create(proto3_unittest.UnittestProto3.ForeignMessage.newBuilder()).apply { block() }._build()
-object ForeignMessageKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: proto3_unittest.UnittestProto3.ForeignMessage.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: proto3_unittest.UnittestProto3.ForeignMessage.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): proto3_unittest.UnittestProto3.ForeignMessage = _builder.build()
-
-    /**
-     * <code>int32 c = 1;</code>
-     */
-    var c: kotlin.Int
-      @JvmName("getC")
-      get() = _builder.getC()
-      @JvmName("setC")
-      set(value) {
-        _builder.setC(value)
-      }
-    /**
-     * <code>int32 c = 1;</code>
-     */
-    fun clearC() {
-      _builder.clearC()
-    }
-  }
-}
-inline fun proto3_unittest.UnittestProto3.ForeignMessage.copy(block: proto3_unittest.ForeignMessageKt.Dsl.() -> Unit): proto3_unittest.UnittestProto3.ForeignMessage =
-  proto3_unittest.ForeignMessageKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/NestedTestAllTypesKt.kt b/java/kotlin-lite/target/generated-test-sources/proto3_unittest/NestedTestAllTypesKt.kt
deleted file mode 100644
index 96c49f6..0000000
--- a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/NestedTestAllTypesKt.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_proto3.proto
-
-package proto3_unittest;
-
-@kotlin.jvm.JvmSynthetic
-inline fun nestedTestAllTypes(block: proto3_unittest.NestedTestAllTypesKt.Dsl.() -> Unit): proto3_unittest.UnittestProto3.NestedTestAllTypes =
-  proto3_unittest.NestedTestAllTypesKt.Dsl._create(proto3_unittest.UnittestProto3.NestedTestAllTypes.newBuilder()).apply { block() }._build()
-object NestedTestAllTypesKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: proto3_unittest.UnittestProto3.NestedTestAllTypes.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: proto3_unittest.UnittestProto3.NestedTestAllTypes.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): proto3_unittest.UnittestProto3.NestedTestAllTypes = _builder.build()
-
-    /**
-     * <code>.proto3_unittest.NestedTestAllTypes child = 1;</code>
-     */
-    var child: proto3_unittest.UnittestProto3.NestedTestAllTypes
-      @JvmName("getChild")
-      get() = _builder.getChild()
-      @JvmName("setChild")
-      set(value) {
-        _builder.setChild(value)
-      }
-    /**
-     * <code>.proto3_unittest.NestedTestAllTypes child = 1;</code>
-     */
-    fun clearChild() {
-      _builder.clearChild()
-    }
-    /**
-     * <code>.proto3_unittest.NestedTestAllTypes child = 1;</code>
-     * @return Whether the child field is set.
-     */
-    fun hasChild(): kotlin.Boolean {
-      return _builder.hasChild()
-    }
-
-    /**
-     * <code>.proto3_unittest.TestAllTypes payload = 2;</code>
-     */
-    var payload: proto3_unittest.UnittestProto3.TestAllTypes
-      @JvmName("getPayload")
-      get() = _builder.getPayload()
-      @JvmName("setPayload")
-      set(value) {
-        _builder.setPayload(value)
-      }
-    /**
-     * <code>.proto3_unittest.TestAllTypes payload = 2;</code>
-     */
-    fun clearPayload() {
-      _builder.clearPayload()
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes payload = 2;</code>
-     * @return Whether the payload field is set.
-     */
-    fun hasPayload(): kotlin.Boolean {
-      return _builder.hasPayload()
-    }
-  }
-}
-inline fun proto3_unittest.UnittestProto3.NestedTestAllTypes.copy(block: proto3_unittest.NestedTestAllTypesKt.Dsl.() -> Unit): proto3_unittest.UnittestProto3.NestedTestAllTypes =
-  proto3_unittest.NestedTestAllTypesKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/TestAllTypesKt.kt b/java/kotlin-lite/target/generated-test-sources/proto3_unittest/TestAllTypesKt.kt
deleted file mode 100644
index 0707aad..0000000
--- a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/TestAllTypesKt.kt
+++ /dev/null
@@ -1,2160 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_proto3.proto
-
-package proto3_unittest;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testAllTypes(block: proto3_unittest.TestAllTypesKt.Dsl.() -> Unit): proto3_unittest.UnittestProto3.TestAllTypes =
-  proto3_unittest.TestAllTypesKt.Dsl._create(proto3_unittest.UnittestProto3.TestAllTypes.newBuilder()).apply { block() }._build()
-object TestAllTypesKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: proto3_unittest.UnittestProto3.TestAllTypes.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: proto3_unittest.UnittestProto3.TestAllTypes.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): proto3_unittest.UnittestProto3.TestAllTypes = _builder.build()
-
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>int32 optional_int32 = 1;</code>
-     */
-    var optionalInt32: kotlin.Int
-      @JvmName("getOptionalInt32")
-      get() = _builder.getOptionalInt32()
-      @JvmName("setOptionalInt32")
-      set(value) {
-        _builder.setOptionalInt32(value)
-      }
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>int32 optional_int32 = 1;</code>
-     */
-    fun clearOptionalInt32() {
-      _builder.clearOptionalInt32()
-    }
-
-    /**
-     * <code>int64 optional_int64 = 2;</code>
-     */
-    var optionalInt64: kotlin.Long
-      @JvmName("getOptionalInt64")
-      get() = _builder.getOptionalInt64()
-      @JvmName("setOptionalInt64")
-      set(value) {
-        _builder.setOptionalInt64(value)
-      }
-    /**
-     * <code>int64 optional_int64 = 2;</code>
-     */
-    fun clearOptionalInt64() {
-      _builder.clearOptionalInt64()
-    }
-
-    /**
-     * <code>uint32 optional_uint32 = 3;</code>
-     */
-    var optionalUint32: kotlin.Int
-      @JvmName("getOptionalUint32")
-      get() = _builder.getOptionalUint32()
-      @JvmName("setOptionalUint32")
-      set(value) {
-        _builder.setOptionalUint32(value)
-      }
-    /**
-     * <code>uint32 optional_uint32 = 3;</code>
-     */
-    fun clearOptionalUint32() {
-      _builder.clearOptionalUint32()
-    }
-
-    /**
-     * <code>uint64 optional_uint64 = 4;</code>
-     */
-    var optionalUint64: kotlin.Long
-      @JvmName("getOptionalUint64")
-      get() = _builder.getOptionalUint64()
-      @JvmName("setOptionalUint64")
-      set(value) {
-        _builder.setOptionalUint64(value)
-      }
-    /**
-     * <code>uint64 optional_uint64 = 4;</code>
-     */
-    fun clearOptionalUint64() {
-      _builder.clearOptionalUint64()
-    }
-
-    /**
-     * <code>sint32 optional_sint32 = 5;</code>
-     */
-    var optionalSint32: kotlin.Int
-      @JvmName("getOptionalSint32")
-      get() = _builder.getOptionalSint32()
-      @JvmName("setOptionalSint32")
-      set(value) {
-        _builder.setOptionalSint32(value)
-      }
-    /**
-     * <code>sint32 optional_sint32 = 5;</code>
-     */
-    fun clearOptionalSint32() {
-      _builder.clearOptionalSint32()
-    }
-
-    /**
-     * <code>sint64 optional_sint64 = 6;</code>
-     */
-    var optionalSint64: kotlin.Long
-      @JvmName("getOptionalSint64")
-      get() = _builder.getOptionalSint64()
-      @JvmName("setOptionalSint64")
-      set(value) {
-        _builder.setOptionalSint64(value)
-      }
-    /**
-     * <code>sint64 optional_sint64 = 6;</code>
-     */
-    fun clearOptionalSint64() {
-      _builder.clearOptionalSint64()
-    }
-
-    /**
-     * <code>fixed32 optional_fixed32 = 7;</code>
-     */
-    var optionalFixed32: kotlin.Int
-      @JvmName("getOptionalFixed32")
-      get() = _builder.getOptionalFixed32()
-      @JvmName("setOptionalFixed32")
-      set(value) {
-        _builder.setOptionalFixed32(value)
-      }
-    /**
-     * <code>fixed32 optional_fixed32 = 7;</code>
-     */
-    fun clearOptionalFixed32() {
-      _builder.clearOptionalFixed32()
-    }
-
-    /**
-     * <code>fixed64 optional_fixed64 = 8;</code>
-     */
-    var optionalFixed64: kotlin.Long
-      @JvmName("getOptionalFixed64")
-      get() = _builder.getOptionalFixed64()
-      @JvmName("setOptionalFixed64")
-      set(value) {
-        _builder.setOptionalFixed64(value)
-      }
-    /**
-     * <code>fixed64 optional_fixed64 = 8;</code>
-     */
-    fun clearOptionalFixed64() {
-      _builder.clearOptionalFixed64()
-    }
-
-    /**
-     * <code>sfixed32 optional_sfixed32 = 9;</code>
-     */
-    var optionalSfixed32: kotlin.Int
-      @JvmName("getOptionalSfixed32")
-      get() = _builder.getOptionalSfixed32()
-      @JvmName("setOptionalSfixed32")
-      set(value) {
-        _builder.setOptionalSfixed32(value)
-      }
-    /**
-     * <code>sfixed32 optional_sfixed32 = 9;</code>
-     */
-    fun clearOptionalSfixed32() {
-      _builder.clearOptionalSfixed32()
-    }
-
-    /**
-     * <code>sfixed64 optional_sfixed64 = 10;</code>
-     */
-    var optionalSfixed64: kotlin.Long
-      @JvmName("getOptionalSfixed64")
-      get() = _builder.getOptionalSfixed64()
-      @JvmName("setOptionalSfixed64")
-      set(value) {
-        _builder.setOptionalSfixed64(value)
-      }
-    /**
-     * <code>sfixed64 optional_sfixed64 = 10;</code>
-     */
-    fun clearOptionalSfixed64() {
-      _builder.clearOptionalSfixed64()
-    }
-
-    /**
-     * <code>float optional_float = 11;</code>
-     */
-    var optionalFloat: kotlin.Float
-      @JvmName("getOptionalFloat")
-      get() = _builder.getOptionalFloat()
-      @JvmName("setOptionalFloat")
-      set(value) {
-        _builder.setOptionalFloat(value)
-      }
-    /**
-     * <code>float optional_float = 11;</code>
-     */
-    fun clearOptionalFloat() {
-      _builder.clearOptionalFloat()
-    }
-
-    /**
-     * <code>double optional_double = 12;</code>
-     */
-    var optionalDouble: kotlin.Double
-      @JvmName("getOptionalDouble")
-      get() = _builder.getOptionalDouble()
-      @JvmName("setOptionalDouble")
-      set(value) {
-        _builder.setOptionalDouble(value)
-      }
-    /**
-     * <code>double optional_double = 12;</code>
-     */
-    fun clearOptionalDouble() {
-      _builder.clearOptionalDouble()
-    }
-
-    /**
-     * <code>bool optional_bool = 13;</code>
-     */
-    var optionalBool: kotlin.Boolean
-      @JvmName("getOptionalBool")
-      get() = _builder.getOptionalBool()
-      @JvmName("setOptionalBool")
-      set(value) {
-        _builder.setOptionalBool(value)
-      }
-    /**
-     * <code>bool optional_bool = 13;</code>
-     */
-    fun clearOptionalBool() {
-      _builder.clearOptionalBool()
-    }
-
-    /**
-     * <code>string optional_string = 14;</code>
-     */
-    var optionalString: kotlin.String
-      @JvmName("getOptionalString")
-      get() = _builder.getOptionalString()
-      @JvmName("setOptionalString")
-      set(value) {
-        _builder.setOptionalString(value)
-      }
-    /**
-     * <code>string optional_string = 14;</code>
-     */
-    fun clearOptionalString() {
-      _builder.clearOptionalString()
-    }
-
-    /**
-     * <code>bytes optional_bytes = 15;</code>
-     */
-    var optionalBytes: com.google.protobuf.ByteString
-      @JvmName("getOptionalBytes")
-      get() = _builder.getOptionalBytes()
-      @JvmName("setOptionalBytes")
-      set(value) {
-        _builder.setOptionalBytes(value)
-      }
-    /**
-     * <code>bytes optional_bytes = 15;</code>
-     */
-    fun clearOptionalBytes() {
-      _builder.clearOptionalBytes()
-    }
-
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-     */
-    var optionalNestedMessage: proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage
-      @JvmName("getOptionalNestedMessage")
-      get() = _builder.getOptionalNestedMessage()
-      @JvmName("setOptionalNestedMessage")
-      set(value) {
-        _builder.setOptionalNestedMessage(value)
-      }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-     */
-    fun clearOptionalNestedMessage() {
-      _builder.clearOptionalNestedMessage()
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-     * @return Whether the optionalNestedMessage field is set.
-     */
-    fun hasOptionalNestedMessage(): kotlin.Boolean {
-      return _builder.hasOptionalNestedMessage()
-    }
-
-    /**
-     * <code>.proto3_unittest.ForeignMessage optional_foreign_message = 19;</code>
-     */
-    var optionalForeignMessage: proto3_unittest.UnittestProto3.ForeignMessage
-      @JvmName("getOptionalForeignMessage")
-      get() = _builder.getOptionalForeignMessage()
-      @JvmName("setOptionalForeignMessage")
-      set(value) {
-        _builder.setOptionalForeignMessage(value)
-      }
-    /**
-     * <code>.proto3_unittest.ForeignMessage optional_foreign_message = 19;</code>
-     */
-    fun clearOptionalForeignMessage() {
-      _builder.clearOptionalForeignMessage()
-    }
-    /**
-     * <code>.proto3_unittest.ForeignMessage optional_foreign_message = 19;</code>
-     * @return Whether the optionalForeignMessage field is set.
-     */
-    fun hasOptionalForeignMessage(): kotlin.Boolean {
-      return _builder.hasOptionalForeignMessage()
-    }
-
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-     */
-    var optionalImportMessage: com.google.protobuf.test.UnittestImport.ImportMessage
-      @JvmName("getOptionalImportMessage")
-      get() = _builder.getOptionalImportMessage()
-      @JvmName("setOptionalImportMessage")
-      set(value) {
-        _builder.setOptionalImportMessage(value)
-      }
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-     */
-    fun clearOptionalImportMessage() {
-      _builder.clearOptionalImportMessage()
-    }
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-     * @return Whether the optionalImportMessage field is set.
-     */
-    fun hasOptionalImportMessage(): kotlin.Boolean {
-      return _builder.hasOptionalImportMessage()
-    }
-
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-     */
-    var optionalNestedEnum: proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum
-      @JvmName("getOptionalNestedEnum")
-      get() = _builder.getOptionalNestedEnum()
-      @JvmName("setOptionalNestedEnum")
-      set(value) {
-        _builder.setOptionalNestedEnum(value)
-      }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-     */
-    fun clearOptionalNestedEnum() {
-      _builder.clearOptionalNestedEnum()
-    }
-
-    /**
-     * <code>.proto3_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     */
-    var optionalForeignEnum: proto3_unittest.UnittestProto3.ForeignEnum
-      @JvmName("getOptionalForeignEnum")
-      get() = _builder.getOptionalForeignEnum()
-      @JvmName("setOptionalForeignEnum")
-      set(value) {
-        _builder.setOptionalForeignEnum(value)
-      }
-    /**
-     * <code>.proto3_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     */
-    fun clearOptionalForeignEnum() {
-      _builder.clearOptionalForeignEnum()
-    }
-
-    /**
-     * <code>string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     */
-    var optionalStringPiece: kotlin.String
-      @JvmName("getOptionalStringPiece")
-      get() = _builder.getOptionalStringPiece()
-      @JvmName("setOptionalStringPiece")
-      set(value) {
-        _builder.setOptionalStringPiece(value)
-      }
-    /**
-     * <code>string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     */
-    fun clearOptionalStringPiece() {
-      _builder.clearOptionalStringPiece()
-    }
-
-    /**
-     * <code>string optional_cord = 25 [ctype = CORD];</code>
-     */
-    var optionalCord: kotlin.String
-      @JvmName("getOptionalCord")
-      get() = _builder.getOptionalCord()
-      @JvmName("setOptionalCord")
-      set(value) {
-        _builder.setOptionalCord(value)
-      }
-    /**
-     * <code>string optional_cord = 25 [ctype = CORD];</code>
-     */
-    fun clearOptionalCord() {
-      _builder.clearOptionalCord()
-    }
-
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>.protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-     */
-    var optionalPublicImportMessage: com.google.protobuf.test.UnittestImportPublic.PublicImportMessage
-      @JvmName("getOptionalPublicImportMessage")
-      get() = _builder.getOptionalPublicImportMessage()
-      @JvmName("setOptionalPublicImportMessage")
-      set(value) {
-        _builder.setOptionalPublicImportMessage(value)
-      }
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>.protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-     */
-    fun clearOptionalPublicImportMessage() {
-      _builder.clearOptionalPublicImportMessage()
-    }
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>.protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-     * @return Whether the optionalPublicImportMessage field is set.
-     */
-    fun hasOptionalPublicImportMessage(): kotlin.Boolean {
-      return _builder.hasOptionalPublicImportMessage()
-    }
-
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     */
-    var optionalLazyMessage: proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage
-      @JvmName("getOptionalLazyMessage")
-      get() = _builder.getOptionalLazyMessage()
-      @JvmName("setOptionalLazyMessage")
-      set(value) {
-        _builder.setOptionalLazyMessage(value)
-      }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     */
-    fun clearOptionalLazyMessage() {
-      _builder.clearOptionalLazyMessage()
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     * @return Whether the optionalLazyMessage field is set.
-     */
-    fun hasOptionalLazyMessage(): kotlin.Boolean {
-      return _builder.hasOptionalLazyMessage()
-    }
-
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115 [lazy = true];</code>
-     */
-    var optionalLazyImportMessage: com.google.protobuf.test.UnittestImport.ImportMessage
-      @JvmName("getOptionalLazyImportMessage")
-      get() = _builder.getOptionalLazyImportMessage()
-      @JvmName("setOptionalLazyImportMessage")
-      set(value) {
-        _builder.setOptionalLazyImportMessage(value)
-      }
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115 [lazy = true];</code>
-     */
-    fun clearOptionalLazyImportMessage() {
-      _builder.clearOptionalLazyImportMessage()
-    }
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115 [lazy = true];</code>
-     * @return Whether the optionalLazyImportMessage field is set.
-     */
-    fun hasOptionalLazyImportMessage(): kotlin.Boolean {
-      return _builder.hasOptionalLazyImportMessage()
-    }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedInt32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     */
-     val repeatedInt32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedInt32List()
-      )
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param value The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedInt32(value)
-    }/**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param value The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedInt32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param values The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedInt32(values)
-    }/**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param values The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedInt32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedInt32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedInt32(index, value)
-    }/**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.clear() {
-      _builder.clearRepeatedInt32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedInt64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     */
-     val repeatedInt64: com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedInt64List()
-      )
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param value The repeatedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedInt64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>.add(value: kotlin.Long) {
-      _builder.addRepeatedInt64(value)
-    }/**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param value The repeatedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedInt64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param values The repeatedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedInt64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllRepeatedInt64(values)
-    }/**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param values The repeatedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedInt64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedInt64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setRepeatedInt64(index, value)
-    }/**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedInt64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>.clear() {
-      _builder.clearRepeatedInt64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedUint32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     */
-     val repeatedUint32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedUint32List()
-      )
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param value The repeatedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedUint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedUint32(value)
-    }/**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param value The repeatedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedUint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param values The repeatedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedUint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedUint32(values)
-    }/**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param values The repeatedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedUint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedUint32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedUint32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedUint32(index, value)
-    }/**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedUint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>.clear() {
-      _builder.clearRepeatedUint32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedUint64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     */
-     val repeatedUint64: com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedUint64List()
-      )
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param value The repeatedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedUint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>.add(value: kotlin.Long) {
-      _builder.addRepeatedUint64(value)
-    }/**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param value The repeatedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedUint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param values The repeatedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedUint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllRepeatedUint64(values)
-    }/**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param values The repeatedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedUint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedUint64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedUint64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setRepeatedUint64(index, value)
-    }/**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedUint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>.clear() {
-      _builder.clearRepeatedUint64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedSint32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     */
-     val repeatedSint32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedSint32List()
-      )
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param value The repeatedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedSint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedSint32(value)
-    }/**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param value The repeatedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedSint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param values The repeatedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedSint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedSint32(values)
-    }/**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param values The repeatedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedSint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSint32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedSint32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedSint32(index, value)
-    }/**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedSint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>.clear() {
-      _builder.clearRepeatedSint32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedSint64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     */
-     val repeatedSint64: com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedSint64List()
-      )
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param value The repeatedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedSint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>.add(value: kotlin.Long) {
-      _builder.addRepeatedSint64(value)
-    }/**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param value The repeatedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedSint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param values The repeatedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedSint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllRepeatedSint64(values)
-    }/**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param values The repeatedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedSint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSint64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedSint64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setRepeatedSint64(index, value)
-    }/**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedSint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>.clear() {
-      _builder.clearRepeatedSint64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedFixed32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     */
-     val repeatedFixed32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedFixed32List()
-      )
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param value The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedFixed32(value)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param value The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedFixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param values The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedFixed32(values)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param values The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedFixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedFixed32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedFixed32(index, value)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.clear() {
-      _builder.clearRepeatedFixed32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedFixed64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     */
-     val repeatedFixed64: com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedFixed64List()
-      )
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param value The repeatedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedFixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>.add(value: kotlin.Long) {
-      _builder.addRepeatedFixed64(value)
-    }/**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param value The repeatedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedFixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param values The repeatedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedFixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllRepeatedFixed64(values)
-    }/**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param values The repeatedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedFixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedFixed64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setRepeatedFixed64(index, value)
-    }/**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedFixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>.clear() {
-      _builder.clearRepeatedFixed64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedSfixed32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     */
-     val repeatedSfixed32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedSfixed32List()
-      )
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param value The repeatedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedSfixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedSfixed32(value)
-    }/**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param value The repeatedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedSfixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param values The repeatedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedSfixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedSfixed32(values)
-    }/**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param values The repeatedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedSfixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSfixed32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedSfixed32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedSfixed32(index, value)
-    }/**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedSfixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>.clear() {
-      _builder.clearRepeatedSfixed32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedSfixed64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     */
-     val repeatedSfixed64: com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedSfixed64List()
-      )
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param value The repeatedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedSfixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>.add(value: kotlin.Long) {
-      _builder.addRepeatedSfixed64(value)
-    }/**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param value The repeatedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedSfixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param values The repeatedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedSfixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllRepeatedSfixed64(values)
-    }/**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param values The repeatedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedSfixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSfixed64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedSfixed64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setRepeatedSfixed64(index, value)
-    }/**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedSfixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>.clear() {
-      _builder.clearRepeatedSfixed64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedFloatProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     */
-     val repeatedFloat: com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedFloatList()
-      )
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param value The repeatedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedFloat")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>.add(value: kotlin.Float) {
-      _builder.addRepeatedFloat(value)
-    }/**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param value The repeatedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedFloat")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>.plusAssign(value: kotlin.Float) {
-      add(value)
-    }/**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param values The repeatedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedFloat")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>.addAll(values: kotlin.collections.Iterable<kotlin.Float>) {
-      _builder.addAllRepeatedFloat(values)
-    }/**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param values The repeatedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedFloat")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Float>) {
-      addAll(values)
-    }/**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFloat to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedFloat")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>.set(index: kotlin.Int, value: kotlin.Float) {
-      _builder.setRepeatedFloat(index, value)
-    }/**
-     * <code>repeated float repeated_float = 41;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedFloat")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>.clear() {
-      _builder.clearRepeatedFloat()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedDoubleProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     */
-     val repeatedDouble: com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedDoubleList()
-      )
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param value The repeatedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedDouble")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>.add(value: kotlin.Double) {
-      _builder.addRepeatedDouble(value)
-    }/**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param value The repeatedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedDouble")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>.plusAssign(value: kotlin.Double) {
-      add(value)
-    }/**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param values The repeatedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedDouble")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>.addAll(values: kotlin.collections.Iterable<kotlin.Double>) {
-      _builder.addAllRepeatedDouble(values)
-    }/**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param values The repeatedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedDouble")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Double>) {
-      addAll(values)
-    }/**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedDouble to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedDouble")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>.set(index: kotlin.Int, value: kotlin.Double) {
-      _builder.setRepeatedDouble(index, value)
-    }/**
-     * <code>repeated double repeated_double = 42;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedDouble")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>.clear() {
-      _builder.clearRepeatedDouble()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedBoolProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     */
-     val repeatedBool: com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedBoolList()
-      )
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param value The repeatedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedBool")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>.add(value: kotlin.Boolean) {
-      _builder.addRepeatedBool(value)
-    }/**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param value The repeatedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedBool")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>.plusAssign(value: kotlin.Boolean) {
-      add(value)
-    }/**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param values The repeatedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedBool")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>.addAll(values: kotlin.collections.Iterable<kotlin.Boolean>) {
-      _builder.addAllRepeatedBool(values)
-    }/**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param values The repeatedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedBool")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Boolean>) {
-      addAll(values)
-    }/**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedBool to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedBool")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>.set(index: kotlin.Int, value: kotlin.Boolean) {
-      _builder.setRepeatedBool(index, value)
-    }/**
-     * <code>repeated bool repeated_bool = 43;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedBool")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>.clear() {
-      _builder.clearRepeatedBool()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedStringProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @return A list containing the repeatedString.
-     */
-    val repeatedString: com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringProxy>
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedStringList()
-      )
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param value The repeatedString to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedString")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringProxy>.add(value: kotlin.String) {
-      _builder.addRepeatedString(value)
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param value The repeatedString to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedString")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringProxy>.plusAssign(value: kotlin.String) {
-      add(value)
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param values The repeatedString to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedString")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringProxy>.addAll(values: kotlin.collections.Iterable<kotlin.String>) {
-      _builder.addAllRepeatedString(values)
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param values The repeatedString to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedString")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.String>) {
-      addAll(values)
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedString to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedString")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringProxy>.set(index: kotlin.Int, value: kotlin.String) {
-      _builder.setRepeatedString(index, value)
-    }/**
-     * <code>repeated string repeated_string = 44;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedString")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringProxy>.clear() {
-      _builder.clearRepeatedString()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedBytesProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     */
-     val repeatedBytes: com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, RepeatedBytesProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedBytesList()
-      )
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param value The repeatedBytes to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedBytes")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, RepeatedBytesProxy>.add(value: com.google.protobuf.ByteString) {
-      _builder.addRepeatedBytes(value)
-    }/**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param value The repeatedBytes to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedBytes")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, RepeatedBytesProxy>.plusAssign(value: com.google.protobuf.ByteString) {
-      add(value)
-    }/**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param values The repeatedBytes to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedBytes")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, RepeatedBytesProxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.ByteString>) {
-      _builder.addAllRepeatedBytes(values)
-    }/**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param values The repeatedBytes to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedBytes")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, RepeatedBytesProxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.ByteString>) {
-      addAll(values)
-    }/**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedBytes to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedBytes")
-    operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, RepeatedBytesProxy>.set(index: kotlin.Int, value: com.google.protobuf.ByteString) {
-      _builder.setRepeatedBytes(index, value)
-    }/**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedBytes")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.ByteString, RepeatedBytesProxy>.clear() {
-      _builder.clearRepeatedBytes()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedNestedMessageProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-     val repeatedNestedMessage: com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage, RepeatedNestedMessageProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedNestedMessageList()
-      )
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     * @param value The repeatedNestedMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedNestedMessage")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage, RepeatedNestedMessageProxy>.add(value: proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage) {
-      _builder.addRepeatedNestedMessage(value)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     * @param value The repeatedNestedMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedNestedMessage")
-    inline operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage, RepeatedNestedMessageProxy>.plusAssign(value: proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage) {
-      add(value)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     * @param values The repeatedNestedMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedNestedMessage")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage, RepeatedNestedMessageProxy>.addAll(values: kotlin.collections.Iterable<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage>) {
-      _builder.addAllRepeatedNestedMessage(values)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     * @param values The repeatedNestedMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedNestedMessage")
-    inline operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage, RepeatedNestedMessageProxy>.plusAssign(values: kotlin.collections.Iterable<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage>) {
-      addAll(values)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedNestedMessage to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedNestedMessage")
-    operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage, RepeatedNestedMessageProxy>.set(index: kotlin.Int, value: proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage) {
-      _builder.setRepeatedNestedMessage(index, value)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedNestedMessage")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage, RepeatedNestedMessageProxy>.clear() {
-      _builder.clearRepeatedNestedMessage()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedForeignMessageProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-     val repeatedForeignMessage: com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignMessage, RepeatedForeignMessageProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedForeignMessageList()
-      )
-    /**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     * @param value The repeatedForeignMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedForeignMessage")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignMessage, RepeatedForeignMessageProxy>.add(value: proto3_unittest.UnittestProto3.ForeignMessage) {
-      _builder.addRepeatedForeignMessage(value)
-    }/**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     * @param value The repeatedForeignMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedForeignMessage")
-    inline operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignMessage, RepeatedForeignMessageProxy>.plusAssign(value: proto3_unittest.UnittestProto3.ForeignMessage) {
-      add(value)
-    }/**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     * @param values The repeatedForeignMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedForeignMessage")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignMessage, RepeatedForeignMessageProxy>.addAll(values: kotlin.collections.Iterable<proto3_unittest.UnittestProto3.ForeignMessage>) {
-      _builder.addAllRepeatedForeignMessage(values)
-    }/**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     * @param values The repeatedForeignMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedForeignMessage")
-    inline operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignMessage, RepeatedForeignMessageProxy>.plusAssign(values: kotlin.collections.Iterable<proto3_unittest.UnittestProto3.ForeignMessage>) {
-      addAll(values)
-    }/**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedForeignMessage to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedForeignMessage")
-    operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignMessage, RepeatedForeignMessageProxy>.set(index: kotlin.Int, value: proto3_unittest.UnittestProto3.ForeignMessage) {
-      _builder.setRepeatedForeignMessage(index, value)
-    }/**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedForeignMessage")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignMessage, RepeatedForeignMessageProxy>.clear() {
-      _builder.clearRepeatedForeignMessage()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedImportMessageProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-     val repeatedImportMessage: com.google.protobuf.kotlin.DslList<com.google.protobuf.test.UnittestImport.ImportMessage, RepeatedImportMessageProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedImportMessageList()
-      )
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     * @param value The repeatedImportMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedImportMessage")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.test.UnittestImport.ImportMessage, RepeatedImportMessageProxy>.add(value: com.google.protobuf.test.UnittestImport.ImportMessage) {
-      _builder.addRepeatedImportMessage(value)
-    }/**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     * @param value The repeatedImportMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedImportMessage")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.test.UnittestImport.ImportMessage, RepeatedImportMessageProxy>.plusAssign(value: com.google.protobuf.test.UnittestImport.ImportMessage) {
-      add(value)
-    }/**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     * @param values The repeatedImportMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedImportMessage")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.test.UnittestImport.ImportMessage, RepeatedImportMessageProxy>.addAll(values: kotlin.collections.Iterable<com.google.protobuf.test.UnittestImport.ImportMessage>) {
-      _builder.addAllRepeatedImportMessage(values)
-    }/**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     * @param values The repeatedImportMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedImportMessage")
-    inline operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.test.UnittestImport.ImportMessage, RepeatedImportMessageProxy>.plusAssign(values: kotlin.collections.Iterable<com.google.protobuf.test.UnittestImport.ImportMessage>) {
-      addAll(values)
-    }/**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedImportMessage to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedImportMessage")
-    operator fun com.google.protobuf.kotlin.DslList<com.google.protobuf.test.UnittestImport.ImportMessage, RepeatedImportMessageProxy>.set(index: kotlin.Int, value: com.google.protobuf.test.UnittestImport.ImportMessage) {
-      _builder.setRepeatedImportMessage(index, value)
-    }/**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedImportMessage")
-    fun com.google.protobuf.kotlin.DslList<com.google.protobuf.test.UnittestImport.ImportMessage, RepeatedImportMessageProxy>.clear() {
-      _builder.clearRepeatedImportMessage()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedNestedEnumProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     */
-     val repeatedNestedEnum: com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum, RepeatedNestedEnumProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedNestedEnumList()
-      )
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param value The repeatedNestedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedNestedEnum")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum, RepeatedNestedEnumProxy>.add(value: proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum) {
-      _builder.addRepeatedNestedEnum(value)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param value The repeatedNestedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedNestedEnum")
-    inline operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum, RepeatedNestedEnumProxy>.plusAssign(value: proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum) {
-      add(value)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param values The repeatedNestedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedNestedEnum")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum, RepeatedNestedEnumProxy>.addAll(values: kotlin.collections.Iterable<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum>) {
-      _builder.addAllRepeatedNestedEnum(values)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param values The repeatedNestedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedNestedEnum")
-    inline operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum, RepeatedNestedEnumProxy>.plusAssign(values: kotlin.collections.Iterable<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum>) {
-      addAll(values)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedNestedEnum to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedNestedEnum")
-    operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum, RepeatedNestedEnumProxy>.set(index: kotlin.Int, value: proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum) {
-      _builder.setRepeatedNestedEnum(index, value)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedNestedEnum")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum, RepeatedNestedEnumProxy>.clear() {
-      _builder.clearRepeatedNestedEnum()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedForeignEnumProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     */
-     val repeatedForeignEnum: com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignEnum, RepeatedForeignEnumProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedForeignEnumList()
-      )
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param value The repeatedForeignEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedForeignEnum")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignEnum, RepeatedForeignEnumProxy>.add(value: proto3_unittest.UnittestProto3.ForeignEnum) {
-      _builder.addRepeatedForeignEnum(value)
-    }/**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param value The repeatedForeignEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedForeignEnum")
-    inline operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignEnum, RepeatedForeignEnumProxy>.plusAssign(value: proto3_unittest.UnittestProto3.ForeignEnum) {
-      add(value)
-    }/**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param values The repeatedForeignEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedForeignEnum")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignEnum, RepeatedForeignEnumProxy>.addAll(values: kotlin.collections.Iterable<proto3_unittest.UnittestProto3.ForeignEnum>) {
-      _builder.addAllRepeatedForeignEnum(values)
-    }/**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param values The repeatedForeignEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedForeignEnum")
-    inline operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignEnum, RepeatedForeignEnumProxy>.plusAssign(values: kotlin.collections.Iterable<proto3_unittest.UnittestProto3.ForeignEnum>) {
-      addAll(values)
-    }/**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedForeignEnum to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedForeignEnum")
-    operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignEnum, RepeatedForeignEnumProxy>.set(index: kotlin.Int, value: proto3_unittest.UnittestProto3.ForeignEnum) {
-      _builder.setRepeatedForeignEnum(index, value)
-    }/**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedForeignEnum")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignEnum, RepeatedForeignEnumProxy>.clear() {
-      _builder.clearRepeatedForeignEnum()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedStringPieceProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @return A list containing the repeatedStringPiece.
-     */
-    val repeatedStringPiece: com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringPieceProxy>
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedStringPieceList()
-      )
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param value The repeatedStringPiece to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedStringPiece")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringPieceProxy>.add(value: kotlin.String) {
-      _builder.addRepeatedStringPiece(value)
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param value The repeatedStringPiece to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedStringPiece")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringPieceProxy>.plusAssign(value: kotlin.String) {
-      add(value)
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param values The repeatedStringPiece to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedStringPiece")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringPieceProxy>.addAll(values: kotlin.collections.Iterable<kotlin.String>) {
-      _builder.addAllRepeatedStringPiece(values)
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param values The repeatedStringPiece to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedStringPiece")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringPieceProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.String>) {
-      addAll(values)
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedStringPiece to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedStringPiece")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringPieceProxy>.set(index: kotlin.Int, value: kotlin.String) {
-      _builder.setRepeatedStringPiece(index, value)
-    }/**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedStringPiece")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedStringPieceProxy>.clear() {
-      _builder.clearRepeatedStringPiece()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedCordProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @return A list containing the repeatedCord.
-     */
-    val repeatedCord: com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedCordProxy>
-      @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedCordList()
-      )
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param value The repeatedCord to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedCord")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedCordProxy>.add(value: kotlin.String) {
-      _builder.addRepeatedCord(value)
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param value The repeatedCord to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedCord")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedCordProxy>.plusAssign(value: kotlin.String) {
-      add(value)
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param values The repeatedCord to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedCord")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedCordProxy>.addAll(values: kotlin.collections.Iterable<kotlin.String>) {
-      _builder.addAllRepeatedCord(values)
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param values The repeatedCord to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedCord")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedCordProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.String>) {
-      addAll(values)
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedCord to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedCord")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedCordProxy>.set(index: kotlin.Int, value: kotlin.String) {
-      _builder.setRepeatedCord(index, value)
-    }/**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedCord")
-    fun com.google.protobuf.kotlin.DslList<kotlin.String, RepeatedCordProxy>.clear() {
-      _builder.clearRepeatedCord()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedLazyMessageProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-     val repeatedLazyMessage: com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage, RepeatedLazyMessageProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedLazyMessageList()
-      )
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     * @param value The repeatedLazyMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedLazyMessage")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage, RepeatedLazyMessageProxy>.add(value: proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage) {
-      _builder.addRepeatedLazyMessage(value)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     * @param value The repeatedLazyMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedLazyMessage")
-    inline operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage, RepeatedLazyMessageProxy>.plusAssign(value: proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage) {
-      add(value)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     * @param values The repeatedLazyMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedLazyMessage")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage, RepeatedLazyMessageProxy>.addAll(values: kotlin.collections.Iterable<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage>) {
-      _builder.addAllRepeatedLazyMessage(values)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     * @param values The repeatedLazyMessage to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedLazyMessage")
-    inline operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage, RepeatedLazyMessageProxy>.plusAssign(values: kotlin.collections.Iterable<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage>) {
-      addAll(values)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedLazyMessage to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedLazyMessage")
-    operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage, RepeatedLazyMessageProxy>.set(index: kotlin.Int, value: proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage) {
-      _builder.setRepeatedLazyMessage(index, value)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedLazyMessage")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage, RepeatedLazyMessageProxy>.clear() {
-      _builder.clearRepeatedLazyMessage()
-    }
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     */
-    var oneofUint32: kotlin.Int
-      @JvmName("getOneofUint32")
-      get() = _builder.getOneofUint32()
-      @JvmName("setOneofUint32")
-      set(value) {
-        _builder.setOneofUint32(value)
-      }
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     */
-    fun clearOneofUint32() {
-      _builder.clearOneofUint32()
-    }
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     * @return Whether the oneofUint32 field is set.
-     */
-    fun hasOneofUint32(): kotlin.Boolean {
-      return _builder.hasOneofUint32()
-    }
-
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-     */
-    var oneofNestedMessage: proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage
-      @JvmName("getOneofNestedMessage")
-      get() = _builder.getOneofNestedMessage()
-      @JvmName("setOneofNestedMessage")
-      set(value) {
-        _builder.setOneofNestedMessage(value)
-      }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-     */
-    fun clearOneofNestedMessage() {
-      _builder.clearOneofNestedMessage()
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-     * @return Whether the oneofNestedMessage field is set.
-     */
-    fun hasOneofNestedMessage(): kotlin.Boolean {
-      return _builder.hasOneofNestedMessage()
-    }
-
-    /**
-     * <code>string oneof_string = 113;</code>
-     */
-    var oneofString: kotlin.String
-      @JvmName("getOneofString")
-      get() = _builder.getOneofString()
-      @JvmName("setOneofString")
-      set(value) {
-        _builder.setOneofString(value)
-      }
-    /**
-     * <code>string oneof_string = 113;</code>
-     */
-    fun clearOneofString() {
-      _builder.clearOneofString()
-    }
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return Whether the oneofString field is set.
-     */
-    fun hasOneofString(): kotlin.Boolean {
-      return _builder.hasOneofString()
-    }
-
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     */
-    var oneofBytes: com.google.protobuf.ByteString
-      @JvmName("getOneofBytes")
-      get() = _builder.getOneofBytes()
-      @JvmName("setOneofBytes")
-      set(value) {
-        _builder.setOneofBytes(value)
-      }
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     */
-    fun clearOneofBytes() {
-      _builder.clearOneofBytes()
-    }
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     * @return Whether the oneofBytes field is set.
-     */
-    fun hasOneofBytes(): kotlin.Boolean {
-      return _builder.hasOneofBytes()
-    }
-    val oneofFieldCase: proto3_unittest.UnittestProto3.TestAllTypes.OneofFieldCase
-      @JvmName("getOneofFieldCase")
-      get() = _builder.getOneofFieldCase()
-
-    fun clearOneofField() {
-      _builder.clearOneofField()
-    }
-  }
-  @kotlin.jvm.JvmSynthetic
-  inline fun nestedMessage(block: proto3_unittest.TestAllTypesKt.NestedMessageKt.Dsl.() -> Unit): proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage =
-    proto3_unittest.TestAllTypesKt.NestedMessageKt.Dsl._create(proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.newBuilder()).apply { block() }._build()
-  object NestedMessageKt {
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    @com.google.protobuf.kotlin.ProtoDslMarker
-    class Dsl private constructor(
-      @kotlin.jvm.JvmField private val _builder: proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.Builder
-    ) {
-      companion object {
-        @kotlin.jvm.JvmSynthetic
-        @kotlin.PublishedApi
-        internal fun _create(builder: proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.Builder): Dsl = Dsl(builder)
-      }
-
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _build(): proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage = _builder.build()
-
-      /**
-       * <pre>
-       * The field name "b" fails to compile in proto1 because it conflicts with
-       * a local variable named "b" in one of the generated methods.  Doh.
-       * This file needs to compile in proto1 to test backwards-compatibility.
-       * </pre>
-       *
-       * <code>int32 bb = 1;</code>
-       */
-      var bb: kotlin.Int
-        @JvmName("getBb")
-        get() = _builder.getBb()
-        @JvmName("setBb")
-        set(value) {
-          _builder.setBb(value)
-        }
-      /**
-       * <pre>
-       * The field name "b" fails to compile in proto1 because it conflicts with
-       * a local variable named "b" in one of the generated methods.  Doh.
-       * This file needs to compile in proto1 to test backwards-compatibility.
-       * </pre>
-       *
-       * <code>int32 bb = 1;</code>
-       */
-      fun clearBb() {
-        _builder.clearBb()
-      }
-    }
-  }
-}
-inline fun proto3_unittest.UnittestProto3.TestAllTypes.copy(block: proto3_unittest.TestAllTypesKt.Dsl.() -> Unit): proto3_unittest.UnittestProto3.TestAllTypes =
-  proto3_unittest.TestAllTypesKt.Dsl._create(this.toBuilder()).apply { block() }._build()
-inline fun proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.copy(block: proto3_unittest.TestAllTypesKt.NestedMessageKt.Dsl.() -> Unit): proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage =
-  proto3_unittest.TestAllTypesKt.NestedMessageKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/TestEmptyMessageKt.kt b/java/kotlin-lite/target/generated-test-sources/proto3_unittest/TestEmptyMessageKt.kt
deleted file mode 100644
index af79690..0000000
--- a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/TestEmptyMessageKt.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_proto3.proto
-
-package proto3_unittest;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testEmptyMessage(block: proto3_unittest.TestEmptyMessageKt.Dsl.() -> Unit): proto3_unittest.UnittestProto3.TestEmptyMessage =
-  proto3_unittest.TestEmptyMessageKt.Dsl._create(proto3_unittest.UnittestProto3.TestEmptyMessage.newBuilder()).apply { block() }._build()
-object TestEmptyMessageKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: proto3_unittest.UnittestProto3.TestEmptyMessage.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: proto3_unittest.UnittestProto3.TestEmptyMessage.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): proto3_unittest.UnittestProto3.TestEmptyMessage = _builder.build()
-  }
-}
-inline fun proto3_unittest.UnittestProto3.TestEmptyMessage.copy(block: proto3_unittest.TestEmptyMessageKt.Dsl.() -> Unit): proto3_unittest.UnittestProto3.TestEmptyMessage =
-  proto3_unittest.TestEmptyMessageKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/TestMessageWithDummyKt.kt b/java/kotlin-lite/target/generated-test-sources/proto3_unittest/TestMessageWithDummyKt.kt
deleted file mode 100644
index eaafe6b..0000000
--- a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/TestMessageWithDummyKt.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_proto3.proto
-
-package proto3_unittest;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testMessageWithDummy(block: proto3_unittest.TestMessageWithDummyKt.Dsl.() -> Unit): proto3_unittest.UnittestProto3.TestMessageWithDummy =
-  proto3_unittest.TestMessageWithDummyKt.Dsl._create(proto3_unittest.UnittestProto3.TestMessageWithDummy.newBuilder()).apply { block() }._build()
-object TestMessageWithDummyKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: proto3_unittest.UnittestProto3.TestMessageWithDummy.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: proto3_unittest.UnittestProto3.TestMessageWithDummy.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): proto3_unittest.UnittestProto3.TestMessageWithDummy = _builder.build()
-
-    /**
-     * <pre>
-     * This field is only here for triggering copy-on-write; it's not intended to
-     * be serialized.
-     * </pre>
-     *
-     * <code>bool dummy = 536870911;</code>
-     */
-    var dummy: kotlin.Boolean
-      @JvmName("getDummy")
-      get() = _builder.getDummy()
-      @JvmName("setDummy")
-      set(value) {
-        _builder.setDummy(value)
-      }
-    /**
-     * <pre>
-     * This field is only here for triggering copy-on-write; it's not intended to
-     * be serialized.
-     * </pre>
-     *
-     * <code>bool dummy = 536870911;</code>
-     */
-    fun clearDummy() {
-      _builder.clearDummy()
-    }
-  }
-}
-inline fun proto3_unittest.UnittestProto3.TestMessageWithDummy.copy(block: proto3_unittest.TestMessageWithDummyKt.Dsl.() -> Unit): proto3_unittest.UnittestProto3.TestMessageWithDummy =
-  proto3_unittest.TestMessageWithDummyKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/TestOneof2Kt.kt b/java/kotlin-lite/target/generated-test-sources/proto3_unittest/TestOneof2Kt.kt
deleted file mode 100644
index 9cab650..0000000
--- a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/TestOneof2Kt.kt
+++ /dev/null
@@ -1,58 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_proto3.proto
-
-package proto3_unittest;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testOneof2(block: proto3_unittest.TestOneof2Kt.Dsl.() -> Unit): proto3_unittest.UnittestProto3.TestOneof2 =
-  proto3_unittest.TestOneof2Kt.Dsl._create(proto3_unittest.UnittestProto3.TestOneof2.newBuilder()).apply { block() }._build()
-object TestOneof2Kt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: proto3_unittest.UnittestProto3.TestOneof2.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: proto3_unittest.UnittestProto3.TestOneof2.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): proto3_unittest.UnittestProto3.TestOneof2 = _builder.build()
-
-    /**
-     * <code>.proto3_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-     */
-    var fooEnum: proto3_unittest.UnittestProto3.TestOneof2.NestedEnum
-      @JvmName("getFooEnum")
-      get() = _builder.getFooEnum()
-      @JvmName("setFooEnum")
-      set(value) {
-        _builder.setFooEnum(value)
-      }
-    /**
-     * <code>.proto3_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-     */
-    fun clearFooEnum() {
-      _builder.clearFooEnum()
-    }
-    /**
-     * <code>.proto3_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-     * @return Whether the fooEnum field is set.
-     */
-    fun hasFooEnum(): kotlin.Boolean {
-      return _builder.hasFooEnum()
-    }
-    val fooCase: proto3_unittest.UnittestProto3.TestOneof2.FooCase
-      @JvmName("getFooCase")
-      get() = _builder.getFooCase()
-
-    fun clearFoo() {
-      _builder.clearFoo()
-    }
-  }
-}
-inline fun proto3_unittest.UnittestProto3.TestOneof2.copy(block: proto3_unittest.TestOneof2Kt.Dsl.() -> Unit): proto3_unittest.UnittestProto3.TestOneof2 =
-  proto3_unittest.TestOneof2Kt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/TestPackedTypesKt.kt b/java/kotlin-lite/target/generated-test-sources/proto3_unittest/TestPackedTypesKt.kt
deleted file mode 100644
index 436ac68..0000000
--- a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/TestPackedTypesKt.kt
+++ /dev/null
@@ -1,909 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_proto3.proto
-
-package proto3_unittest;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testPackedTypes(block: proto3_unittest.TestPackedTypesKt.Dsl.() -> Unit): proto3_unittest.UnittestProto3.TestPackedTypes =
-  proto3_unittest.TestPackedTypesKt.Dsl._create(proto3_unittest.UnittestProto3.TestPackedTypes.newBuilder()).apply { block() }._build()
-object TestPackedTypesKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: proto3_unittest.UnittestProto3.TestPackedTypes.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: proto3_unittest.UnittestProto3.TestPackedTypes.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): proto3_unittest.UnittestProto3.TestPackedTypes = _builder.build()
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedInt32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     */
-     val packedInt32: com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedInt32List()
-      )
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param value The packedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>.add(value: kotlin.Int) {
-      _builder.addPackedInt32(value)
-    }/**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param value The packedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedInt32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param values The packedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllPackedInt32(values)
-    }/**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param values The packedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedInt32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedInt32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedInt32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setPackedInt32(index, value)
-    }/**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedInt32Proxy>.clear() {
-      _builder.clearPackedInt32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedInt64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     */
-     val packedInt64: com.google.protobuf.kotlin.DslList<kotlin.Long, PackedInt64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedInt64List()
-      )
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param value The packedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedInt64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedInt64Proxy>.add(value: kotlin.Long) {
-      _builder.addPackedInt64(value)
-    }/**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param value The packedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedInt64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedInt64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param values The packedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedInt64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedInt64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllPackedInt64(values)
-    }/**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param values The packedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedInt64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedInt64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedInt64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedInt64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedInt64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setPackedInt64(index, value)
-    }/**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedInt64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedInt64Proxy>.clear() {
-      _builder.clearPackedInt64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedUint32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     */
-     val packedUint32: com.google.protobuf.kotlin.DslList<kotlin.Int, PackedUint32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedUint32List()
-      )
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param value The packedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedUint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedUint32Proxy>.add(value: kotlin.Int) {
-      _builder.addPackedUint32(value)
-    }/**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param value The packedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedUint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedUint32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param values The packedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedUint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedUint32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllPackedUint32(values)
-    }/**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param values The packedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedUint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedUint32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedUint32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedUint32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedUint32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setPackedUint32(index, value)
-    }/**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedUint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedUint32Proxy>.clear() {
-      _builder.clearPackedUint32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedUint64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     */
-     val packedUint64: com.google.protobuf.kotlin.DslList<kotlin.Long, PackedUint64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedUint64List()
-      )
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param value The packedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedUint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedUint64Proxy>.add(value: kotlin.Long) {
-      _builder.addPackedUint64(value)
-    }/**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param value The packedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedUint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedUint64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param values The packedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedUint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedUint64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllPackedUint64(values)
-    }/**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param values The packedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedUint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedUint64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedUint64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedUint64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedUint64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setPackedUint64(index, value)
-    }/**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedUint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedUint64Proxy>.clear() {
-      _builder.clearPackedUint64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedSint32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     */
-     val packedSint32: com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSint32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedSint32List()
-      )
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param value The packedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedSint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSint32Proxy>.add(value: kotlin.Int) {
-      _builder.addPackedSint32(value)
-    }/**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param value The packedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedSint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSint32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param values The packedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedSint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSint32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllPackedSint32(values)
-    }/**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param values The packedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedSint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSint32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSint32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedSint32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSint32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setPackedSint32(index, value)
-    }/**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedSint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSint32Proxy>.clear() {
-      _builder.clearPackedSint32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedSint64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     */
-     val packedSint64: com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSint64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedSint64List()
-      )
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param value The packedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedSint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSint64Proxy>.add(value: kotlin.Long) {
-      _builder.addPackedSint64(value)
-    }/**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param value The packedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedSint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSint64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param values The packedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedSint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSint64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllPackedSint64(values)
-    }/**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param values The packedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedSint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSint64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSint64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedSint64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSint64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setPackedSint64(index, value)
-    }/**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedSint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSint64Proxy>.clear() {
-      _builder.clearPackedSint64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedFixed32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     */
-     val packedFixed32: com.google.protobuf.kotlin.DslList<kotlin.Int, PackedFixed32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedFixed32List()
-      )
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param value The packedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedFixed32Proxy>.add(value: kotlin.Int) {
-      _builder.addPackedFixed32(value)
-    }/**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param value The packedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedFixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedFixed32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param values The packedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedFixed32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllPackedFixed32(values)
-    }/**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param values The packedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedFixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedFixed32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedFixed32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedFixed32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedFixed32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setPackedFixed32(index, value)
-    }/**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedFixed32Proxy>.clear() {
-      _builder.clearPackedFixed32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedFixed64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     */
-     val packedFixed64: com.google.protobuf.kotlin.DslList<kotlin.Long, PackedFixed64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedFixed64List()
-      )
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param value The packedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedFixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedFixed64Proxy>.add(value: kotlin.Long) {
-      _builder.addPackedFixed64(value)
-    }/**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param value The packedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedFixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedFixed64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param values The packedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedFixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedFixed64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllPackedFixed64(values)
-    }/**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param values The packedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedFixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedFixed64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedFixed64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedFixed64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedFixed64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setPackedFixed64(index, value)
-    }/**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedFixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedFixed64Proxy>.clear() {
-      _builder.clearPackedFixed64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedSfixed32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     */
-     val packedSfixed32: com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSfixed32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedSfixed32List()
-      )
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param value The packedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedSfixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSfixed32Proxy>.add(value: kotlin.Int) {
-      _builder.addPackedSfixed32(value)
-    }/**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param value The packedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedSfixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSfixed32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param values The packedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedSfixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSfixed32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllPackedSfixed32(values)
-    }/**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param values The packedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedSfixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSfixed32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSfixed32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedSfixed32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSfixed32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setPackedSfixed32(index, value)
-    }/**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedSfixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, PackedSfixed32Proxy>.clear() {
-      _builder.clearPackedSfixed32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedSfixed64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     */
-     val packedSfixed64: com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSfixed64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedSfixed64List()
-      )
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param value The packedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedSfixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSfixed64Proxy>.add(value: kotlin.Long) {
-      _builder.addPackedSfixed64(value)
-    }/**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param value The packedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedSfixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSfixed64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param values The packedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedSfixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSfixed64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllPackedSfixed64(values)
-    }/**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param values The packedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedSfixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSfixed64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSfixed64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedSfixed64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSfixed64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setPackedSfixed64(index, value)
-    }/**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedSfixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, PackedSfixed64Proxy>.clear() {
-      _builder.clearPackedSfixed64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedFloatProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     */
-     val packedFloat: com.google.protobuf.kotlin.DslList<kotlin.Float, PackedFloatProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedFloatList()
-      )
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param value The packedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedFloat")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Float, PackedFloatProxy>.add(value: kotlin.Float) {
-      _builder.addPackedFloat(value)
-    }/**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param value The packedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedFloat")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Float, PackedFloatProxy>.plusAssign(value: kotlin.Float) {
-      add(value)
-    }/**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param values The packedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedFloat")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Float, PackedFloatProxy>.addAll(values: kotlin.collections.Iterable<kotlin.Float>) {
-      _builder.addAllPackedFloat(values)
-    }/**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param values The packedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedFloat")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Float, PackedFloatProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Float>) {
-      addAll(values)
-    }/**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedFloat to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedFloat")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Float, PackedFloatProxy>.set(index: kotlin.Int, value: kotlin.Float) {
-      _builder.setPackedFloat(index, value)
-    }/**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedFloat")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Float, PackedFloatProxy>.clear() {
-      _builder.clearPackedFloat()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedDoubleProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     */
-     val packedDouble: com.google.protobuf.kotlin.DslList<kotlin.Double, PackedDoubleProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedDoubleList()
-      )
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param value The packedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedDouble")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Double, PackedDoubleProxy>.add(value: kotlin.Double) {
-      _builder.addPackedDouble(value)
-    }/**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param value The packedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedDouble")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Double, PackedDoubleProxy>.plusAssign(value: kotlin.Double) {
-      add(value)
-    }/**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param values The packedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedDouble")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Double, PackedDoubleProxy>.addAll(values: kotlin.collections.Iterable<kotlin.Double>) {
-      _builder.addAllPackedDouble(values)
-    }/**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param values The packedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedDouble")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Double, PackedDoubleProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Double>) {
-      addAll(values)
-    }/**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedDouble to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedDouble")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Double, PackedDoubleProxy>.set(index: kotlin.Int, value: kotlin.Double) {
-      _builder.setPackedDouble(index, value)
-    }/**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedDouble")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Double, PackedDoubleProxy>.clear() {
-      _builder.clearPackedDouble()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedBoolProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     */
-     val packedBool: com.google.protobuf.kotlin.DslList<kotlin.Boolean, PackedBoolProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedBoolList()
-      )
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param value The packedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedBool")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, PackedBoolProxy>.add(value: kotlin.Boolean) {
-      _builder.addPackedBool(value)
-    }/**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param value The packedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedBool")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, PackedBoolProxy>.plusAssign(value: kotlin.Boolean) {
-      add(value)
-    }/**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param values The packedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedBool")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, PackedBoolProxy>.addAll(values: kotlin.collections.Iterable<kotlin.Boolean>) {
-      _builder.addAllPackedBool(values)
-    }/**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param values The packedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedBool")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, PackedBoolProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Boolean>) {
-      addAll(values)
-    }/**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedBool to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedBool")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, PackedBoolProxy>.set(index: kotlin.Int, value: kotlin.Boolean) {
-      _builder.setPackedBool(index, value)
-    }/**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedBool")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, PackedBoolProxy>.clear() {
-      _builder.clearPackedBool()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class PackedEnumProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     */
-     val packedEnum: com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignEnum, PackedEnumProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getPackedEnumList()
-      )
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param value The packedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addPackedEnum")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignEnum, PackedEnumProxy>.add(value: proto3_unittest.UnittestProto3.ForeignEnum) {
-      _builder.addPackedEnum(value)
-    }/**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param value The packedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignPackedEnum")
-    inline operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignEnum, PackedEnumProxy>.plusAssign(value: proto3_unittest.UnittestProto3.ForeignEnum) {
-      add(value)
-    }/**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param values The packedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllPackedEnum")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignEnum, PackedEnumProxy>.addAll(values: kotlin.collections.Iterable<proto3_unittest.UnittestProto3.ForeignEnum>) {
-      _builder.addAllPackedEnum(values)
-    }/**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param values The packedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllPackedEnum")
-    inline operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignEnum, PackedEnumProxy>.plusAssign(values: kotlin.collections.Iterable<proto3_unittest.UnittestProto3.ForeignEnum>) {
-      addAll(values)
-    }/**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedEnum to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setPackedEnum")
-    operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignEnum, PackedEnumProxy>.set(index: kotlin.Int, value: proto3_unittest.UnittestProto3.ForeignEnum) {
-      _builder.setPackedEnum(index, value)
-    }/**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearPackedEnum")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.ForeignEnum, PackedEnumProxy>.clear() {
-      _builder.clearPackedEnum()
-    }}
-}
-inline fun proto3_unittest.UnittestProto3.TestPackedTypes.copy(block: proto3_unittest.TestPackedTypesKt.Dsl.() -> Unit): proto3_unittest.UnittestProto3.TestPackedTypes =
-  proto3_unittest.TestPackedTypesKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/TestUnpackedTypesKt.kt b/java/kotlin-lite/target/generated-test-sources/proto3_unittest/TestUnpackedTypesKt.kt
deleted file mode 100644
index da0c122..0000000
--- a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/TestUnpackedTypesKt.kt
+++ /dev/null
@@ -1,909 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/unittest_proto3.proto
-
-package proto3_unittest;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testUnpackedTypes(block: proto3_unittest.TestUnpackedTypesKt.Dsl.() -> Unit): proto3_unittest.UnittestProto3.TestUnpackedTypes =
-  proto3_unittest.TestUnpackedTypesKt.Dsl._create(proto3_unittest.UnittestProto3.TestUnpackedTypes.newBuilder()).apply { block() }._build()
-object TestUnpackedTypesKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: proto3_unittest.UnittestProto3.TestUnpackedTypes.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: proto3_unittest.UnittestProto3.TestUnpackedTypes.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): proto3_unittest.UnittestProto3.TestUnpackedTypes = _builder.build()
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedInt32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-     */
-     val repeatedInt32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedInt32List()
-      )
-    /**
-     * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-     * @param value The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedInt32(value)
-    }/**
-     * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-     * @param value The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedInt32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-     * @param values The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedInt32(values)
-    }/**
-     * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-     * @param values The repeatedInt32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedInt32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedInt32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedInt32(index, value)
-    }/**
-     * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedInt32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedInt32Proxy>.clear() {
-      _builder.clearRepeatedInt32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedInt64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-     */
-     val repeatedInt64: com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedInt64List()
-      )
-    /**
-     * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-     * @param value The repeatedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedInt64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>.add(value: kotlin.Long) {
-      _builder.addRepeatedInt64(value)
-    }/**
-     * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-     * @param value The repeatedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedInt64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-     * @param values The repeatedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedInt64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllRepeatedInt64(values)
-    }/**
-     * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-     * @param values The repeatedInt64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedInt64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedInt64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setRepeatedInt64(index, value)
-    }/**
-     * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedInt64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedInt64Proxy>.clear() {
-      _builder.clearRepeatedInt64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedUint32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-     */
-     val repeatedUint32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedUint32List()
-      )
-    /**
-     * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-     * @param value The repeatedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedUint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedUint32(value)
-    }/**
-     * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-     * @param value The repeatedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedUint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-     * @param values The repeatedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedUint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedUint32(values)
-    }/**
-     * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-     * @param values The repeatedUint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedUint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedUint32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedUint32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedUint32(index, value)
-    }/**
-     * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedUint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedUint32Proxy>.clear() {
-      _builder.clearRepeatedUint32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedUint64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-     */
-     val repeatedUint64: com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedUint64List()
-      )
-    /**
-     * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-     * @param value The repeatedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedUint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>.add(value: kotlin.Long) {
-      _builder.addRepeatedUint64(value)
-    }/**
-     * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-     * @param value The repeatedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedUint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-     * @param values The repeatedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedUint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllRepeatedUint64(values)
-    }/**
-     * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-     * @param values The repeatedUint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedUint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedUint64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedUint64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setRepeatedUint64(index, value)
-    }/**
-     * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedUint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedUint64Proxy>.clear() {
-      _builder.clearRepeatedUint64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedSint32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-     */
-     val repeatedSint32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedSint32List()
-      )
-    /**
-     * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-     * @param value The repeatedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedSint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedSint32(value)
-    }/**
-     * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-     * @param value The repeatedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedSint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-     * @param values The repeatedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedSint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedSint32(values)
-    }/**
-     * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-     * @param values The repeatedSint32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedSint32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSint32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedSint32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedSint32(index, value)
-    }/**
-     * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedSint32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSint32Proxy>.clear() {
-      _builder.clearRepeatedSint32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedSint64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-     */
-     val repeatedSint64: com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedSint64List()
-      )
-    /**
-     * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-     * @param value The repeatedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedSint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>.add(value: kotlin.Long) {
-      _builder.addRepeatedSint64(value)
-    }/**
-     * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-     * @param value The repeatedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedSint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-     * @param values The repeatedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedSint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllRepeatedSint64(values)
-    }/**
-     * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-     * @param values The repeatedSint64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedSint64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSint64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedSint64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setRepeatedSint64(index, value)
-    }/**
-     * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedSint64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSint64Proxy>.clear() {
-      _builder.clearRepeatedSint64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedFixed32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-     */
-     val repeatedFixed32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedFixed32List()
-      )
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-     * @param value The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedFixed32(value)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-     * @param value The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedFixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-     * @param values The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedFixed32(values)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-     * @param values The repeatedFixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedFixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedFixed32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedFixed32(index, value)
-    }/**
-     * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedFixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedFixed32Proxy>.clear() {
-      _builder.clearRepeatedFixed32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedFixed64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-     */
-     val repeatedFixed64: com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedFixed64List()
-      )
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-     * @param value The repeatedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedFixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>.add(value: kotlin.Long) {
-      _builder.addRepeatedFixed64(value)
-    }/**
-     * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-     * @param value The repeatedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedFixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-     * @param values The repeatedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedFixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllRepeatedFixed64(values)
-    }/**
-     * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-     * @param values The repeatedFixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedFixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedFixed64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setRepeatedFixed64(index, value)
-    }/**
-     * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedFixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedFixed64Proxy>.clear() {
-      _builder.clearRepeatedFixed64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedSfixed32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-     */
-     val repeatedSfixed32: com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedSfixed32List()
-      )
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-     * @param value The repeatedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedSfixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>.add(value: kotlin.Int) {
-      _builder.addRepeatedSfixed32(value)
-    }/**
-     * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-     * @param value The repeatedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedSfixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>.plusAssign(value: kotlin.Int) {
-      add(value)
-    }/**
-     * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-     * @param values The repeatedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedSfixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Int>) {
-      _builder.addAllRepeatedSfixed32(values)
-    }/**
-     * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-     * @param values The repeatedSfixed32 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedSfixed32")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Int>) {
-      addAll(values)
-    }/**
-     * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSfixed32 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedSfixed32")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>.set(index: kotlin.Int, value: kotlin.Int) {
-      _builder.setRepeatedSfixed32(index, value)
-    }/**
-     * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedSfixed32")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Int, RepeatedSfixed32Proxy>.clear() {
-      _builder.clearRepeatedSfixed32()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedSfixed64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-     */
-     val repeatedSfixed64: com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedSfixed64List()
-      )
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-     * @param value The repeatedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedSfixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>.add(value: kotlin.Long) {
-      _builder.addRepeatedSfixed64(value)
-    }/**
-     * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-     * @param value The repeatedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedSfixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>.plusAssign(value: kotlin.Long) {
-      add(value)
-    }/**
-     * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-     * @param values The repeatedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedSfixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>.addAll(values: kotlin.collections.Iterable<kotlin.Long>) {
-      _builder.addAllRepeatedSfixed64(values)
-    }/**
-     * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-     * @param values The repeatedSfixed64 to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedSfixed64")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Long>) {
-      addAll(values)
-    }/**
-     * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSfixed64 to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedSfixed64")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>.set(index: kotlin.Int, value: kotlin.Long) {
-      _builder.setRepeatedSfixed64(index, value)
-    }/**
-     * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedSfixed64")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Long, RepeatedSfixed64Proxy>.clear() {
-      _builder.clearRepeatedSfixed64()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedFloatProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated float repeated_float = 11 [packed = false];</code>
-     */
-     val repeatedFloat: com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedFloatList()
-      )
-    /**
-     * <code>repeated float repeated_float = 11 [packed = false];</code>
-     * @param value The repeatedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedFloat")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>.add(value: kotlin.Float) {
-      _builder.addRepeatedFloat(value)
-    }/**
-     * <code>repeated float repeated_float = 11 [packed = false];</code>
-     * @param value The repeatedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedFloat")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>.plusAssign(value: kotlin.Float) {
-      add(value)
-    }/**
-     * <code>repeated float repeated_float = 11 [packed = false];</code>
-     * @param values The repeatedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedFloat")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>.addAll(values: kotlin.collections.Iterable<kotlin.Float>) {
-      _builder.addAllRepeatedFloat(values)
-    }/**
-     * <code>repeated float repeated_float = 11 [packed = false];</code>
-     * @param values The repeatedFloat to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedFloat")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Float>) {
-      addAll(values)
-    }/**
-     * <code>repeated float repeated_float = 11 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFloat to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedFloat")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>.set(index: kotlin.Int, value: kotlin.Float) {
-      _builder.setRepeatedFloat(index, value)
-    }/**
-     * <code>repeated float repeated_float = 11 [packed = false];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedFloat")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Float, RepeatedFloatProxy>.clear() {
-      _builder.clearRepeatedFloat()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedDoubleProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated double repeated_double = 12 [packed = false];</code>
-     */
-     val repeatedDouble: com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedDoubleList()
-      )
-    /**
-     * <code>repeated double repeated_double = 12 [packed = false];</code>
-     * @param value The repeatedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedDouble")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>.add(value: kotlin.Double) {
-      _builder.addRepeatedDouble(value)
-    }/**
-     * <code>repeated double repeated_double = 12 [packed = false];</code>
-     * @param value The repeatedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedDouble")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>.plusAssign(value: kotlin.Double) {
-      add(value)
-    }/**
-     * <code>repeated double repeated_double = 12 [packed = false];</code>
-     * @param values The repeatedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedDouble")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>.addAll(values: kotlin.collections.Iterable<kotlin.Double>) {
-      _builder.addAllRepeatedDouble(values)
-    }/**
-     * <code>repeated double repeated_double = 12 [packed = false];</code>
-     * @param values The repeatedDouble to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedDouble")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Double>) {
-      addAll(values)
-    }/**
-     * <code>repeated double repeated_double = 12 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedDouble to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedDouble")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>.set(index: kotlin.Int, value: kotlin.Double) {
-      _builder.setRepeatedDouble(index, value)
-    }/**
-     * <code>repeated double repeated_double = 12 [packed = false];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedDouble")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Double, RepeatedDoubleProxy>.clear() {
-      _builder.clearRepeatedDouble()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedBoolProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-     */
-     val repeatedBool: com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedBoolList()
-      )
-    /**
-     * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-     * @param value The repeatedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedBool")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>.add(value: kotlin.Boolean) {
-      _builder.addRepeatedBool(value)
-    }/**
-     * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-     * @param value The repeatedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedBool")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>.plusAssign(value: kotlin.Boolean) {
-      add(value)
-    }/**
-     * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-     * @param values The repeatedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedBool")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>.addAll(values: kotlin.collections.Iterable<kotlin.Boolean>) {
-      _builder.addAllRepeatedBool(values)
-    }/**
-     * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-     * @param values The repeatedBool to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedBool")
-    inline operator fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>.plusAssign(values: kotlin.collections.Iterable<kotlin.Boolean>) {
-      addAll(values)
-    }/**
-     * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedBool to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedBool")
-    operator fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>.set(index: kotlin.Int, value: kotlin.Boolean) {
-      _builder.setRepeatedBool(index, value)
-    }/**
-     * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedBool")
-    fun com.google.protobuf.kotlin.DslList<kotlin.Boolean, RepeatedBoolProxy>.clear() {
-      _builder.clearRepeatedBool()
-    }
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class RepeatedNestedEnumProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     */
-     val repeatedNestedEnum: com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum, RepeatedNestedEnumProxy>
-      @kotlin.jvm.JvmSynthetic
-      get() = com.google.protobuf.kotlin.DslList(
-        _builder.getRepeatedNestedEnumList()
-      )
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @param value The repeatedNestedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addRepeatedNestedEnum")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum, RepeatedNestedEnumProxy>.add(value: proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum) {
-      _builder.addRepeatedNestedEnum(value)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @param value The repeatedNestedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignRepeatedNestedEnum")
-    inline operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum, RepeatedNestedEnumProxy>.plusAssign(value: proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum) {
-      add(value)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @param values The repeatedNestedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("addAllRepeatedNestedEnum")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum, RepeatedNestedEnumProxy>.addAll(values: kotlin.collections.Iterable<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum>) {
-      _builder.addAllRepeatedNestedEnum(values)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @param values The repeatedNestedEnum to add.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("plusAssignAllRepeatedNestedEnum")
-    inline operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum, RepeatedNestedEnumProxy>.plusAssign(values: kotlin.collections.Iterable<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum>) {
-      addAll(values)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedNestedEnum to set.
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("setRepeatedNestedEnum")
-    operator fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum, RepeatedNestedEnumProxy>.set(index: kotlin.Int, value: proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum) {
-      _builder.setRepeatedNestedEnum(index, value)
-    }/**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.jvm.JvmName("clearRepeatedNestedEnum")
-    fun com.google.protobuf.kotlin.DslList<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum, RepeatedNestedEnumProxy>.clear() {
-      _builder.clearRepeatedNestedEnum()
-    }}
-}
-inline fun proto3_unittest.UnittestProto3.TestUnpackedTypes.copy(block: proto3_unittest.TestUnpackedTypesKt.Dsl.() -> Unit): proto3_unittest.UnittestProto3.TestUnpackedTypes =
-  proto3_unittest.TestUnpackedTypesKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/UnittestProto3.java b/java/kotlin-lite/target/generated-test-sources/proto3_unittest/UnittestProto3.java
deleted file mode 100644
index d4dda39..0000000
--- a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/UnittestProto3.java
+++ /dev/null
@@ -1,14313 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/unittest_proto3.proto
-
-package proto3_unittest;
-
-public final class UnittestProto3 {
-  private UnittestProto3() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-  /**
-   * Protobuf enum {@code proto3_unittest.ForeignEnum}
-   */
-  public enum ForeignEnum
-      implements com.google.protobuf.Internal.EnumLite {
-    /**
-     * <code>FOREIGN_ZERO = 0;</code>
-     */
-    FOREIGN_ZERO(0),
-    /**
-     * <code>FOREIGN_FOO = 4;</code>
-     */
-    FOREIGN_FOO(4),
-    /**
-     * <code>FOREIGN_BAR = 5;</code>
-     */
-    FOREIGN_BAR(5),
-    /**
-     * <code>FOREIGN_BAZ = 6;</code>
-     */
-    FOREIGN_BAZ(6),
-    UNRECOGNIZED(-1),
-    ;
-
-    /**
-     * <code>FOREIGN_ZERO = 0;</code>
-     */
-    public static final int FOREIGN_ZERO_VALUE = 0;
-    /**
-     * <code>FOREIGN_FOO = 4;</code>
-     */
-    public static final int FOREIGN_FOO_VALUE = 4;
-    /**
-     * <code>FOREIGN_BAR = 5;</code>
-     */
-    public static final int FOREIGN_BAR_VALUE = 5;
-    /**
-     * <code>FOREIGN_BAZ = 6;</code>
-     */
-    public static final int FOREIGN_BAZ_VALUE = 6;
-
-
-    @java.lang.Override
-    public final int getNumber() {
-      if (this == UNRECOGNIZED) {
-        throw new java.lang.IllegalArgumentException(
-            "Can't get the number of an unknown enum value.");
-      }
-      return value;
-    }
-
-    /**
-     * @param value The number of the enum to look for.
-     * @return The enum associated with the given number.
-     * @deprecated Use {@link #forNumber(int)} instead.
-     */
-    @java.lang.Deprecated
-    public static ForeignEnum valueOf(int value) {
-      return forNumber(value);
-    }
-
-    public static ForeignEnum forNumber(int value) {
-      switch (value) {
-        case 0: return FOREIGN_ZERO;
-        case 4: return FOREIGN_FOO;
-        case 5: return FOREIGN_BAR;
-        case 6: return FOREIGN_BAZ;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<ForeignEnum>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        ForeignEnum> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<ForeignEnum>() {
-            @java.lang.Override
-            public ForeignEnum findValueByNumber(int number) {
-              return ForeignEnum.forNumber(number);
-            }
-          };
-
-    public static com.google.protobuf.Internal.EnumVerifier 
-        internalGetVerifier() {
-      return ForeignEnumVerifier.INSTANCE;
-    }
-
-    private static final class ForeignEnumVerifier implements 
-         com.google.protobuf.Internal.EnumVerifier { 
-            static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new ForeignEnumVerifier();
-            @java.lang.Override
-            public boolean isInRange(int number) {
-              return ForeignEnum.forNumber(number) != null;
-            }
-          };
-
-    private final int value;
-
-    private ForeignEnum(int value) {
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:proto3_unittest.ForeignEnum)
-  }
-
-  public interface TestAllTypesOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:proto3_unittest.TestAllTypes)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>int32 optional_int32 = 1;</code>
-     * @return The optionalInt32.
-     */
-    int getOptionalInt32();
-
-    /**
-     * <code>int64 optional_int64 = 2;</code>
-     * @return The optionalInt64.
-     */
-    long getOptionalInt64();
-
-    /**
-     * <code>uint32 optional_uint32 = 3;</code>
-     * @return The optionalUint32.
-     */
-    int getOptionalUint32();
-
-    /**
-     * <code>uint64 optional_uint64 = 4;</code>
-     * @return The optionalUint64.
-     */
-    long getOptionalUint64();
-
-    /**
-     * <code>sint32 optional_sint32 = 5;</code>
-     * @return The optionalSint32.
-     */
-    int getOptionalSint32();
-
-    /**
-     * <code>sint64 optional_sint64 = 6;</code>
-     * @return The optionalSint64.
-     */
-    long getOptionalSint64();
-
-    /**
-     * <code>fixed32 optional_fixed32 = 7;</code>
-     * @return The optionalFixed32.
-     */
-    int getOptionalFixed32();
-
-    /**
-     * <code>fixed64 optional_fixed64 = 8;</code>
-     * @return The optionalFixed64.
-     */
-    long getOptionalFixed64();
-
-    /**
-     * <code>sfixed32 optional_sfixed32 = 9;</code>
-     * @return The optionalSfixed32.
-     */
-    int getOptionalSfixed32();
-
-    /**
-     * <code>sfixed64 optional_sfixed64 = 10;</code>
-     * @return The optionalSfixed64.
-     */
-    long getOptionalSfixed64();
-
-    /**
-     * <code>float optional_float = 11;</code>
-     * @return The optionalFloat.
-     */
-    float getOptionalFloat();
-
-    /**
-     * <code>double optional_double = 12;</code>
-     * @return The optionalDouble.
-     */
-    double getOptionalDouble();
-
-    /**
-     * <code>bool optional_bool = 13;</code>
-     * @return The optionalBool.
-     */
-    boolean getOptionalBool();
-
-    /**
-     * <code>string optional_string = 14;</code>
-     * @return The optionalString.
-     */
-    java.lang.String getOptionalString();
-    /**
-     * <code>string optional_string = 14;</code>
-     * @return The bytes for optionalString.
-     */
-    com.google.protobuf.ByteString
-        getOptionalStringBytes();
-
-    /**
-     * <code>bytes optional_bytes = 15;</code>
-     * @return The optionalBytes.
-     */
-    com.google.protobuf.ByteString getOptionalBytes();
-
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-     * @return Whether the optionalNestedMessage field is set.
-     */
-    boolean hasOptionalNestedMessage();
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-     * @return The optionalNestedMessage.
-     */
-    proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage getOptionalNestedMessage();
-
-    /**
-     * <code>.proto3_unittest.ForeignMessage optional_foreign_message = 19;</code>
-     * @return Whether the optionalForeignMessage field is set.
-     */
-    boolean hasOptionalForeignMessage();
-    /**
-     * <code>.proto3_unittest.ForeignMessage optional_foreign_message = 19;</code>
-     * @return The optionalForeignMessage.
-     */
-    proto3_unittest.UnittestProto3.ForeignMessage getOptionalForeignMessage();
-
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-     * @return Whether the optionalImportMessage field is set.
-     */
-    boolean hasOptionalImportMessage();
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-     * @return The optionalImportMessage.
-     */
-    com.google.protobuf.test.UnittestImport.ImportMessage getOptionalImportMessage();
-
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-     * @return The enum numeric value on the wire for optionalNestedEnum.
-     */
-    int getOptionalNestedEnumValue();
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-     * @return The optionalNestedEnum.
-     */
-    proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum getOptionalNestedEnum();
-
-    /**
-     * <code>.proto3_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     * @return The enum numeric value on the wire for optionalForeignEnum.
-     */
-    int getOptionalForeignEnumValue();
-    /**
-     * <code>.proto3_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     * @return The optionalForeignEnum.
-     */
-    proto3_unittest.UnittestProto3.ForeignEnum getOptionalForeignEnum();
-
-    /**
-     * <code>string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @return The optionalStringPiece.
-     */
-    java.lang.String getOptionalStringPiece();
-    /**
-     * <code>string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @return The bytes for optionalStringPiece.
-     */
-    com.google.protobuf.ByteString
-        getOptionalStringPieceBytes();
-
-    /**
-     * <code>string optional_cord = 25 [ctype = CORD];</code>
-     * @return The optionalCord.
-     */
-    java.lang.String getOptionalCord();
-    /**
-     * <code>string optional_cord = 25 [ctype = CORD];</code>
-     * @return The bytes for optionalCord.
-     */
-    com.google.protobuf.ByteString
-        getOptionalCordBytes();
-
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>.protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-     * @return Whether the optionalPublicImportMessage field is set.
-     */
-    boolean hasOptionalPublicImportMessage();
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>.protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-     * @return The optionalPublicImportMessage.
-     */
-    com.google.protobuf.test.UnittestImportPublic.PublicImportMessage getOptionalPublicImportMessage();
-
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     * @return Whether the optionalLazyMessage field is set.
-     */
-    boolean hasOptionalLazyMessage();
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     * @return The optionalLazyMessage.
-     */
-    proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage getOptionalLazyMessage();
-
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115 [lazy = true];</code>
-     * @return Whether the optionalLazyImportMessage field is set.
-     */
-    boolean hasOptionalLazyImportMessage();
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115 [lazy = true];</code>
-     * @return The optionalLazyImportMessage.
-     */
-    com.google.protobuf.test.UnittestImport.ImportMessage getOptionalLazyImportMessage();
-
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @return A list containing the repeatedInt32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedInt32List();
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @return The count of repeatedInt32.
-     */
-    int getRepeatedInt32Count();
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt32 at the given index.
-     */
-    int getRepeatedInt32(int index);
-
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @return A list containing the repeatedInt64.
-     */
-    java.util.List<java.lang.Long> getRepeatedInt64List();
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @return The count of repeatedInt64.
-     */
-    int getRepeatedInt64Count();
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt64 at the given index.
-     */
-    long getRepeatedInt64(int index);
-
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @return A list containing the repeatedUint32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedUint32List();
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @return The count of repeatedUint32.
-     */
-    int getRepeatedUint32Count();
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedUint32 at the given index.
-     */
-    int getRepeatedUint32(int index);
-
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @return A list containing the repeatedUint64.
-     */
-    java.util.List<java.lang.Long> getRepeatedUint64List();
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @return The count of repeatedUint64.
-     */
-    int getRepeatedUint64Count();
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedUint64 at the given index.
-     */
-    long getRepeatedUint64(int index);
-
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @return A list containing the repeatedSint32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedSint32List();
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @return The count of repeatedSint32.
-     */
-    int getRepeatedSint32Count();
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSint32 at the given index.
-     */
-    int getRepeatedSint32(int index);
-
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @return A list containing the repeatedSint64.
-     */
-    java.util.List<java.lang.Long> getRepeatedSint64List();
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @return The count of repeatedSint64.
-     */
-    int getRepeatedSint64Count();
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSint64 at the given index.
-     */
-    long getRepeatedSint64(int index);
-
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @return A list containing the repeatedFixed32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedFixed32List();
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @return The count of repeatedFixed32.
-     */
-    int getRepeatedFixed32Count();
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed32 at the given index.
-     */
-    int getRepeatedFixed32(int index);
-
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @return A list containing the repeatedFixed64.
-     */
-    java.util.List<java.lang.Long> getRepeatedFixed64List();
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @return The count of repeatedFixed64.
-     */
-    int getRepeatedFixed64Count();
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed64 at the given index.
-     */
-    long getRepeatedFixed64(int index);
-
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @return A list containing the repeatedSfixed32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedSfixed32List();
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @return The count of repeatedSfixed32.
-     */
-    int getRepeatedSfixed32Count();
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSfixed32 at the given index.
-     */
-    int getRepeatedSfixed32(int index);
-
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @return A list containing the repeatedSfixed64.
-     */
-    java.util.List<java.lang.Long> getRepeatedSfixed64List();
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @return The count of repeatedSfixed64.
-     */
-    int getRepeatedSfixed64Count();
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSfixed64 at the given index.
-     */
-    long getRepeatedSfixed64(int index);
-
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @return A list containing the repeatedFloat.
-     */
-    java.util.List<java.lang.Float> getRepeatedFloatList();
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @return The count of repeatedFloat.
-     */
-    int getRepeatedFloatCount();
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFloat at the given index.
-     */
-    float getRepeatedFloat(int index);
-
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @return A list containing the repeatedDouble.
-     */
-    java.util.List<java.lang.Double> getRepeatedDoubleList();
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @return The count of repeatedDouble.
-     */
-    int getRepeatedDoubleCount();
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedDouble at the given index.
-     */
-    double getRepeatedDouble(int index);
-
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @return A list containing the repeatedBool.
-     */
-    java.util.List<java.lang.Boolean> getRepeatedBoolList();
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @return The count of repeatedBool.
-     */
-    int getRepeatedBoolCount();
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedBool at the given index.
-     */
-    boolean getRepeatedBool(int index);
-
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @return A list containing the repeatedString.
-     */
-    java.util.List<java.lang.String>
-        getRepeatedStringList();
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @return The count of repeatedString.
-     */
-    int getRepeatedStringCount();
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedString at the given index.
-     */
-    java.lang.String getRepeatedString(int index);
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedString at the given index.
-     */
-    com.google.protobuf.ByteString
-        getRepeatedStringBytes(int index);
-
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @return A list containing the repeatedBytes.
-     */
-    java.util.List<com.google.protobuf.ByteString> getRepeatedBytesList();
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @return The count of repeatedBytes.
-     */
-    int getRepeatedBytesCount();
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedBytes at the given index.
-     */
-    com.google.protobuf.ByteString getRepeatedBytes(int index);
-
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    java.util.List<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage> 
-        getRepeatedNestedMessageList();
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage getRepeatedNestedMessage(int index);
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    int getRepeatedNestedMessageCount();
-
-    /**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    java.util.List<proto3_unittest.UnittestProto3.ForeignMessage> 
-        getRepeatedForeignMessageList();
-    /**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    proto3_unittest.UnittestProto3.ForeignMessage getRepeatedForeignMessage(int index);
-    /**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    int getRepeatedForeignMessageCount();
-
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    java.util.List<com.google.protobuf.test.UnittestImport.ImportMessage> 
-        getRepeatedImportMessageList();
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    com.google.protobuf.test.UnittestImport.ImportMessage getRepeatedImportMessage(int index);
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    int getRepeatedImportMessageCount();
-
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @return A list containing the repeatedNestedEnum.
-     */
-    java.util.List<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum> getRepeatedNestedEnumList();
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @return The count of repeatedNestedEnum.
-     */
-    int getRepeatedNestedEnumCount();
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedNestedEnum at the given index.
-     */
-    proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum getRepeatedNestedEnum(int index);
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @return A list containing the enum numeric values on the wire for repeatedNestedEnum.
-     */
-    java.util.List<java.lang.Integer>
-    getRepeatedNestedEnumValueList();
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param index The index of the value to return.
-     * @return The enum numeric value on the wire of repeatedNestedEnum at the given index.
-     */
-    int getRepeatedNestedEnumValue(int index);
-
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @return A list containing the repeatedForeignEnum.
-     */
-    java.util.List<proto3_unittest.UnittestProto3.ForeignEnum> getRepeatedForeignEnumList();
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @return The count of repeatedForeignEnum.
-     */
-    int getRepeatedForeignEnumCount();
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedForeignEnum at the given index.
-     */
-    proto3_unittest.UnittestProto3.ForeignEnum getRepeatedForeignEnum(int index);
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @return A list containing the enum numeric values on the wire for repeatedForeignEnum.
-     */
-    java.util.List<java.lang.Integer>
-    getRepeatedForeignEnumValueList();
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param index The index of the value to return.
-     * @return The enum numeric value on the wire of repeatedForeignEnum at the given index.
-     */
-    int getRepeatedForeignEnumValue(int index);
-
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @return A list containing the repeatedStringPiece.
-     */
-    java.util.List<java.lang.String>
-        getRepeatedStringPieceList();
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @return The count of repeatedStringPiece.
-     */
-    int getRepeatedStringPieceCount();
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedStringPiece at the given index.
-     */
-    java.lang.String getRepeatedStringPiece(int index);
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedStringPiece at the given index.
-     */
-    com.google.protobuf.ByteString
-        getRepeatedStringPieceBytes(int index);
-
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @return A list containing the repeatedCord.
-     */
-    java.util.List<java.lang.String>
-        getRepeatedCordList();
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @return The count of repeatedCord.
-     */
-    int getRepeatedCordCount();
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedCord at the given index.
-     */
-    java.lang.String getRepeatedCord(int index);
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedCord at the given index.
-     */
-    com.google.protobuf.ByteString
-        getRepeatedCordBytes(int index);
-
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    java.util.List<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage> 
-        getRepeatedLazyMessageList();
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage getRepeatedLazyMessage(int index);
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    int getRepeatedLazyMessageCount();
-
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     * @return Whether the oneofUint32 field is set.
-     */
-    boolean hasOneofUint32();
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     * @return The oneofUint32.
-     */
-    int getOneofUint32();
-
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-     * @return Whether the oneofNestedMessage field is set.
-     */
-    boolean hasOneofNestedMessage();
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-     * @return The oneofNestedMessage.
-     */
-    proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage getOneofNestedMessage();
-
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return Whether the oneofString field is set.
-     */
-    boolean hasOneofString();
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return The oneofString.
-     */
-    java.lang.String getOneofString();
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return The bytes for oneofString.
-     */
-    com.google.protobuf.ByteString
-        getOneofStringBytes();
-
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     * @return Whether the oneofBytes field is set.
-     */
-    boolean hasOneofBytes();
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     * @return The oneofBytes.
-     */
-    com.google.protobuf.ByteString getOneofBytes();
-
-    public proto3_unittest.UnittestProto3.TestAllTypes.OneofFieldCase getOneofFieldCase();
-  }
-  /**
-   * <pre>
-   * This proto includes every type of field in both singular and repeated
-   * forms.
-   * </pre>
-   *
-   * Protobuf type {@code proto3_unittest.TestAllTypes}
-   */
-  public  static final class TestAllTypes extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestAllTypes, TestAllTypes.Builder> implements
-      // @@protoc_insertion_point(message_implements:proto3_unittest.TestAllTypes)
-      TestAllTypesOrBuilder {
-    private TestAllTypes() {
-      optionalString_ = "";
-      optionalBytes_ = com.google.protobuf.ByteString.EMPTY;
-      optionalStringPiece_ = "";
-      optionalCord_ = "";
-      repeatedInt32_ = emptyIntList();
-      repeatedInt64_ = emptyLongList();
-      repeatedUint32_ = emptyIntList();
-      repeatedUint64_ = emptyLongList();
-      repeatedSint32_ = emptyIntList();
-      repeatedSint64_ = emptyLongList();
-      repeatedFixed32_ = emptyIntList();
-      repeatedFixed64_ = emptyLongList();
-      repeatedSfixed32_ = emptyIntList();
-      repeatedSfixed64_ = emptyLongList();
-      repeatedFloat_ = emptyFloatList();
-      repeatedDouble_ = emptyDoubleList();
-      repeatedBool_ = emptyBooleanList();
-      repeatedString_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      repeatedBytes_ = emptyProtobufList();
-      repeatedNestedMessage_ = emptyProtobufList();
-      repeatedForeignMessage_ = emptyProtobufList();
-      repeatedImportMessage_ = emptyProtobufList();
-      repeatedNestedEnum_ = emptyIntList();
-      repeatedForeignEnum_ = emptyIntList();
-      repeatedStringPiece_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      repeatedCord_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      repeatedLazyMessage_ = emptyProtobufList();
-    }
-    /**
-     * Protobuf enum {@code proto3_unittest.TestAllTypes.NestedEnum}
-     */
-    public enum NestedEnum
-        implements com.google.protobuf.Internal.EnumLite {
-      /**
-       * <code>ZERO = 0;</code>
-       */
-      ZERO(0),
-      /**
-       * <code>FOO = 1;</code>
-       */
-      FOO(1),
-      /**
-       * <code>BAR = 2;</code>
-       */
-      BAR(2),
-      /**
-       * <code>BAZ = 3;</code>
-       */
-      BAZ(3),
-      /**
-       * <pre>
-       * Intentionally negative.
-       * </pre>
-       *
-       * <code>NEG = -1;</code>
-       */
-      NEG(-1),
-      UNRECOGNIZED(-1),
-      ;
-
-      /**
-       * <code>ZERO = 0;</code>
-       */
-      public static final int ZERO_VALUE = 0;
-      /**
-       * <code>FOO = 1;</code>
-       */
-      public static final int FOO_VALUE = 1;
-      /**
-       * <code>BAR = 2;</code>
-       */
-      public static final int BAR_VALUE = 2;
-      /**
-       * <code>BAZ = 3;</code>
-       */
-      public static final int BAZ_VALUE = 3;
-      /**
-       * <pre>
-       * Intentionally negative.
-       * </pre>
-       *
-       * <code>NEG = -1;</code>
-       */
-      public static final int NEG_VALUE = -1;
-
-
-      @java.lang.Override
-      public final int getNumber() {
-        if (this == UNRECOGNIZED) {
-          throw new java.lang.IllegalArgumentException(
-              "Can't get the number of an unknown enum value.");
-        }
-        return value;
-      }
-
-      /**
-       * @param value The number of the enum to look for.
-       * @return The enum associated with the given number.
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static NestedEnum valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static NestedEnum forNumber(int value) {
-        switch (value) {
-          case 0: return ZERO;
-          case 1: return FOO;
-          case 2: return BAR;
-          case 3: return BAZ;
-          case -1: return NEG;
-          default: return null;
-        }
-      }
-
-      public static com.google.protobuf.Internal.EnumLiteMap<NestedEnum>
-          internalGetValueMap() {
-        return internalValueMap;
-      }
-      private static final com.google.protobuf.Internal.EnumLiteMap<
-          NestedEnum> internalValueMap =
-            new com.google.protobuf.Internal.EnumLiteMap<NestedEnum>() {
-              @java.lang.Override
-              public NestedEnum findValueByNumber(int number) {
-                return NestedEnum.forNumber(number);
-              }
-            };
-
-      public static com.google.protobuf.Internal.EnumVerifier 
-          internalGetVerifier() {
-        return NestedEnumVerifier.INSTANCE;
-      }
-
-      private static final class NestedEnumVerifier implements 
-           com.google.protobuf.Internal.EnumVerifier { 
-              static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new NestedEnumVerifier();
-              @java.lang.Override
-              public boolean isInRange(int number) {
-                return NestedEnum.forNumber(number) != null;
-              }
-            };
-
-      private final int value;
-
-      private NestedEnum(int value) {
-        this.value = value;
-      }
-
-      // @@protoc_insertion_point(enum_scope:proto3_unittest.TestAllTypes.NestedEnum)
-    }
-
-    public interface NestedMessageOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:proto3_unittest.TestAllTypes.NestedMessage)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <pre>
-       * The field name "b" fails to compile in proto1 because it conflicts with
-       * a local variable named "b" in one of the generated methods.  Doh.
-       * This file needs to compile in proto1 to test backwards-compatibility.
-       * </pre>
-       *
-       * <code>int32 bb = 1;</code>
-       * @return The bb.
-       */
-      int getBb();
-    }
-    /**
-     * Protobuf type {@code proto3_unittest.TestAllTypes.NestedMessage}
-     */
-    public  static final class NestedMessage extends
-        com.google.protobuf.GeneratedMessageLite<
-            NestedMessage, NestedMessage.Builder> implements
-        // @@protoc_insertion_point(message_implements:proto3_unittest.TestAllTypes.NestedMessage)
-        NestedMessageOrBuilder {
-      private NestedMessage() {
-      }
-      public static final int BB_FIELD_NUMBER = 1;
-      private int bb_;
-      /**
-       * <pre>
-       * The field name "b" fails to compile in proto1 because it conflicts with
-       * a local variable named "b" in one of the generated methods.  Doh.
-       * This file needs to compile in proto1 to test backwards-compatibility.
-       * </pre>
-       *
-       * <code>int32 bb = 1;</code>
-       * @return The bb.
-       */
-      @java.lang.Override
-      public int getBb() {
-        return bb_;
-      }
-      /**
-       * <pre>
-       * The field name "b" fails to compile in proto1 because it conflicts with
-       * a local variable named "b" in one of the generated methods.  Doh.
-       * This file needs to compile in proto1 to test backwards-compatibility.
-       * </pre>
-       *
-       * <code>int32 bb = 1;</code>
-       * @param value The bb to set.
-       */
-      private void setBb(int value) {
-        
-        bb_ = value;
-      }
-      /**
-       * <pre>
-       * The field name "b" fails to compile in proto1 because it conflicts with
-       * a local variable named "b" in one of the generated methods.  Doh.
-       * This file needs to compile in proto1 to test backwards-compatibility.
-       * </pre>
-       *
-       * <code>int32 bb = 1;</code>
-       */
-      private void clearBb() {
-        
-        bb_ = 0;
-      }
-
-      public static proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code proto3_unittest.TestAllTypes.NestedMessage}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage, Builder> implements
-          // @@protoc_insertion_point(builder_implements:proto3_unittest.TestAllTypes.NestedMessage)
-          proto3_unittest.UnittestProto3.TestAllTypes.NestedMessageOrBuilder {
-        // Construct using proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <pre>
-         * The field name "b" fails to compile in proto1 because it conflicts with
-         * a local variable named "b" in one of the generated methods.  Doh.
-         * This file needs to compile in proto1 to test backwards-compatibility.
-         * </pre>
-         *
-         * <code>int32 bb = 1;</code>
-         * @return The bb.
-         */
-        @java.lang.Override
-        public int getBb() {
-          return instance.getBb();
-        }
-        /**
-         * <pre>
-         * The field name "b" fails to compile in proto1 because it conflicts with
-         * a local variable named "b" in one of the generated methods.  Doh.
-         * This file needs to compile in proto1 to test backwards-compatibility.
-         * </pre>
-         *
-         * <code>int32 bb = 1;</code>
-         * @param value The bb to set.
-         * @return This builder for chaining.
-         */
-        public Builder setBb(int value) {
-          copyOnWrite();
-          instance.setBb(value);
-          return this;
-        }
-        /**
-         * <pre>
-         * The field name "b" fails to compile in proto1 because it conflicts with
-         * a local variable named "b" in one of the generated methods.  Doh.
-         * This file needs to compile in proto1 to test backwards-compatibility.
-         * </pre>
-         *
-         * <code>int32 bb = 1;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearBb() {
-          copyOnWrite();
-          instance.clearBb();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:proto3_unittest.TestAllTypes.NestedMessage)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bb_",
-              };
-              java.lang.String info =
-                  "\u0000\u0001\u0000\u0000\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u0004";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage> parser = PARSER;
-            if (parser == null) {
-              synchronized (proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:proto3_unittest.TestAllTypes.NestedMessage)
-      private static final proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage DEFAULT_INSTANCE;
-      static {
-        NestedMessage defaultInstance = new NestedMessage();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          NestedMessage.class, defaultInstance);
-      }
-
-      public static proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<NestedMessage> PARSER;
-
-      public static com.google.protobuf.Parser<NestedMessage> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int oneofFieldCase_ = 0;
-    private java.lang.Object oneofField_;
-    public enum OneofFieldCase {
-      ONEOF_UINT32(111),
-      ONEOF_NESTED_MESSAGE(112),
-      ONEOF_STRING(113),
-      ONEOF_BYTES(114),
-      ONEOFFIELD_NOT_SET(0);
-      private final int value;
-      private OneofFieldCase(int value) {
-        this.value = value;
-      }
-      /**
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static OneofFieldCase valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static OneofFieldCase forNumber(int value) {
-        switch (value) {
-          case 111: return ONEOF_UINT32;
-          case 112: return ONEOF_NESTED_MESSAGE;
-          case 113: return ONEOF_STRING;
-          case 114: return ONEOF_BYTES;
-          case 0: return ONEOFFIELD_NOT_SET;
-          default: return null;
-        }
-      }
-      public int getNumber() {
-        return this.value;
-      }
-    };
-
-    @java.lang.Override
-    public OneofFieldCase
-    getOneofFieldCase() {
-      return OneofFieldCase.forNumber(
-          oneofFieldCase_);
-    }
-
-    private void clearOneofField() {
-      oneofFieldCase_ = 0;
-      oneofField_ = null;
-    }
-
-    public static final int OPTIONAL_INT32_FIELD_NUMBER = 1;
-    private int optionalInt32_;
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>int32 optional_int32 = 1;</code>
-     * @return The optionalInt32.
-     */
-    @java.lang.Override
-    public int getOptionalInt32() {
-      return optionalInt32_;
-    }
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>int32 optional_int32 = 1;</code>
-     * @param value The optionalInt32 to set.
-     */
-    private void setOptionalInt32(int value) {
-      
-      optionalInt32_ = value;
-    }
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>int32 optional_int32 = 1;</code>
-     */
-    private void clearOptionalInt32() {
-      
-      optionalInt32_ = 0;
-    }
-
-    public static final int OPTIONAL_INT64_FIELD_NUMBER = 2;
-    private long optionalInt64_;
-    /**
-     * <code>int64 optional_int64 = 2;</code>
-     * @return The optionalInt64.
-     */
-    @java.lang.Override
-    public long getOptionalInt64() {
-      return optionalInt64_;
-    }
-    /**
-     * <code>int64 optional_int64 = 2;</code>
-     * @param value The optionalInt64 to set.
-     */
-    private void setOptionalInt64(long value) {
-      
-      optionalInt64_ = value;
-    }
-    /**
-     * <code>int64 optional_int64 = 2;</code>
-     */
-    private void clearOptionalInt64() {
-      
-      optionalInt64_ = 0L;
-    }
-
-    public static final int OPTIONAL_UINT32_FIELD_NUMBER = 3;
-    private int optionalUint32_;
-    /**
-     * <code>uint32 optional_uint32 = 3;</code>
-     * @return The optionalUint32.
-     */
-    @java.lang.Override
-    public int getOptionalUint32() {
-      return optionalUint32_;
-    }
-    /**
-     * <code>uint32 optional_uint32 = 3;</code>
-     * @param value The optionalUint32 to set.
-     */
-    private void setOptionalUint32(int value) {
-      
-      optionalUint32_ = value;
-    }
-    /**
-     * <code>uint32 optional_uint32 = 3;</code>
-     */
-    private void clearOptionalUint32() {
-      
-      optionalUint32_ = 0;
-    }
-
-    public static final int OPTIONAL_UINT64_FIELD_NUMBER = 4;
-    private long optionalUint64_;
-    /**
-     * <code>uint64 optional_uint64 = 4;</code>
-     * @return The optionalUint64.
-     */
-    @java.lang.Override
-    public long getOptionalUint64() {
-      return optionalUint64_;
-    }
-    /**
-     * <code>uint64 optional_uint64 = 4;</code>
-     * @param value The optionalUint64 to set.
-     */
-    private void setOptionalUint64(long value) {
-      
-      optionalUint64_ = value;
-    }
-    /**
-     * <code>uint64 optional_uint64 = 4;</code>
-     */
-    private void clearOptionalUint64() {
-      
-      optionalUint64_ = 0L;
-    }
-
-    public static final int OPTIONAL_SINT32_FIELD_NUMBER = 5;
-    private int optionalSint32_;
-    /**
-     * <code>sint32 optional_sint32 = 5;</code>
-     * @return The optionalSint32.
-     */
-    @java.lang.Override
-    public int getOptionalSint32() {
-      return optionalSint32_;
-    }
-    /**
-     * <code>sint32 optional_sint32 = 5;</code>
-     * @param value The optionalSint32 to set.
-     */
-    private void setOptionalSint32(int value) {
-      
-      optionalSint32_ = value;
-    }
-    /**
-     * <code>sint32 optional_sint32 = 5;</code>
-     */
-    private void clearOptionalSint32() {
-      
-      optionalSint32_ = 0;
-    }
-
-    public static final int OPTIONAL_SINT64_FIELD_NUMBER = 6;
-    private long optionalSint64_;
-    /**
-     * <code>sint64 optional_sint64 = 6;</code>
-     * @return The optionalSint64.
-     */
-    @java.lang.Override
-    public long getOptionalSint64() {
-      return optionalSint64_;
-    }
-    /**
-     * <code>sint64 optional_sint64 = 6;</code>
-     * @param value The optionalSint64 to set.
-     */
-    private void setOptionalSint64(long value) {
-      
-      optionalSint64_ = value;
-    }
-    /**
-     * <code>sint64 optional_sint64 = 6;</code>
-     */
-    private void clearOptionalSint64() {
-      
-      optionalSint64_ = 0L;
-    }
-
-    public static final int OPTIONAL_FIXED32_FIELD_NUMBER = 7;
-    private int optionalFixed32_;
-    /**
-     * <code>fixed32 optional_fixed32 = 7;</code>
-     * @return The optionalFixed32.
-     */
-    @java.lang.Override
-    public int getOptionalFixed32() {
-      return optionalFixed32_;
-    }
-    /**
-     * <code>fixed32 optional_fixed32 = 7;</code>
-     * @param value The optionalFixed32 to set.
-     */
-    private void setOptionalFixed32(int value) {
-      
-      optionalFixed32_ = value;
-    }
-    /**
-     * <code>fixed32 optional_fixed32 = 7;</code>
-     */
-    private void clearOptionalFixed32() {
-      
-      optionalFixed32_ = 0;
-    }
-
-    public static final int OPTIONAL_FIXED64_FIELD_NUMBER = 8;
-    private long optionalFixed64_;
-    /**
-     * <code>fixed64 optional_fixed64 = 8;</code>
-     * @return The optionalFixed64.
-     */
-    @java.lang.Override
-    public long getOptionalFixed64() {
-      return optionalFixed64_;
-    }
-    /**
-     * <code>fixed64 optional_fixed64 = 8;</code>
-     * @param value The optionalFixed64 to set.
-     */
-    private void setOptionalFixed64(long value) {
-      
-      optionalFixed64_ = value;
-    }
-    /**
-     * <code>fixed64 optional_fixed64 = 8;</code>
-     */
-    private void clearOptionalFixed64() {
-      
-      optionalFixed64_ = 0L;
-    }
-
-    public static final int OPTIONAL_SFIXED32_FIELD_NUMBER = 9;
-    private int optionalSfixed32_;
-    /**
-     * <code>sfixed32 optional_sfixed32 = 9;</code>
-     * @return The optionalSfixed32.
-     */
-    @java.lang.Override
-    public int getOptionalSfixed32() {
-      return optionalSfixed32_;
-    }
-    /**
-     * <code>sfixed32 optional_sfixed32 = 9;</code>
-     * @param value The optionalSfixed32 to set.
-     */
-    private void setOptionalSfixed32(int value) {
-      
-      optionalSfixed32_ = value;
-    }
-    /**
-     * <code>sfixed32 optional_sfixed32 = 9;</code>
-     */
-    private void clearOptionalSfixed32() {
-      
-      optionalSfixed32_ = 0;
-    }
-
-    public static final int OPTIONAL_SFIXED64_FIELD_NUMBER = 10;
-    private long optionalSfixed64_;
-    /**
-     * <code>sfixed64 optional_sfixed64 = 10;</code>
-     * @return The optionalSfixed64.
-     */
-    @java.lang.Override
-    public long getOptionalSfixed64() {
-      return optionalSfixed64_;
-    }
-    /**
-     * <code>sfixed64 optional_sfixed64 = 10;</code>
-     * @param value The optionalSfixed64 to set.
-     */
-    private void setOptionalSfixed64(long value) {
-      
-      optionalSfixed64_ = value;
-    }
-    /**
-     * <code>sfixed64 optional_sfixed64 = 10;</code>
-     */
-    private void clearOptionalSfixed64() {
-      
-      optionalSfixed64_ = 0L;
-    }
-
-    public static final int OPTIONAL_FLOAT_FIELD_NUMBER = 11;
-    private float optionalFloat_;
-    /**
-     * <code>float optional_float = 11;</code>
-     * @return The optionalFloat.
-     */
-    @java.lang.Override
-    public float getOptionalFloat() {
-      return optionalFloat_;
-    }
-    /**
-     * <code>float optional_float = 11;</code>
-     * @param value The optionalFloat to set.
-     */
-    private void setOptionalFloat(float value) {
-      
-      optionalFloat_ = value;
-    }
-    /**
-     * <code>float optional_float = 11;</code>
-     */
-    private void clearOptionalFloat() {
-      
-      optionalFloat_ = 0F;
-    }
-
-    public static final int OPTIONAL_DOUBLE_FIELD_NUMBER = 12;
-    private double optionalDouble_;
-    /**
-     * <code>double optional_double = 12;</code>
-     * @return The optionalDouble.
-     */
-    @java.lang.Override
-    public double getOptionalDouble() {
-      return optionalDouble_;
-    }
-    /**
-     * <code>double optional_double = 12;</code>
-     * @param value The optionalDouble to set.
-     */
-    private void setOptionalDouble(double value) {
-      
-      optionalDouble_ = value;
-    }
-    /**
-     * <code>double optional_double = 12;</code>
-     */
-    private void clearOptionalDouble() {
-      
-      optionalDouble_ = 0D;
-    }
-
-    public static final int OPTIONAL_BOOL_FIELD_NUMBER = 13;
-    private boolean optionalBool_;
-    /**
-     * <code>bool optional_bool = 13;</code>
-     * @return The optionalBool.
-     */
-    @java.lang.Override
-    public boolean getOptionalBool() {
-      return optionalBool_;
-    }
-    /**
-     * <code>bool optional_bool = 13;</code>
-     * @param value The optionalBool to set.
-     */
-    private void setOptionalBool(boolean value) {
-      
-      optionalBool_ = value;
-    }
-    /**
-     * <code>bool optional_bool = 13;</code>
-     */
-    private void clearOptionalBool() {
-      
-      optionalBool_ = false;
-    }
-
-    public static final int OPTIONAL_STRING_FIELD_NUMBER = 14;
-    private java.lang.String optionalString_;
-    /**
-     * <code>string optional_string = 14;</code>
-     * @return The optionalString.
-     */
-    @java.lang.Override
-    public java.lang.String getOptionalString() {
-      return optionalString_;
-    }
-    /**
-     * <code>string optional_string = 14;</code>
-     * @return The bytes for optionalString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOptionalStringBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(optionalString_);
-    }
-    /**
-     * <code>string optional_string = 14;</code>
-     * @param value The optionalString to set.
-     */
-    private void setOptionalString(
-        java.lang.String value) {
-      value.getClass();
-  
-      optionalString_ = value;
-    }
-    /**
-     * <code>string optional_string = 14;</code>
-     */
-    private void clearOptionalString() {
-      
-      optionalString_ = getDefaultInstance().getOptionalString();
-    }
-    /**
-     * <code>string optional_string = 14;</code>
-     * @param value The bytes for optionalString to set.
-     */
-    private void setOptionalStringBytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      optionalString_ = value.toStringUtf8();
-      
-    }
-
-    public static final int OPTIONAL_BYTES_FIELD_NUMBER = 15;
-    private com.google.protobuf.ByteString optionalBytes_;
-    /**
-     * <code>bytes optional_bytes = 15;</code>
-     * @return The optionalBytes.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getOptionalBytes() {
-      return optionalBytes_;
-    }
-    /**
-     * <code>bytes optional_bytes = 15;</code>
-     * @param value The optionalBytes to set.
-     */
-    private void setOptionalBytes(com.google.protobuf.ByteString value) {
-      value.getClass();
-  
-      optionalBytes_ = value;
-    }
-    /**
-     * <code>bytes optional_bytes = 15;</code>
-     */
-    private void clearOptionalBytes() {
-      
-      optionalBytes_ = getDefaultInstance().getOptionalBytes();
-    }
-
-    public static final int OPTIONAL_NESTED_MESSAGE_FIELD_NUMBER = 18;
-    private proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage optionalNestedMessage_;
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalNestedMessage() {
-      return optionalNestedMessage_ != null;
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-     */
-    @java.lang.Override
-    public proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage getOptionalNestedMessage() {
-      return optionalNestedMessage_ == null ? proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.getDefaultInstance() : optionalNestedMessage_;
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-     */
-    private void setOptionalNestedMessage(proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  optionalNestedMessage_ = value;
-      
-      }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalNestedMessage(proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  if (optionalNestedMessage_ != null &&
-          optionalNestedMessage_ != proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.getDefaultInstance()) {
-        optionalNestedMessage_ =
-          proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.newBuilder(optionalNestedMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalNestedMessage_ = value;
-      }
-      
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-     */
-    private void clearOptionalNestedMessage() {  optionalNestedMessage_ = null;
-      
-    }
-
-    public static final int OPTIONAL_FOREIGN_MESSAGE_FIELD_NUMBER = 19;
-    private proto3_unittest.UnittestProto3.ForeignMessage optionalForeignMessage_;
-    /**
-     * <code>.proto3_unittest.ForeignMessage optional_foreign_message = 19;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalForeignMessage() {
-      return optionalForeignMessage_ != null;
-    }
-    /**
-     * <code>.proto3_unittest.ForeignMessage optional_foreign_message = 19;</code>
-     */
-    @java.lang.Override
-    public proto3_unittest.UnittestProto3.ForeignMessage getOptionalForeignMessage() {
-      return optionalForeignMessage_ == null ? proto3_unittest.UnittestProto3.ForeignMessage.getDefaultInstance() : optionalForeignMessage_;
-    }
-    /**
-     * <code>.proto3_unittest.ForeignMessage optional_foreign_message = 19;</code>
-     */
-    private void setOptionalForeignMessage(proto3_unittest.UnittestProto3.ForeignMessage value) {
-      value.getClass();
-  optionalForeignMessage_ = value;
-      
-      }
-    /**
-     * <code>.proto3_unittest.ForeignMessage optional_foreign_message = 19;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalForeignMessage(proto3_unittest.UnittestProto3.ForeignMessage value) {
-      value.getClass();
-  if (optionalForeignMessage_ != null &&
-          optionalForeignMessage_ != proto3_unittest.UnittestProto3.ForeignMessage.getDefaultInstance()) {
-        optionalForeignMessage_ =
-          proto3_unittest.UnittestProto3.ForeignMessage.newBuilder(optionalForeignMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalForeignMessage_ = value;
-      }
-      
-    }
-    /**
-     * <code>.proto3_unittest.ForeignMessage optional_foreign_message = 19;</code>
-     */
-    private void clearOptionalForeignMessage() {  optionalForeignMessage_ = null;
-      
-    }
-
-    public static final int OPTIONAL_IMPORT_MESSAGE_FIELD_NUMBER = 20;
-    private com.google.protobuf.test.UnittestImport.ImportMessage optionalImportMessage_;
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalImportMessage() {
-      return optionalImportMessage_ != null;
-    }
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.test.UnittestImport.ImportMessage getOptionalImportMessage() {
-      return optionalImportMessage_ == null ? com.google.protobuf.test.UnittestImport.ImportMessage.getDefaultInstance() : optionalImportMessage_;
-    }
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-     */
-    private void setOptionalImportMessage(com.google.protobuf.test.UnittestImport.ImportMessage value) {
-      value.getClass();
-  optionalImportMessage_ = value;
-      
-      }
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalImportMessage(com.google.protobuf.test.UnittestImport.ImportMessage value) {
-      value.getClass();
-  if (optionalImportMessage_ != null &&
-          optionalImportMessage_ != com.google.protobuf.test.UnittestImport.ImportMessage.getDefaultInstance()) {
-        optionalImportMessage_ =
-          com.google.protobuf.test.UnittestImport.ImportMessage.newBuilder(optionalImportMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalImportMessage_ = value;
-      }
-      
-    }
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-     */
-    private void clearOptionalImportMessage() {  optionalImportMessage_ = null;
-      
-    }
-
-    public static final int OPTIONAL_NESTED_ENUM_FIELD_NUMBER = 21;
-    private int optionalNestedEnum_;
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-     * @return The enum numeric value on the wire for optionalNestedEnum.
-     */
-    @java.lang.Override
-    public int getOptionalNestedEnumValue() {
-      return optionalNestedEnum_;
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-     * @return The optionalNestedEnum.
-     */
-    @java.lang.Override
-    public proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum getOptionalNestedEnum() {
-      proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum result = proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum.forNumber(optionalNestedEnum_);
-      return result == null ? proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum.UNRECOGNIZED : result;
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-     * @param value The enum numeric value on the wire for optionalNestedEnum to set.
-     */
-    private void setOptionalNestedEnumValue(int value) {
-        optionalNestedEnum_ = value;
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-     * @param value The optionalNestedEnum to set.
-     */
-    private void setOptionalNestedEnum(proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum value) {
-      optionalNestedEnum_ = value.getNumber();
-      
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-     */
-    private void clearOptionalNestedEnum() {
-      
-      optionalNestedEnum_ = 0;
-    }
-
-    public static final int OPTIONAL_FOREIGN_ENUM_FIELD_NUMBER = 22;
-    private int optionalForeignEnum_;
-    /**
-     * <code>.proto3_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     * @return The enum numeric value on the wire for optionalForeignEnum.
-     */
-    @java.lang.Override
-    public int getOptionalForeignEnumValue() {
-      return optionalForeignEnum_;
-    }
-    /**
-     * <code>.proto3_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     * @return The optionalForeignEnum.
-     */
-    @java.lang.Override
-    public proto3_unittest.UnittestProto3.ForeignEnum getOptionalForeignEnum() {
-      proto3_unittest.UnittestProto3.ForeignEnum result = proto3_unittest.UnittestProto3.ForeignEnum.forNumber(optionalForeignEnum_);
-      return result == null ? proto3_unittest.UnittestProto3.ForeignEnum.UNRECOGNIZED : result;
-    }
-    /**
-     * <code>.proto3_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     * @param value The enum numeric value on the wire for optionalForeignEnum to set.
-     */
-    private void setOptionalForeignEnumValue(int value) {
-        optionalForeignEnum_ = value;
-    }
-    /**
-     * <code>.proto3_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     * @param value The optionalForeignEnum to set.
-     */
-    private void setOptionalForeignEnum(proto3_unittest.UnittestProto3.ForeignEnum value) {
-      optionalForeignEnum_ = value.getNumber();
-      
-    }
-    /**
-     * <code>.proto3_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     */
-    private void clearOptionalForeignEnum() {
-      
-      optionalForeignEnum_ = 0;
-    }
-
-    public static final int OPTIONAL_STRING_PIECE_FIELD_NUMBER = 24;
-    private java.lang.String optionalStringPiece_;
-    /**
-     * <code>string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @return The optionalStringPiece.
-     */
-    @java.lang.Override
-    public java.lang.String getOptionalStringPiece() {
-      return optionalStringPiece_;
-    }
-    /**
-     * <code>string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @return The bytes for optionalStringPiece.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOptionalStringPieceBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(optionalStringPiece_);
-    }
-    /**
-     * <code>string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @param value The optionalStringPiece to set.
-     */
-    private void setOptionalStringPiece(
-        java.lang.String value) {
-      value.getClass();
-  
-      optionalStringPiece_ = value;
-    }
-    /**
-     * <code>string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     */
-    private void clearOptionalStringPiece() {
-      
-      optionalStringPiece_ = getDefaultInstance().getOptionalStringPiece();
-    }
-    /**
-     * <code>string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @param value The bytes for optionalStringPiece to set.
-     */
-    private void setOptionalStringPieceBytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      optionalStringPiece_ = value.toStringUtf8();
-      
-    }
-
-    public static final int OPTIONAL_CORD_FIELD_NUMBER = 25;
-    private java.lang.String optionalCord_;
-    /**
-     * <code>string optional_cord = 25 [ctype = CORD];</code>
-     * @return The optionalCord.
-     */
-    @java.lang.Override
-    public java.lang.String getOptionalCord() {
-      return optionalCord_;
-    }
-    /**
-     * <code>string optional_cord = 25 [ctype = CORD];</code>
-     * @return The bytes for optionalCord.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOptionalCordBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(optionalCord_);
-    }
-    /**
-     * <code>string optional_cord = 25 [ctype = CORD];</code>
-     * @param value The optionalCord to set.
-     */
-    private void setOptionalCord(
-        java.lang.String value) {
-      value.getClass();
-  
-      optionalCord_ = value;
-    }
-    /**
-     * <code>string optional_cord = 25 [ctype = CORD];</code>
-     */
-    private void clearOptionalCord() {
-      
-      optionalCord_ = getDefaultInstance().getOptionalCord();
-    }
-    /**
-     * <code>string optional_cord = 25 [ctype = CORD];</code>
-     * @param value The bytes for optionalCord to set.
-     */
-    private void setOptionalCordBytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      optionalCord_ = value.toStringUtf8();
-      
-    }
-
-    public static final int OPTIONAL_PUBLIC_IMPORT_MESSAGE_FIELD_NUMBER = 26;
-    private com.google.protobuf.test.UnittestImportPublic.PublicImportMessage optionalPublicImportMessage_;
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>.protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalPublicImportMessage() {
-      return optionalPublicImportMessage_ != null;
-    }
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>.protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.test.UnittestImportPublic.PublicImportMessage getOptionalPublicImportMessage() {
-      return optionalPublicImportMessage_ == null ? com.google.protobuf.test.UnittestImportPublic.PublicImportMessage.getDefaultInstance() : optionalPublicImportMessage_;
-    }
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>.protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-     */
-    private void setOptionalPublicImportMessage(com.google.protobuf.test.UnittestImportPublic.PublicImportMessage value) {
-      value.getClass();
-  optionalPublicImportMessage_ = value;
-      
-      }
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>.protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalPublicImportMessage(com.google.protobuf.test.UnittestImportPublic.PublicImportMessage value) {
-      value.getClass();
-  if (optionalPublicImportMessage_ != null &&
-          optionalPublicImportMessage_ != com.google.protobuf.test.UnittestImportPublic.PublicImportMessage.getDefaultInstance()) {
-        optionalPublicImportMessage_ =
-          com.google.protobuf.test.UnittestImportPublic.PublicImportMessage.newBuilder(optionalPublicImportMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalPublicImportMessage_ = value;
-      }
-      
-    }
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>.protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-     */
-    private void clearOptionalPublicImportMessage() {  optionalPublicImportMessage_ = null;
-      
-    }
-
-    public static final int OPTIONAL_LAZY_MESSAGE_FIELD_NUMBER = 27;
-    private proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage optionalLazyMessage_;
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalLazyMessage() {
-      return optionalLazyMessage_ != null;
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage getOptionalLazyMessage() {
-      return optionalLazyMessage_ == null ? proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.getDefaultInstance() : optionalLazyMessage_;
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     */
-    private void setOptionalLazyMessage(proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  optionalLazyMessage_ = value;
-      
-      }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalLazyMessage(proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  if (optionalLazyMessage_ != null &&
-          optionalLazyMessage_ != proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.getDefaultInstance()) {
-        optionalLazyMessage_ =
-          proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.newBuilder(optionalLazyMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalLazyMessage_ = value;
-      }
-      
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     */
-    private void clearOptionalLazyMessage() {  optionalLazyMessage_ = null;
-      
-    }
-
-    public static final int OPTIONAL_LAZY_IMPORT_MESSAGE_FIELD_NUMBER = 115;
-    private com.google.protobuf.test.UnittestImport.ImportMessage optionalLazyImportMessage_;
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalLazyImportMessage() {
-      return optionalLazyImportMessage_ != null;
-    }
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.test.UnittestImport.ImportMessage getOptionalLazyImportMessage() {
-      return optionalLazyImportMessage_ == null ? com.google.protobuf.test.UnittestImport.ImportMessage.getDefaultInstance() : optionalLazyImportMessage_;
-    }
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115 [lazy = true];</code>
-     */
-    private void setOptionalLazyImportMessage(com.google.protobuf.test.UnittestImport.ImportMessage value) {
-      value.getClass();
-  optionalLazyImportMessage_ = value;
-      
-      }
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115 [lazy = true];</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalLazyImportMessage(com.google.protobuf.test.UnittestImport.ImportMessage value) {
-      value.getClass();
-  if (optionalLazyImportMessage_ != null &&
-          optionalLazyImportMessage_ != com.google.protobuf.test.UnittestImport.ImportMessage.getDefaultInstance()) {
-        optionalLazyImportMessage_ =
-          com.google.protobuf.test.UnittestImport.ImportMessage.newBuilder(optionalLazyImportMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalLazyImportMessage_ = value;
-      }
-      
-    }
-    /**
-     * <code>.protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115 [lazy = true];</code>
-     */
-    private void clearOptionalLazyImportMessage() {  optionalLazyImportMessage_ = null;
-      
-    }
-
-    public static final int REPEATED_INT32_FIELD_NUMBER = 31;
-    private com.google.protobuf.Internal.IntList repeatedInt32_;
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @return A list containing the repeatedInt32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedInt32List() {
-      return repeatedInt32_;
-    }
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @return The count of repeatedInt32.
-     */
-    @java.lang.Override
-    public int getRepeatedInt32Count() {
-      return repeatedInt32_.size();
-    }
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedInt32(int index) {
-      return repeatedInt32_.getInt(index);
-    }
-    private int repeatedInt32MemoizedSerializedSize = -1;
-    private void ensureRepeatedInt32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedInt32_;
-      if (!tmp.isModifiable()) {
-        repeatedInt32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt32 to set.
-     */
-    private void setRepeatedInt32(
-        int index, int value) {
-      ensureRepeatedInt32IsMutable();
-      repeatedInt32_.setInt(index, value);
-    }
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param value The repeatedInt32 to add.
-     */
-    private void addRepeatedInt32(int value) {
-      ensureRepeatedInt32IsMutable();
-      repeatedInt32_.addInt(value);
-    }
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param values The repeatedInt32 to add.
-     */
-    private void addAllRepeatedInt32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedInt32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedInt32_);
-    }
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     */
-    private void clearRepeatedInt32() {
-      repeatedInt32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_INT64_FIELD_NUMBER = 32;
-    private com.google.protobuf.Internal.LongList repeatedInt64_;
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @return A list containing the repeatedInt64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedInt64List() {
-      return repeatedInt64_;
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @return The count of repeatedInt64.
-     */
-    @java.lang.Override
-    public int getRepeatedInt64Count() {
-      return repeatedInt64_.size();
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedInt64(int index) {
-      return repeatedInt64_.getLong(index);
-    }
-    private int repeatedInt64MemoizedSerializedSize = -1;
-    private void ensureRepeatedInt64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedInt64_;
-      if (!tmp.isModifiable()) {
-        repeatedInt64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt64 to set.
-     */
-    private void setRepeatedInt64(
-        int index, long value) {
-      ensureRepeatedInt64IsMutable();
-      repeatedInt64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param value The repeatedInt64 to add.
-     */
-    private void addRepeatedInt64(long value) {
-      ensureRepeatedInt64IsMutable();
-      repeatedInt64_.addLong(value);
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param values The repeatedInt64 to add.
-     */
-    private void addAllRepeatedInt64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedInt64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedInt64_);
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     */
-    private void clearRepeatedInt64() {
-      repeatedInt64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_UINT32_FIELD_NUMBER = 33;
-    private com.google.protobuf.Internal.IntList repeatedUint32_;
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @return A list containing the repeatedUint32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedUint32List() {
-      return repeatedUint32_;
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @return The count of repeatedUint32.
-     */
-    @java.lang.Override
-    public int getRepeatedUint32Count() {
-      return repeatedUint32_.size();
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedUint32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedUint32(int index) {
-      return repeatedUint32_.getInt(index);
-    }
-    private int repeatedUint32MemoizedSerializedSize = -1;
-    private void ensureRepeatedUint32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedUint32_;
-      if (!tmp.isModifiable()) {
-        repeatedUint32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedUint32 to set.
-     */
-    private void setRepeatedUint32(
-        int index, int value) {
-      ensureRepeatedUint32IsMutable();
-      repeatedUint32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param value The repeatedUint32 to add.
-     */
-    private void addRepeatedUint32(int value) {
-      ensureRepeatedUint32IsMutable();
-      repeatedUint32_.addInt(value);
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param values The repeatedUint32 to add.
-     */
-    private void addAllRepeatedUint32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedUint32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedUint32_);
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     */
-    private void clearRepeatedUint32() {
-      repeatedUint32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_UINT64_FIELD_NUMBER = 34;
-    private com.google.protobuf.Internal.LongList repeatedUint64_;
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @return A list containing the repeatedUint64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedUint64List() {
-      return repeatedUint64_;
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @return The count of repeatedUint64.
-     */
-    @java.lang.Override
-    public int getRepeatedUint64Count() {
-      return repeatedUint64_.size();
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedUint64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedUint64(int index) {
-      return repeatedUint64_.getLong(index);
-    }
-    private int repeatedUint64MemoizedSerializedSize = -1;
-    private void ensureRepeatedUint64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedUint64_;
-      if (!tmp.isModifiable()) {
-        repeatedUint64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedUint64 to set.
-     */
-    private void setRepeatedUint64(
-        int index, long value) {
-      ensureRepeatedUint64IsMutable();
-      repeatedUint64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param value The repeatedUint64 to add.
-     */
-    private void addRepeatedUint64(long value) {
-      ensureRepeatedUint64IsMutable();
-      repeatedUint64_.addLong(value);
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param values The repeatedUint64 to add.
-     */
-    private void addAllRepeatedUint64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedUint64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedUint64_);
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     */
-    private void clearRepeatedUint64() {
-      repeatedUint64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_SINT32_FIELD_NUMBER = 35;
-    private com.google.protobuf.Internal.IntList repeatedSint32_;
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @return A list containing the repeatedSint32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedSint32List() {
-      return repeatedSint32_;
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @return The count of repeatedSint32.
-     */
-    @java.lang.Override
-    public int getRepeatedSint32Count() {
-      return repeatedSint32_.size();
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSint32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedSint32(int index) {
-      return repeatedSint32_.getInt(index);
-    }
-    private int repeatedSint32MemoizedSerializedSize = -1;
-    private void ensureRepeatedSint32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedSint32_;
-      if (!tmp.isModifiable()) {
-        repeatedSint32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSint32 to set.
-     */
-    private void setRepeatedSint32(
-        int index, int value) {
-      ensureRepeatedSint32IsMutable();
-      repeatedSint32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param value The repeatedSint32 to add.
-     */
-    private void addRepeatedSint32(int value) {
-      ensureRepeatedSint32IsMutable();
-      repeatedSint32_.addInt(value);
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param values The repeatedSint32 to add.
-     */
-    private void addAllRepeatedSint32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedSint32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedSint32_);
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     */
-    private void clearRepeatedSint32() {
-      repeatedSint32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_SINT64_FIELD_NUMBER = 36;
-    private com.google.protobuf.Internal.LongList repeatedSint64_;
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @return A list containing the repeatedSint64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedSint64List() {
-      return repeatedSint64_;
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @return The count of repeatedSint64.
-     */
-    @java.lang.Override
-    public int getRepeatedSint64Count() {
-      return repeatedSint64_.size();
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSint64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedSint64(int index) {
-      return repeatedSint64_.getLong(index);
-    }
-    private int repeatedSint64MemoizedSerializedSize = -1;
-    private void ensureRepeatedSint64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedSint64_;
-      if (!tmp.isModifiable()) {
-        repeatedSint64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSint64 to set.
-     */
-    private void setRepeatedSint64(
-        int index, long value) {
-      ensureRepeatedSint64IsMutable();
-      repeatedSint64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param value The repeatedSint64 to add.
-     */
-    private void addRepeatedSint64(long value) {
-      ensureRepeatedSint64IsMutable();
-      repeatedSint64_.addLong(value);
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param values The repeatedSint64 to add.
-     */
-    private void addAllRepeatedSint64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedSint64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedSint64_);
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     */
-    private void clearRepeatedSint64() {
-      repeatedSint64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_FIXED32_FIELD_NUMBER = 37;
-    private com.google.protobuf.Internal.IntList repeatedFixed32_;
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @return A list containing the repeatedFixed32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedFixed32List() {
-      return repeatedFixed32_;
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @return The count of repeatedFixed32.
-     */
-    @java.lang.Override
-    public int getRepeatedFixed32Count() {
-      return repeatedFixed32_.size();
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedFixed32(int index) {
-      return repeatedFixed32_.getInt(index);
-    }
-    private int repeatedFixed32MemoizedSerializedSize = -1;
-    private void ensureRepeatedFixed32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedFixed32_;
-      if (!tmp.isModifiable()) {
-        repeatedFixed32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed32 to set.
-     */
-    private void setRepeatedFixed32(
-        int index, int value) {
-      ensureRepeatedFixed32IsMutable();
-      repeatedFixed32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param value The repeatedFixed32 to add.
-     */
-    private void addRepeatedFixed32(int value) {
-      ensureRepeatedFixed32IsMutable();
-      repeatedFixed32_.addInt(value);
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param values The repeatedFixed32 to add.
-     */
-    private void addAllRepeatedFixed32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedFixed32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedFixed32_);
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     */
-    private void clearRepeatedFixed32() {
-      repeatedFixed32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_FIXED64_FIELD_NUMBER = 38;
-    private com.google.protobuf.Internal.LongList repeatedFixed64_;
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @return A list containing the repeatedFixed64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedFixed64List() {
-      return repeatedFixed64_;
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @return The count of repeatedFixed64.
-     */
-    @java.lang.Override
-    public int getRepeatedFixed64Count() {
-      return repeatedFixed64_.size();
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedFixed64(int index) {
-      return repeatedFixed64_.getLong(index);
-    }
-    private int repeatedFixed64MemoizedSerializedSize = -1;
-    private void ensureRepeatedFixed64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedFixed64_;
-      if (!tmp.isModifiable()) {
-        repeatedFixed64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed64 to set.
-     */
-    private void setRepeatedFixed64(
-        int index, long value) {
-      ensureRepeatedFixed64IsMutable();
-      repeatedFixed64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param value The repeatedFixed64 to add.
-     */
-    private void addRepeatedFixed64(long value) {
-      ensureRepeatedFixed64IsMutable();
-      repeatedFixed64_.addLong(value);
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param values The repeatedFixed64 to add.
-     */
-    private void addAllRepeatedFixed64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedFixed64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedFixed64_);
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     */
-    private void clearRepeatedFixed64() {
-      repeatedFixed64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_SFIXED32_FIELD_NUMBER = 39;
-    private com.google.protobuf.Internal.IntList repeatedSfixed32_;
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @return A list containing the repeatedSfixed32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedSfixed32List() {
-      return repeatedSfixed32_;
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @return The count of repeatedSfixed32.
-     */
-    @java.lang.Override
-    public int getRepeatedSfixed32Count() {
-      return repeatedSfixed32_.size();
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSfixed32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedSfixed32(int index) {
-      return repeatedSfixed32_.getInt(index);
-    }
-    private int repeatedSfixed32MemoizedSerializedSize = -1;
-    private void ensureRepeatedSfixed32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedSfixed32_;
-      if (!tmp.isModifiable()) {
-        repeatedSfixed32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSfixed32 to set.
-     */
-    private void setRepeatedSfixed32(
-        int index, int value) {
-      ensureRepeatedSfixed32IsMutable();
-      repeatedSfixed32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param value The repeatedSfixed32 to add.
-     */
-    private void addRepeatedSfixed32(int value) {
-      ensureRepeatedSfixed32IsMutable();
-      repeatedSfixed32_.addInt(value);
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param values The repeatedSfixed32 to add.
-     */
-    private void addAllRepeatedSfixed32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedSfixed32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedSfixed32_);
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     */
-    private void clearRepeatedSfixed32() {
-      repeatedSfixed32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_SFIXED64_FIELD_NUMBER = 40;
-    private com.google.protobuf.Internal.LongList repeatedSfixed64_;
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @return A list containing the repeatedSfixed64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedSfixed64List() {
-      return repeatedSfixed64_;
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @return The count of repeatedSfixed64.
-     */
-    @java.lang.Override
-    public int getRepeatedSfixed64Count() {
-      return repeatedSfixed64_.size();
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSfixed64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedSfixed64(int index) {
-      return repeatedSfixed64_.getLong(index);
-    }
-    private int repeatedSfixed64MemoizedSerializedSize = -1;
-    private void ensureRepeatedSfixed64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedSfixed64_;
-      if (!tmp.isModifiable()) {
-        repeatedSfixed64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSfixed64 to set.
-     */
-    private void setRepeatedSfixed64(
-        int index, long value) {
-      ensureRepeatedSfixed64IsMutable();
-      repeatedSfixed64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param value The repeatedSfixed64 to add.
-     */
-    private void addRepeatedSfixed64(long value) {
-      ensureRepeatedSfixed64IsMutable();
-      repeatedSfixed64_.addLong(value);
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param values The repeatedSfixed64 to add.
-     */
-    private void addAllRepeatedSfixed64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedSfixed64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedSfixed64_);
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     */
-    private void clearRepeatedSfixed64() {
-      repeatedSfixed64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_FLOAT_FIELD_NUMBER = 41;
-    private com.google.protobuf.Internal.FloatList repeatedFloat_;
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @return A list containing the repeatedFloat.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Float>
-        getRepeatedFloatList() {
-      return repeatedFloat_;
-    }
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @return The count of repeatedFloat.
-     */
-    @java.lang.Override
-    public int getRepeatedFloatCount() {
-      return repeatedFloat_.size();
-    }
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFloat at the given index.
-     */
-    @java.lang.Override
-    public float getRepeatedFloat(int index) {
-      return repeatedFloat_.getFloat(index);
-    }
-    private int repeatedFloatMemoizedSerializedSize = -1;
-    private void ensureRepeatedFloatIsMutable() {
-      com.google.protobuf.Internal.FloatList tmp = repeatedFloat_;
-      if (!tmp.isModifiable()) {
-        repeatedFloat_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFloat to set.
-     */
-    private void setRepeatedFloat(
-        int index, float value) {
-      ensureRepeatedFloatIsMutable();
-      repeatedFloat_.setFloat(index, value);
-    }
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param value The repeatedFloat to add.
-     */
-    private void addRepeatedFloat(float value) {
-      ensureRepeatedFloatIsMutable();
-      repeatedFloat_.addFloat(value);
-    }
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param values The repeatedFloat to add.
-     */
-    private void addAllRepeatedFloat(
-        java.lang.Iterable<? extends java.lang.Float> values) {
-      ensureRepeatedFloatIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedFloat_);
-    }
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     */
-    private void clearRepeatedFloat() {
-      repeatedFloat_ = emptyFloatList();
-    }
-
-    public static final int REPEATED_DOUBLE_FIELD_NUMBER = 42;
-    private com.google.protobuf.Internal.DoubleList repeatedDouble_;
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @return A list containing the repeatedDouble.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Double>
-        getRepeatedDoubleList() {
-      return repeatedDouble_;
-    }
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @return The count of repeatedDouble.
-     */
-    @java.lang.Override
-    public int getRepeatedDoubleCount() {
-      return repeatedDouble_.size();
-    }
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedDouble at the given index.
-     */
-    @java.lang.Override
-    public double getRepeatedDouble(int index) {
-      return repeatedDouble_.getDouble(index);
-    }
-    private int repeatedDoubleMemoizedSerializedSize = -1;
-    private void ensureRepeatedDoubleIsMutable() {
-      com.google.protobuf.Internal.DoubleList tmp = repeatedDouble_;
-      if (!tmp.isModifiable()) {
-        repeatedDouble_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedDouble to set.
-     */
-    private void setRepeatedDouble(
-        int index, double value) {
-      ensureRepeatedDoubleIsMutable();
-      repeatedDouble_.setDouble(index, value);
-    }
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param value The repeatedDouble to add.
-     */
-    private void addRepeatedDouble(double value) {
-      ensureRepeatedDoubleIsMutable();
-      repeatedDouble_.addDouble(value);
-    }
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param values The repeatedDouble to add.
-     */
-    private void addAllRepeatedDouble(
-        java.lang.Iterable<? extends java.lang.Double> values) {
-      ensureRepeatedDoubleIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedDouble_);
-    }
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     */
-    private void clearRepeatedDouble() {
-      repeatedDouble_ = emptyDoubleList();
-    }
-
-    public static final int REPEATED_BOOL_FIELD_NUMBER = 43;
-    private com.google.protobuf.Internal.BooleanList repeatedBool_;
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @return A list containing the repeatedBool.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Boolean>
-        getRepeatedBoolList() {
-      return repeatedBool_;
-    }
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @return The count of repeatedBool.
-     */
-    @java.lang.Override
-    public int getRepeatedBoolCount() {
-      return repeatedBool_.size();
-    }
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedBool at the given index.
-     */
-    @java.lang.Override
-    public boolean getRepeatedBool(int index) {
-      return repeatedBool_.getBoolean(index);
-    }
-    private int repeatedBoolMemoizedSerializedSize = -1;
-    private void ensureRepeatedBoolIsMutable() {
-      com.google.protobuf.Internal.BooleanList tmp = repeatedBool_;
-      if (!tmp.isModifiable()) {
-        repeatedBool_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedBool to set.
-     */
-    private void setRepeatedBool(
-        int index, boolean value) {
-      ensureRepeatedBoolIsMutable();
-      repeatedBool_.setBoolean(index, value);
-    }
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param value The repeatedBool to add.
-     */
-    private void addRepeatedBool(boolean value) {
-      ensureRepeatedBoolIsMutable();
-      repeatedBool_.addBoolean(value);
-    }
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param values The repeatedBool to add.
-     */
-    private void addAllRepeatedBool(
-        java.lang.Iterable<? extends java.lang.Boolean> values) {
-      ensureRepeatedBoolIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedBool_);
-    }
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     */
-    private void clearRepeatedBool() {
-      repeatedBool_ = emptyBooleanList();
-    }
-
-    public static final int REPEATED_STRING_FIELD_NUMBER = 44;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> repeatedString_;
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @return A list containing the repeatedString.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getRepeatedStringList() {
-      return repeatedString_;
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @return The count of repeatedString.
-     */
-    @java.lang.Override
-    public int getRepeatedStringCount() {
-      return repeatedString_.size();
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedString at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getRepeatedString(int index) {
-      return repeatedString_.get(index);
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the repeatedString at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getRepeatedStringBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          repeatedString_.get(index));
-    }
-    private void ensureRepeatedStringIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          repeatedString_;  if (!tmp.isModifiable()) {
-        repeatedString_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedString to set.
-     */
-    private void setRepeatedString(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureRepeatedStringIsMutable();
-      repeatedString_.set(index, value);
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param value The repeatedString to add.
-     */
-    private void addRepeatedString(
-        java.lang.String value) {
-      value.getClass();
-  ensureRepeatedStringIsMutable();
-      repeatedString_.add(value);
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param values The repeatedString to add.
-     */
-    private void addAllRepeatedString(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureRepeatedStringIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedString_);
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     */
-    private void clearRepeatedString() {
-      repeatedString_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param value The bytes of the repeatedString to add.
-     */
-    private void addRepeatedStringBytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      ensureRepeatedStringIsMutable();
-      repeatedString_.add(value.toStringUtf8());
-    }
-
-    public static final int REPEATED_BYTES_FIELD_NUMBER = 45;
-    private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.ByteString> repeatedBytes_;
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @return A list containing the repeatedBytes.
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.ByteString>
-        getRepeatedBytesList() {
-      return repeatedBytes_;
-    }
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @return The count of repeatedBytes.
-     */
-    @java.lang.Override
-    public int getRepeatedBytesCount() {
-      return repeatedBytes_.size();
-    }
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedBytes at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getRepeatedBytes(int index) {
-      return repeatedBytes_.get(index);
-    }
-    private void ensureRepeatedBytesIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<com.google.protobuf.ByteString> tmp = repeatedBytes_;
-      if (!tmp.isModifiable()) {
-        repeatedBytes_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedBytes to set.
-     */
-    private void setRepeatedBytes(
-        int index, com.google.protobuf.ByteString value) {
-      value.getClass();
-  ensureRepeatedBytesIsMutable();
-      repeatedBytes_.set(index, value);
-    }
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param value The repeatedBytes to add.
-     */
-    private void addRepeatedBytes(com.google.protobuf.ByteString value) {
-      value.getClass();
-  ensureRepeatedBytesIsMutable();
-      repeatedBytes_.add(value);
-    }
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param values The repeatedBytes to add.
-     */
-    private void addAllRepeatedBytes(
-        java.lang.Iterable<? extends com.google.protobuf.ByteString> values) {
-      ensureRepeatedBytesIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedBytes_);
-    }
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     */
-    private void clearRepeatedBytes() {
-      repeatedBytes_ = emptyProtobufList();
-    }
-
-    public static final int REPEATED_NESTED_MESSAGE_FIELD_NUMBER = 48;
-    private com.google.protobuf.Internal.ProtobufList<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage> repeatedNestedMessage_;
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    @java.lang.Override
-    public java.util.List<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage> getRepeatedNestedMessageList() {
-      return repeatedNestedMessage_;
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    public java.util.List<? extends proto3_unittest.UnittestProto3.TestAllTypes.NestedMessageOrBuilder> 
-        getRepeatedNestedMessageOrBuilderList() {
-      return repeatedNestedMessage_;
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    @java.lang.Override
-    public int getRepeatedNestedMessageCount() {
-      return repeatedNestedMessage_.size();
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    @java.lang.Override
-    public proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage getRepeatedNestedMessage(int index) {
-      return repeatedNestedMessage_.get(index);
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    public proto3_unittest.UnittestProto3.TestAllTypes.NestedMessageOrBuilder getRepeatedNestedMessageOrBuilder(
-        int index) {
-      return repeatedNestedMessage_.get(index);
-    }
-    private void ensureRepeatedNestedMessageIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage> tmp = repeatedNestedMessage_;
-      if (!tmp.isModifiable()) {
-        repeatedNestedMessage_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    private void setRepeatedNestedMessage(
-        int index, proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  ensureRepeatedNestedMessageIsMutable();
-      repeatedNestedMessage_.set(index, value);
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    private void addRepeatedNestedMessage(proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  ensureRepeatedNestedMessageIsMutable();
-      repeatedNestedMessage_.add(value);
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    private void addRepeatedNestedMessage(
-        int index, proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  ensureRepeatedNestedMessageIsMutable();
-      repeatedNestedMessage_.add(index, value);
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    private void addAllRepeatedNestedMessage(
-        java.lang.Iterable<? extends proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage> values) {
-      ensureRepeatedNestedMessageIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedNestedMessage_);
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    private void clearRepeatedNestedMessage() {
-      repeatedNestedMessage_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    private void removeRepeatedNestedMessage(int index) {
-      ensureRepeatedNestedMessageIsMutable();
-      repeatedNestedMessage_.remove(index);
-    }
-
-    public static final int REPEATED_FOREIGN_MESSAGE_FIELD_NUMBER = 49;
-    private com.google.protobuf.Internal.ProtobufList<proto3_unittest.UnittestProto3.ForeignMessage> repeatedForeignMessage_;
-    /**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    @java.lang.Override
-    public java.util.List<proto3_unittest.UnittestProto3.ForeignMessage> getRepeatedForeignMessageList() {
-      return repeatedForeignMessage_;
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    public java.util.List<? extends proto3_unittest.UnittestProto3.ForeignMessageOrBuilder> 
-        getRepeatedForeignMessageOrBuilderList() {
-      return repeatedForeignMessage_;
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    @java.lang.Override
-    public int getRepeatedForeignMessageCount() {
-      return repeatedForeignMessage_.size();
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    @java.lang.Override
-    public proto3_unittest.UnittestProto3.ForeignMessage getRepeatedForeignMessage(int index) {
-      return repeatedForeignMessage_.get(index);
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    public proto3_unittest.UnittestProto3.ForeignMessageOrBuilder getRepeatedForeignMessageOrBuilder(
-        int index) {
-      return repeatedForeignMessage_.get(index);
-    }
-    private void ensureRepeatedForeignMessageIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<proto3_unittest.UnittestProto3.ForeignMessage> tmp = repeatedForeignMessage_;
-      if (!tmp.isModifiable()) {
-        repeatedForeignMessage_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    private void setRepeatedForeignMessage(
-        int index, proto3_unittest.UnittestProto3.ForeignMessage value) {
-      value.getClass();
-  ensureRepeatedForeignMessageIsMutable();
-      repeatedForeignMessage_.set(index, value);
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    private void addRepeatedForeignMessage(proto3_unittest.UnittestProto3.ForeignMessage value) {
-      value.getClass();
-  ensureRepeatedForeignMessageIsMutable();
-      repeatedForeignMessage_.add(value);
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    private void addRepeatedForeignMessage(
-        int index, proto3_unittest.UnittestProto3.ForeignMessage value) {
-      value.getClass();
-  ensureRepeatedForeignMessageIsMutable();
-      repeatedForeignMessage_.add(index, value);
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    private void addAllRepeatedForeignMessage(
-        java.lang.Iterable<? extends proto3_unittest.UnittestProto3.ForeignMessage> values) {
-      ensureRepeatedForeignMessageIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedForeignMessage_);
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    private void clearRepeatedForeignMessage() {
-      repeatedForeignMessage_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    private void removeRepeatedForeignMessage(int index) {
-      ensureRepeatedForeignMessageIsMutable();
-      repeatedForeignMessage_.remove(index);
-    }
-
-    public static final int REPEATED_IMPORT_MESSAGE_FIELD_NUMBER = 50;
-    private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.test.UnittestImport.ImportMessage> repeatedImportMessage_;
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.test.UnittestImport.ImportMessage> getRepeatedImportMessageList() {
-      return repeatedImportMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    public java.util.List<? extends com.google.protobuf.test.UnittestImport.ImportMessageOrBuilder> 
-        getRepeatedImportMessageOrBuilderList() {
-      return repeatedImportMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    @java.lang.Override
-    public int getRepeatedImportMessageCount() {
-      return repeatedImportMessage_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.test.UnittestImport.ImportMessage getRepeatedImportMessage(int index) {
-      return repeatedImportMessage_.get(index);
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    public com.google.protobuf.test.UnittestImport.ImportMessageOrBuilder getRepeatedImportMessageOrBuilder(
-        int index) {
-      return repeatedImportMessage_.get(index);
-    }
-    private void ensureRepeatedImportMessageIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<com.google.protobuf.test.UnittestImport.ImportMessage> tmp = repeatedImportMessage_;
-      if (!tmp.isModifiable()) {
-        repeatedImportMessage_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    private void setRepeatedImportMessage(
-        int index, com.google.protobuf.test.UnittestImport.ImportMessage value) {
-      value.getClass();
-  ensureRepeatedImportMessageIsMutable();
-      repeatedImportMessage_.set(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    private void addRepeatedImportMessage(com.google.protobuf.test.UnittestImport.ImportMessage value) {
-      value.getClass();
-  ensureRepeatedImportMessageIsMutable();
-      repeatedImportMessage_.add(value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    private void addRepeatedImportMessage(
-        int index, com.google.protobuf.test.UnittestImport.ImportMessage value) {
-      value.getClass();
-  ensureRepeatedImportMessageIsMutable();
-      repeatedImportMessage_.add(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    private void addAllRepeatedImportMessage(
-        java.lang.Iterable<? extends com.google.protobuf.test.UnittestImport.ImportMessage> values) {
-      ensureRepeatedImportMessageIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedImportMessage_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    private void clearRepeatedImportMessage() {
-      repeatedImportMessage_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    private void removeRepeatedImportMessage(int index) {
-      ensureRepeatedImportMessageIsMutable();
-      repeatedImportMessage_.remove(index);
-    }
-
-    public static final int REPEATED_NESTED_ENUM_FIELD_NUMBER = 51;
-    private com.google.protobuf.Internal.IntList repeatedNestedEnum_;
-    private static final com.google.protobuf.Internal.ListAdapter.Converter<
-        java.lang.Integer, proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum> repeatedNestedEnum_converter_ =
-            new com.google.protobuf.Internal.ListAdapter.Converter<
-                java.lang.Integer, proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum>() {
-              @java.lang.Override
-              public proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum convert(java.lang.Integer from) {
-                proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum result = proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum.forNumber(from);
-                return result == null ? proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum.UNRECOGNIZED : result;
-              }
-            };
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @return A list containing the repeatedNestedEnum.
-     */
-    @java.lang.Override
-    public java.util.List<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum> getRepeatedNestedEnumList() {
-      return new com.google.protobuf.Internal.ListAdapter<
-          java.lang.Integer, proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum>(repeatedNestedEnum_, repeatedNestedEnum_converter_);
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @return The count of repeatedNestedEnum.
-     */
-    @java.lang.Override
-    public int getRepeatedNestedEnumCount() {
-      return repeatedNestedEnum_.size();
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedNestedEnum at the given index.
-     */
-    @java.lang.Override
-    public proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum getRepeatedNestedEnum(int index) {
-      return repeatedNestedEnum_converter_.convert(repeatedNestedEnum_.getInt(index));
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @return A list containing the enum numeric values on the wire for repeatedNestedEnum.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-    getRepeatedNestedEnumValueList() {
-      return repeatedNestedEnum_;
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param index The index of the value to return.
-     * @return The enum numeric value on the wire of repeatedNestedEnum at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedNestedEnumValue(int index) {
-      return repeatedNestedEnum_.getInt(index);
-    }
-    private int repeatedNestedEnumMemoizedSerializedSize;
-    private void ensureRepeatedNestedEnumIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedNestedEnum_;
-      if (!tmp.isModifiable()) {
-        repeatedNestedEnum_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-      }
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedNestedEnum to set.
-     */
-    private void setRepeatedNestedEnum(
-        int index, proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum value) {
-      value.getClass();
-  ensureRepeatedNestedEnumIsMutable();
-      repeatedNestedEnum_.setInt(index, value.getNumber());
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param value The repeatedNestedEnum to add.
-     */
-    private void addRepeatedNestedEnum(proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum value) {
-      value.getClass();
-  ensureRepeatedNestedEnumIsMutable();
-      repeatedNestedEnum_.addInt(value.getNumber());
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param values The repeatedNestedEnum to add.
-     */
-    private void addAllRepeatedNestedEnum(
-        java.lang.Iterable<? extends proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum> values) {
-      ensureRepeatedNestedEnumIsMutable();
-      for (proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum value : values) {
-        repeatedNestedEnum_.addInt(value.getNumber());
-      }
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     */
-    private void clearRepeatedNestedEnum() {
-      repeatedNestedEnum_ = emptyIntList();
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param value The enum numeric value on the wire for repeatedNestedEnum to set.
-     */
-    private void setRepeatedNestedEnumValue(
-        int index, int value) {
-      ensureRepeatedNestedEnumIsMutable();
-      repeatedNestedEnum_.setInt(index, value);
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param value The enum numeric value on the wire for repeatedNestedEnum to add.
-     */
-    private void addRepeatedNestedEnumValue(int value) {
-      ensureRepeatedNestedEnumIsMutable();
-      repeatedNestedEnum_.addInt(value);
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param values The enum numeric values on the wire for repeatedNestedEnum to add.
-     */
-    private void addAllRepeatedNestedEnumValue(
-        java.lang.Iterable<java.lang.Integer> values) {
-      ensureRepeatedNestedEnumIsMutable();
-      for (int value : values) {
-        repeatedNestedEnum_.addInt(value);
-      }
-    }
-
-    public static final int REPEATED_FOREIGN_ENUM_FIELD_NUMBER = 52;
-    private com.google.protobuf.Internal.IntList repeatedForeignEnum_;
-    private static final com.google.protobuf.Internal.ListAdapter.Converter<
-        java.lang.Integer, proto3_unittest.UnittestProto3.ForeignEnum> repeatedForeignEnum_converter_ =
-            new com.google.protobuf.Internal.ListAdapter.Converter<
-                java.lang.Integer, proto3_unittest.UnittestProto3.ForeignEnum>() {
-              @java.lang.Override
-              public proto3_unittest.UnittestProto3.ForeignEnum convert(java.lang.Integer from) {
-                proto3_unittest.UnittestProto3.ForeignEnum result = proto3_unittest.UnittestProto3.ForeignEnum.forNumber(from);
-                return result == null ? proto3_unittest.UnittestProto3.ForeignEnum.UNRECOGNIZED : result;
-              }
-            };
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @return A list containing the repeatedForeignEnum.
-     */
-    @java.lang.Override
-    public java.util.List<proto3_unittest.UnittestProto3.ForeignEnum> getRepeatedForeignEnumList() {
-      return new com.google.protobuf.Internal.ListAdapter<
-          java.lang.Integer, proto3_unittest.UnittestProto3.ForeignEnum>(repeatedForeignEnum_, repeatedForeignEnum_converter_);
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @return The count of repeatedForeignEnum.
-     */
-    @java.lang.Override
-    public int getRepeatedForeignEnumCount() {
-      return repeatedForeignEnum_.size();
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedForeignEnum at the given index.
-     */
-    @java.lang.Override
-    public proto3_unittest.UnittestProto3.ForeignEnum getRepeatedForeignEnum(int index) {
-      return repeatedForeignEnum_converter_.convert(repeatedForeignEnum_.getInt(index));
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @return A list containing the enum numeric values on the wire for repeatedForeignEnum.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-    getRepeatedForeignEnumValueList() {
-      return repeatedForeignEnum_;
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param index The index of the value to return.
-     * @return The enum numeric value on the wire of repeatedForeignEnum at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedForeignEnumValue(int index) {
-      return repeatedForeignEnum_.getInt(index);
-    }
-    private int repeatedForeignEnumMemoizedSerializedSize;
-    private void ensureRepeatedForeignEnumIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedForeignEnum_;
-      if (!tmp.isModifiable()) {
-        repeatedForeignEnum_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-      }
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedForeignEnum to set.
-     */
-    private void setRepeatedForeignEnum(
-        int index, proto3_unittest.UnittestProto3.ForeignEnum value) {
-      value.getClass();
-  ensureRepeatedForeignEnumIsMutable();
-      repeatedForeignEnum_.setInt(index, value.getNumber());
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param value The repeatedForeignEnum to add.
-     */
-    private void addRepeatedForeignEnum(proto3_unittest.UnittestProto3.ForeignEnum value) {
-      value.getClass();
-  ensureRepeatedForeignEnumIsMutable();
-      repeatedForeignEnum_.addInt(value.getNumber());
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param values The repeatedForeignEnum to add.
-     */
-    private void addAllRepeatedForeignEnum(
-        java.lang.Iterable<? extends proto3_unittest.UnittestProto3.ForeignEnum> values) {
-      ensureRepeatedForeignEnumIsMutable();
-      for (proto3_unittest.UnittestProto3.ForeignEnum value : values) {
-        repeatedForeignEnum_.addInt(value.getNumber());
-      }
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     */
-    private void clearRepeatedForeignEnum() {
-      repeatedForeignEnum_ = emptyIntList();
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param value The enum numeric value on the wire for repeatedForeignEnum to set.
-     */
-    private void setRepeatedForeignEnumValue(
-        int index, int value) {
-      ensureRepeatedForeignEnumIsMutable();
-      repeatedForeignEnum_.setInt(index, value);
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param value The enum numeric value on the wire for repeatedForeignEnum to add.
-     */
-    private void addRepeatedForeignEnumValue(int value) {
-      ensureRepeatedForeignEnumIsMutable();
-      repeatedForeignEnum_.addInt(value);
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param values The enum numeric values on the wire for repeatedForeignEnum to add.
-     */
-    private void addAllRepeatedForeignEnumValue(
-        java.lang.Iterable<java.lang.Integer> values) {
-      ensureRepeatedForeignEnumIsMutable();
-      for (int value : values) {
-        repeatedForeignEnum_.addInt(value);
-      }
-    }
-
-    public static final int REPEATED_STRING_PIECE_FIELD_NUMBER = 54;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> repeatedStringPiece_;
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @return A list containing the repeatedStringPiece.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getRepeatedStringPieceList() {
-      return repeatedStringPiece_;
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @return The count of repeatedStringPiece.
-     */
-    @java.lang.Override
-    public int getRepeatedStringPieceCount() {
-      return repeatedStringPiece_.size();
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedStringPiece at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getRepeatedStringPiece(int index) {
-      return repeatedStringPiece_.get(index);
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the repeatedStringPiece at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getRepeatedStringPieceBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          repeatedStringPiece_.get(index));
-    }
-    private void ensureRepeatedStringPieceIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          repeatedStringPiece_;  if (!tmp.isModifiable()) {
-        repeatedStringPiece_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedStringPiece to set.
-     */
-    private void setRepeatedStringPiece(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureRepeatedStringPieceIsMutable();
-      repeatedStringPiece_.set(index, value);
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param value The repeatedStringPiece to add.
-     */
-    private void addRepeatedStringPiece(
-        java.lang.String value) {
-      value.getClass();
-  ensureRepeatedStringPieceIsMutable();
-      repeatedStringPiece_.add(value);
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param values The repeatedStringPiece to add.
-     */
-    private void addAllRepeatedStringPiece(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureRepeatedStringPieceIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedStringPiece_);
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     */
-    private void clearRepeatedStringPiece() {
-      repeatedStringPiece_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param value The bytes of the repeatedStringPiece to add.
-     */
-    private void addRepeatedStringPieceBytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      ensureRepeatedStringPieceIsMutable();
-      repeatedStringPiece_.add(value.toStringUtf8());
-    }
-
-    public static final int REPEATED_CORD_FIELD_NUMBER = 55;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> repeatedCord_;
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @return A list containing the repeatedCord.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getRepeatedCordList() {
-      return repeatedCord_;
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @return The count of repeatedCord.
-     */
-    @java.lang.Override
-    public int getRepeatedCordCount() {
-      return repeatedCord_.size();
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedCord at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getRepeatedCord(int index) {
-      return repeatedCord_.get(index);
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the repeatedCord at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getRepeatedCordBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          repeatedCord_.get(index));
-    }
-    private void ensureRepeatedCordIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          repeatedCord_;  if (!tmp.isModifiable()) {
-        repeatedCord_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedCord to set.
-     */
-    private void setRepeatedCord(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureRepeatedCordIsMutable();
-      repeatedCord_.set(index, value);
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param value The repeatedCord to add.
-     */
-    private void addRepeatedCord(
-        java.lang.String value) {
-      value.getClass();
-  ensureRepeatedCordIsMutable();
-      repeatedCord_.add(value);
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param values The repeatedCord to add.
-     */
-    private void addAllRepeatedCord(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureRepeatedCordIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedCord_);
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     */
-    private void clearRepeatedCord() {
-      repeatedCord_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param value The bytes of the repeatedCord to add.
-     */
-    private void addRepeatedCordBytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      ensureRepeatedCordIsMutable();
-      repeatedCord_.add(value.toStringUtf8());
-    }
-
-    public static final int REPEATED_LAZY_MESSAGE_FIELD_NUMBER = 57;
-    private com.google.protobuf.Internal.ProtobufList<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage> repeatedLazyMessage_;
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public java.util.List<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage> getRepeatedLazyMessageList() {
-      return repeatedLazyMessage_;
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    public java.util.List<? extends proto3_unittest.UnittestProto3.TestAllTypes.NestedMessageOrBuilder> 
-        getRepeatedLazyMessageOrBuilderList() {
-      return repeatedLazyMessage_;
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public int getRepeatedLazyMessageCount() {
-      return repeatedLazyMessage_.size();
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage getRepeatedLazyMessage(int index) {
-      return repeatedLazyMessage_.get(index);
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    public proto3_unittest.UnittestProto3.TestAllTypes.NestedMessageOrBuilder getRepeatedLazyMessageOrBuilder(
-        int index) {
-      return repeatedLazyMessage_.get(index);
-    }
-    private void ensureRepeatedLazyMessageIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage> tmp = repeatedLazyMessage_;
-      if (!tmp.isModifiable()) {
-        repeatedLazyMessage_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    private void setRepeatedLazyMessage(
-        int index, proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  ensureRepeatedLazyMessageIsMutable();
-      repeatedLazyMessage_.set(index, value);
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    private void addRepeatedLazyMessage(proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  ensureRepeatedLazyMessageIsMutable();
-      repeatedLazyMessage_.add(value);
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    private void addRepeatedLazyMessage(
-        int index, proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  ensureRepeatedLazyMessageIsMutable();
-      repeatedLazyMessage_.add(index, value);
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    private void addAllRepeatedLazyMessage(
-        java.lang.Iterable<? extends proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage> values) {
-      ensureRepeatedLazyMessageIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedLazyMessage_);
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    private void clearRepeatedLazyMessage() {
-      repeatedLazyMessage_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    private void removeRepeatedLazyMessage(int index) {
-      ensureRepeatedLazyMessageIsMutable();
-      repeatedLazyMessage_.remove(index);
-    }
-
-    public static final int ONEOF_UINT32_FIELD_NUMBER = 111;
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     * @return Whether the oneofUint32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofUint32() {
-      return oneofFieldCase_ == 111;
-    }
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     * @return The oneofUint32.
-     */
-    @java.lang.Override
-    public int getOneofUint32() {
-      if (oneofFieldCase_ == 111) {
-        return (java.lang.Integer) oneofField_;
-      }
-      return 0;
-    }
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     * @param value The oneofUint32 to set.
-     */
-    private void setOneofUint32(int value) {
-      oneofFieldCase_ = 111;
-      oneofField_ = value;
-    }
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     */
-    private void clearOneofUint32() {
-      if (oneofFieldCase_ == 111) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static final int ONEOF_NESTED_MESSAGE_FIELD_NUMBER = 112;
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-     */
-    @java.lang.Override
-    public boolean hasOneofNestedMessage() {
-      return oneofFieldCase_ == 112;
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-     */
-    @java.lang.Override
-    public proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage getOneofNestedMessage() {
-      if (oneofFieldCase_ == 112) {
-         return (proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage) oneofField_;
-      }
-      return proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.getDefaultInstance();
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-     */
-    private void setOneofNestedMessage(proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  oneofField_ = value;
-      oneofFieldCase_ = 112;
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-     */
-    private void mergeOneofNestedMessage(proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  if (oneofFieldCase_ == 112 &&
-          oneofField_ != proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.getDefaultInstance()) {
-        oneofField_ = proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.newBuilder((proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage) oneofField_)
-            .mergeFrom(value).buildPartial();
-      } else {
-        oneofField_ = value;
-      }
-      oneofFieldCase_ = 112;
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-     */
-    private void clearOneofNestedMessage() {
-      if (oneofFieldCase_ == 112) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static final int ONEOF_STRING_FIELD_NUMBER = 113;
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return Whether the oneofString field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofString() {
-      return oneofFieldCase_ == 113;
-    }
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return The oneofString.
-     */
-    @java.lang.Override
-    public java.lang.String getOneofString() {
-      java.lang.String ref = "";
-      if (oneofFieldCase_ == 113) {
-        ref = (java.lang.String) oneofField_;
-      }
-      return ref;
-    }
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return The bytes for oneofString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOneofStringBytes() {
-      java.lang.String ref = "";
-      if (oneofFieldCase_ == 113) {
-        ref = (java.lang.String) oneofField_;
-      }
-      return com.google.protobuf.ByteString.copyFromUtf8(ref);
-    }
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @param value The oneofString to set.
-     */
-    private void setOneofString(
-        java.lang.String value) {
-      value.getClass();
-  oneofFieldCase_ = 113;
-      oneofField_ = value;
-    }
-    /**
-     * <code>string oneof_string = 113;</code>
-     */
-    private void clearOneofString() {
-      if (oneofFieldCase_ == 113) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @param value The bytes for oneofString to set.
-     */
-    private void setOneofStringBytes(
-        com.google.protobuf.ByteString value) {
-      checkByteStringIsUtf8(value);
-      oneofField_ = value.toStringUtf8();
-      oneofFieldCase_ = 113;
-    }
-
-    public static final int ONEOF_BYTES_FIELD_NUMBER = 114;
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     * @return Whether the oneofBytes field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofBytes() {
-      return oneofFieldCase_ == 114;
-    }
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     * @return The oneofBytes.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getOneofBytes() {
-      if (oneofFieldCase_ == 114) {
-        return (com.google.protobuf.ByteString) oneofField_;
-      }
-      return com.google.protobuf.ByteString.EMPTY;
-    }
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     * @param value The oneofBytes to set.
-     */
-    private void setOneofBytes(com.google.protobuf.ByteString value) {
-      value.getClass();
-  oneofFieldCase_ = 114;
-      oneofField_ = value;
-    }
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     */
-    private void clearOneofBytes() {
-      if (oneofFieldCase_ == 114) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static proto3_unittest.UnittestProto3.TestAllTypes parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.TestAllTypes parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestAllTypes parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.TestAllTypes parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestAllTypes parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.TestAllTypes parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestAllTypes parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.TestAllTypes parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestAllTypes parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.TestAllTypes parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestAllTypes parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.TestAllTypes parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(proto3_unittest.UnittestProto3.TestAllTypes prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * This proto includes every type of field in both singular and repeated
-     * forms.
-     * </pre>
-     *
-     * Protobuf type {@code proto3_unittest.TestAllTypes}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          proto3_unittest.UnittestProto3.TestAllTypes, Builder> implements
-        // @@protoc_insertion_point(builder_implements:proto3_unittest.TestAllTypes)
-        proto3_unittest.UnittestProto3.TestAllTypesOrBuilder {
-      // Construct using proto3_unittest.UnittestProto3.TestAllTypes.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-      @java.lang.Override
-      public OneofFieldCase
-          getOneofFieldCase() {
-        return instance.getOneofFieldCase();
-      }
-
-      public Builder clearOneofField() {
-        copyOnWrite();
-        instance.clearOneofField();
-        return this;
-      }
-
-
-      /**
-       * <pre>
-       * Singular
-       * </pre>
-       *
-       * <code>int32 optional_int32 = 1;</code>
-       * @return The optionalInt32.
-       */
-      @java.lang.Override
-      public int getOptionalInt32() {
-        return instance.getOptionalInt32();
-      }
-      /**
-       * <pre>
-       * Singular
-       * </pre>
-       *
-       * <code>int32 optional_int32 = 1;</code>
-       * @param value The optionalInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalInt32(int value) {
-        copyOnWrite();
-        instance.setOptionalInt32(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Singular
-       * </pre>
-       *
-       * <code>int32 optional_int32 = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalInt32() {
-        copyOnWrite();
-        instance.clearOptionalInt32();
-        return this;
-      }
-
-      /**
-       * <code>int64 optional_int64 = 2;</code>
-       * @return The optionalInt64.
-       */
-      @java.lang.Override
-      public long getOptionalInt64() {
-        return instance.getOptionalInt64();
-      }
-      /**
-       * <code>int64 optional_int64 = 2;</code>
-       * @param value The optionalInt64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalInt64(long value) {
-        copyOnWrite();
-        instance.setOptionalInt64(value);
-        return this;
-      }
-      /**
-       * <code>int64 optional_int64 = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalInt64() {
-        copyOnWrite();
-        instance.clearOptionalInt64();
-        return this;
-      }
-
-      /**
-       * <code>uint32 optional_uint32 = 3;</code>
-       * @return The optionalUint32.
-       */
-      @java.lang.Override
-      public int getOptionalUint32() {
-        return instance.getOptionalUint32();
-      }
-      /**
-       * <code>uint32 optional_uint32 = 3;</code>
-       * @param value The optionalUint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalUint32(int value) {
-        copyOnWrite();
-        instance.setOptionalUint32(value);
-        return this;
-      }
-      /**
-       * <code>uint32 optional_uint32 = 3;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalUint32() {
-        copyOnWrite();
-        instance.clearOptionalUint32();
-        return this;
-      }
-
-      /**
-       * <code>uint64 optional_uint64 = 4;</code>
-       * @return The optionalUint64.
-       */
-      @java.lang.Override
-      public long getOptionalUint64() {
-        return instance.getOptionalUint64();
-      }
-      /**
-       * <code>uint64 optional_uint64 = 4;</code>
-       * @param value The optionalUint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalUint64(long value) {
-        copyOnWrite();
-        instance.setOptionalUint64(value);
-        return this;
-      }
-      /**
-       * <code>uint64 optional_uint64 = 4;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalUint64() {
-        copyOnWrite();
-        instance.clearOptionalUint64();
-        return this;
-      }
-
-      /**
-       * <code>sint32 optional_sint32 = 5;</code>
-       * @return The optionalSint32.
-       */
-      @java.lang.Override
-      public int getOptionalSint32() {
-        return instance.getOptionalSint32();
-      }
-      /**
-       * <code>sint32 optional_sint32 = 5;</code>
-       * @param value The optionalSint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalSint32(int value) {
-        copyOnWrite();
-        instance.setOptionalSint32(value);
-        return this;
-      }
-      /**
-       * <code>sint32 optional_sint32 = 5;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalSint32() {
-        copyOnWrite();
-        instance.clearOptionalSint32();
-        return this;
-      }
-
-      /**
-       * <code>sint64 optional_sint64 = 6;</code>
-       * @return The optionalSint64.
-       */
-      @java.lang.Override
-      public long getOptionalSint64() {
-        return instance.getOptionalSint64();
-      }
-      /**
-       * <code>sint64 optional_sint64 = 6;</code>
-       * @param value The optionalSint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalSint64(long value) {
-        copyOnWrite();
-        instance.setOptionalSint64(value);
-        return this;
-      }
-      /**
-       * <code>sint64 optional_sint64 = 6;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalSint64() {
-        copyOnWrite();
-        instance.clearOptionalSint64();
-        return this;
-      }
-
-      /**
-       * <code>fixed32 optional_fixed32 = 7;</code>
-       * @return The optionalFixed32.
-       */
-      @java.lang.Override
-      public int getOptionalFixed32() {
-        return instance.getOptionalFixed32();
-      }
-      /**
-       * <code>fixed32 optional_fixed32 = 7;</code>
-       * @param value The optionalFixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalFixed32(int value) {
-        copyOnWrite();
-        instance.setOptionalFixed32(value);
-        return this;
-      }
-      /**
-       * <code>fixed32 optional_fixed32 = 7;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalFixed32() {
-        copyOnWrite();
-        instance.clearOptionalFixed32();
-        return this;
-      }
-
-      /**
-       * <code>fixed64 optional_fixed64 = 8;</code>
-       * @return The optionalFixed64.
-       */
-      @java.lang.Override
-      public long getOptionalFixed64() {
-        return instance.getOptionalFixed64();
-      }
-      /**
-       * <code>fixed64 optional_fixed64 = 8;</code>
-       * @param value The optionalFixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalFixed64(long value) {
-        copyOnWrite();
-        instance.setOptionalFixed64(value);
-        return this;
-      }
-      /**
-       * <code>fixed64 optional_fixed64 = 8;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalFixed64() {
-        copyOnWrite();
-        instance.clearOptionalFixed64();
-        return this;
-      }
-
-      /**
-       * <code>sfixed32 optional_sfixed32 = 9;</code>
-       * @return The optionalSfixed32.
-       */
-      @java.lang.Override
-      public int getOptionalSfixed32() {
-        return instance.getOptionalSfixed32();
-      }
-      /**
-       * <code>sfixed32 optional_sfixed32 = 9;</code>
-       * @param value The optionalSfixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalSfixed32(int value) {
-        copyOnWrite();
-        instance.setOptionalSfixed32(value);
-        return this;
-      }
-      /**
-       * <code>sfixed32 optional_sfixed32 = 9;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalSfixed32() {
-        copyOnWrite();
-        instance.clearOptionalSfixed32();
-        return this;
-      }
-
-      /**
-       * <code>sfixed64 optional_sfixed64 = 10;</code>
-       * @return The optionalSfixed64.
-       */
-      @java.lang.Override
-      public long getOptionalSfixed64() {
-        return instance.getOptionalSfixed64();
-      }
-      /**
-       * <code>sfixed64 optional_sfixed64 = 10;</code>
-       * @param value The optionalSfixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalSfixed64(long value) {
-        copyOnWrite();
-        instance.setOptionalSfixed64(value);
-        return this;
-      }
-      /**
-       * <code>sfixed64 optional_sfixed64 = 10;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalSfixed64() {
-        copyOnWrite();
-        instance.clearOptionalSfixed64();
-        return this;
-      }
-
-      /**
-       * <code>float optional_float = 11;</code>
-       * @return The optionalFloat.
-       */
-      @java.lang.Override
-      public float getOptionalFloat() {
-        return instance.getOptionalFloat();
-      }
-      /**
-       * <code>float optional_float = 11;</code>
-       * @param value The optionalFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalFloat(float value) {
-        copyOnWrite();
-        instance.setOptionalFloat(value);
-        return this;
-      }
-      /**
-       * <code>float optional_float = 11;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalFloat() {
-        copyOnWrite();
-        instance.clearOptionalFloat();
-        return this;
-      }
-
-      /**
-       * <code>double optional_double = 12;</code>
-       * @return The optionalDouble.
-       */
-      @java.lang.Override
-      public double getOptionalDouble() {
-        return instance.getOptionalDouble();
-      }
-      /**
-       * <code>double optional_double = 12;</code>
-       * @param value The optionalDouble to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalDouble(double value) {
-        copyOnWrite();
-        instance.setOptionalDouble(value);
-        return this;
-      }
-      /**
-       * <code>double optional_double = 12;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalDouble() {
-        copyOnWrite();
-        instance.clearOptionalDouble();
-        return this;
-      }
-
-      /**
-       * <code>bool optional_bool = 13;</code>
-       * @return The optionalBool.
-       */
-      @java.lang.Override
-      public boolean getOptionalBool() {
-        return instance.getOptionalBool();
-      }
-      /**
-       * <code>bool optional_bool = 13;</code>
-       * @param value The optionalBool to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalBool(boolean value) {
-        copyOnWrite();
-        instance.setOptionalBool(value);
-        return this;
-      }
-      /**
-       * <code>bool optional_bool = 13;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalBool() {
-        copyOnWrite();
-        instance.clearOptionalBool();
-        return this;
-      }
-
-      /**
-       * <code>string optional_string = 14;</code>
-       * @return The optionalString.
-       */
-      @java.lang.Override
-      public java.lang.String getOptionalString() {
-        return instance.getOptionalString();
-      }
-      /**
-       * <code>string optional_string = 14;</code>
-       * @return The bytes for optionalString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getOptionalStringBytes() {
-        return instance.getOptionalStringBytes();
-      }
-      /**
-       * <code>string optional_string = 14;</code>
-       * @param value The optionalString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setOptionalString(value);
-        return this;
-      }
-      /**
-       * <code>string optional_string = 14;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalString() {
-        copyOnWrite();
-        instance.clearOptionalString();
-        return this;
-      }
-      /**
-       * <code>string optional_string = 14;</code>
-       * @param value The bytes for optionalString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOptionalStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>bytes optional_bytes = 15;</code>
-       * @return The optionalBytes.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getOptionalBytes() {
-        return instance.getOptionalBytes();
-      }
-      /**
-       * <code>bytes optional_bytes = 15;</code>
-       * @param value The optionalBytes to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalBytes(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOptionalBytes(value);
-        return this;
-      }
-      /**
-       * <code>bytes optional_bytes = 15;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalBytes() {
-        copyOnWrite();
-        instance.clearOptionalBytes();
-        return this;
-      }
-
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalNestedMessage() {
-        return instance.hasOptionalNestedMessage();
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-       */
-      @java.lang.Override
-      public proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage getOptionalNestedMessage() {
-        return instance.getOptionalNestedMessage();
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-       */
-      public Builder setOptionalNestedMessage(proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.setOptionalNestedMessage(value);
-        return this;
-        }
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-       */
-      public Builder setOptionalNestedMessage(
-          proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalNestedMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-       */
-      public Builder mergeOptionalNestedMessage(proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.mergeOptionalNestedMessage(value);
-        return this;
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-       */
-      public Builder clearOptionalNestedMessage() {  copyOnWrite();
-        instance.clearOptionalNestedMessage();
-        return this;
-      }
-
-      /**
-       * <code>.proto3_unittest.ForeignMessage optional_foreign_message = 19;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalForeignMessage() {
-        return instance.hasOptionalForeignMessage();
-      }
-      /**
-       * <code>.proto3_unittest.ForeignMessage optional_foreign_message = 19;</code>
-       */
-      @java.lang.Override
-      public proto3_unittest.UnittestProto3.ForeignMessage getOptionalForeignMessage() {
-        return instance.getOptionalForeignMessage();
-      }
-      /**
-       * <code>.proto3_unittest.ForeignMessage optional_foreign_message = 19;</code>
-       */
-      public Builder setOptionalForeignMessage(proto3_unittest.UnittestProto3.ForeignMessage value) {
-        copyOnWrite();
-        instance.setOptionalForeignMessage(value);
-        return this;
-        }
-      /**
-       * <code>.proto3_unittest.ForeignMessage optional_foreign_message = 19;</code>
-       */
-      public Builder setOptionalForeignMessage(
-          proto3_unittest.UnittestProto3.ForeignMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalForeignMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.proto3_unittest.ForeignMessage optional_foreign_message = 19;</code>
-       */
-      public Builder mergeOptionalForeignMessage(proto3_unittest.UnittestProto3.ForeignMessage value) {
-        copyOnWrite();
-        instance.mergeOptionalForeignMessage(value);
-        return this;
-      }
-      /**
-       * <code>.proto3_unittest.ForeignMessage optional_foreign_message = 19;</code>
-       */
-      public Builder clearOptionalForeignMessage() {  copyOnWrite();
-        instance.clearOptionalForeignMessage();
-        return this;
-      }
-
-      /**
-       * <code>.protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalImportMessage() {
-        return instance.hasOptionalImportMessage();
-      }
-      /**
-       * <code>.protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.test.UnittestImport.ImportMessage getOptionalImportMessage() {
-        return instance.getOptionalImportMessage();
-      }
-      /**
-       * <code>.protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-       */
-      public Builder setOptionalImportMessage(com.google.protobuf.test.UnittestImport.ImportMessage value) {
-        copyOnWrite();
-        instance.setOptionalImportMessage(value);
-        return this;
-        }
-      /**
-       * <code>.protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-       */
-      public Builder setOptionalImportMessage(
-          com.google.protobuf.test.UnittestImport.ImportMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalImportMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-       */
-      public Builder mergeOptionalImportMessage(com.google.protobuf.test.UnittestImport.ImportMessage value) {
-        copyOnWrite();
-        instance.mergeOptionalImportMessage(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-       */
-      public Builder clearOptionalImportMessage() {  copyOnWrite();
-        instance.clearOptionalImportMessage();
-        return this;
-      }
-
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-       * @return The enum numeric value on the wire for optionalNestedEnum.
-       */
-      @java.lang.Override
-      public int getOptionalNestedEnumValue() {
-        return instance.getOptionalNestedEnumValue();
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-       * @param value The optionalNestedEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalNestedEnumValue(int value) {
-        copyOnWrite();
-        instance.setOptionalNestedEnumValue(value);
-        return this;
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-       * @return The optionalNestedEnum.
-       */
-      @java.lang.Override
-      public proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum getOptionalNestedEnum() {
-        return instance.getOptionalNestedEnum();
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-       * @param value The enum numeric value on the wire for optionalNestedEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalNestedEnum(proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum value) {
-        copyOnWrite();
-        instance.setOptionalNestedEnum(value);
-        return this;
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalNestedEnum() {
-        copyOnWrite();
-        instance.clearOptionalNestedEnum();
-        return this;
-      }
-
-      /**
-       * <code>.proto3_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-       * @return The enum numeric value on the wire for optionalForeignEnum.
-       */
-      @java.lang.Override
-      public int getOptionalForeignEnumValue() {
-        return instance.getOptionalForeignEnumValue();
-      }
-      /**
-       * <code>.proto3_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-       * @param value The optionalForeignEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalForeignEnumValue(int value) {
-        copyOnWrite();
-        instance.setOptionalForeignEnumValue(value);
-        return this;
-      }
-      /**
-       * <code>.proto3_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-       * @return The optionalForeignEnum.
-       */
-      @java.lang.Override
-      public proto3_unittest.UnittestProto3.ForeignEnum getOptionalForeignEnum() {
-        return instance.getOptionalForeignEnum();
-      }
-      /**
-       * <code>.proto3_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-       * @param value The enum numeric value on the wire for optionalForeignEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalForeignEnum(proto3_unittest.UnittestProto3.ForeignEnum value) {
-        copyOnWrite();
-        instance.setOptionalForeignEnum(value);
-        return this;
-      }
-      /**
-       * <code>.proto3_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalForeignEnum() {
-        copyOnWrite();
-        instance.clearOptionalForeignEnum();
-        return this;
-      }
-
-      /**
-       * <code>string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-       * @return The optionalStringPiece.
-       */
-      @java.lang.Override
-      public java.lang.String getOptionalStringPiece() {
-        return instance.getOptionalStringPiece();
-      }
-      /**
-       * <code>string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-       * @return The bytes for optionalStringPiece.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getOptionalStringPieceBytes() {
-        return instance.getOptionalStringPieceBytes();
-      }
-      /**
-       * <code>string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-       * @param value The optionalStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalStringPiece(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setOptionalStringPiece(value);
-        return this;
-      }
-      /**
-       * <code>string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalStringPiece() {
-        copyOnWrite();
-        instance.clearOptionalStringPiece();
-        return this;
-      }
-      /**
-       * <code>string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-       * @param value The bytes for optionalStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalStringPieceBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOptionalStringPieceBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>string optional_cord = 25 [ctype = CORD];</code>
-       * @return The optionalCord.
-       */
-      @java.lang.Override
-      public java.lang.String getOptionalCord() {
-        return instance.getOptionalCord();
-      }
-      /**
-       * <code>string optional_cord = 25 [ctype = CORD];</code>
-       * @return The bytes for optionalCord.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getOptionalCordBytes() {
-        return instance.getOptionalCordBytes();
-      }
-      /**
-       * <code>string optional_cord = 25 [ctype = CORD];</code>
-       * @param value The optionalCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalCord(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setOptionalCord(value);
-        return this;
-      }
-      /**
-       * <code>string optional_cord = 25 [ctype = CORD];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalCord() {
-        copyOnWrite();
-        instance.clearOptionalCord();
-        return this;
-      }
-      /**
-       * <code>string optional_cord = 25 [ctype = CORD];</code>
-       * @param value The bytes for optionalCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalCordBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOptionalCordBytes(value);
-        return this;
-      }
-
-      /**
-       * <pre>
-       * Defined in unittest_import_public.proto
-       * </pre>
-       *
-       * <code>.protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalPublicImportMessage() {
-        return instance.hasOptionalPublicImportMessage();
-      }
-      /**
-       * <pre>
-       * Defined in unittest_import_public.proto
-       * </pre>
-       *
-       * <code>.protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.test.UnittestImportPublic.PublicImportMessage getOptionalPublicImportMessage() {
-        return instance.getOptionalPublicImportMessage();
-      }
-      /**
-       * <pre>
-       * Defined in unittest_import_public.proto
-       * </pre>
-       *
-       * <code>.protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-       */
-      public Builder setOptionalPublicImportMessage(com.google.protobuf.test.UnittestImportPublic.PublicImportMessage value) {
-        copyOnWrite();
-        instance.setOptionalPublicImportMessage(value);
-        return this;
-        }
-      /**
-       * <pre>
-       * Defined in unittest_import_public.proto
-       * </pre>
-       *
-       * <code>.protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-       */
-      public Builder setOptionalPublicImportMessage(
-          com.google.protobuf.test.UnittestImportPublic.PublicImportMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalPublicImportMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <pre>
-       * Defined in unittest_import_public.proto
-       * </pre>
-       *
-       * <code>.protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-       */
-      public Builder mergeOptionalPublicImportMessage(com.google.protobuf.test.UnittestImportPublic.PublicImportMessage value) {
-        copyOnWrite();
-        instance.mergeOptionalPublicImportMessage(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Defined in unittest_import_public.proto
-       * </pre>
-       *
-       * <code>.protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-       */
-      public Builder clearOptionalPublicImportMessage() {  copyOnWrite();
-        instance.clearOptionalPublicImportMessage();
-        return this;
-      }
-
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalLazyMessage() {
-        return instance.hasOptionalLazyMessage();
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage getOptionalLazyMessage() {
-        return instance.getOptionalLazyMessage();
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-       */
-      public Builder setOptionalLazyMessage(proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.setOptionalLazyMessage(value);
-        return this;
-        }
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-       */
-      public Builder setOptionalLazyMessage(
-          proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalLazyMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-       */
-      public Builder mergeOptionalLazyMessage(proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.mergeOptionalLazyMessage(value);
-        return this;
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-       */
-      public Builder clearOptionalLazyMessage() {  copyOnWrite();
-        instance.clearOptionalLazyMessage();
-        return this;
-      }
-
-      /**
-       * <code>.protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalLazyImportMessage() {
-        return instance.hasOptionalLazyImportMessage();
-      }
-      /**
-       * <code>.protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.test.UnittestImport.ImportMessage getOptionalLazyImportMessage() {
-        return instance.getOptionalLazyImportMessage();
-      }
-      /**
-       * <code>.protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115 [lazy = true];</code>
-       */
-      public Builder setOptionalLazyImportMessage(com.google.protobuf.test.UnittestImport.ImportMessage value) {
-        copyOnWrite();
-        instance.setOptionalLazyImportMessage(value);
-        return this;
-        }
-      /**
-       * <code>.protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115 [lazy = true];</code>
-       */
-      public Builder setOptionalLazyImportMessage(
-          com.google.protobuf.test.UnittestImport.ImportMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalLazyImportMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115 [lazy = true];</code>
-       */
-      public Builder mergeOptionalLazyImportMessage(com.google.protobuf.test.UnittestImport.ImportMessage value) {
-        copyOnWrite();
-        instance.mergeOptionalLazyImportMessage(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115 [lazy = true];</code>
-       */
-      public Builder clearOptionalLazyImportMessage() {  copyOnWrite();
-        instance.clearOptionalLazyImportMessage();
-        return this;
-      }
-
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @return A list containing the repeatedInt32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedInt32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedInt32List());
-      }
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @return The count of repeatedInt32.
-       */
-      @java.lang.Override
-      public int getRepeatedInt32Count() {
-        return instance.getRepeatedInt32Count();
-      }
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedInt32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedInt32(int index) {
-        return instance.getRepeatedInt32(index);
-      }
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @param value The repeatedInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedInt32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedInt32(index, value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @param value The repeatedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedInt32(int value) {
-        copyOnWrite();
-        instance.addRepeatedInt32(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @param values The repeatedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedInt32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedInt32(values);
-        return this;
-      }
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedInt32() {
-        copyOnWrite();
-        instance.clearRepeatedInt32();
-        return this;
-      }
-
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @return A list containing the repeatedInt64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedInt64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedInt64List());
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @return The count of repeatedInt64.
-       */
-      @java.lang.Override
-      public int getRepeatedInt64Count() {
-        return instance.getRepeatedInt64Count();
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedInt64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedInt64(int index) {
-        return instance.getRepeatedInt64(index);
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @param value The repeatedInt64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedInt64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedInt64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @param value The repeatedInt64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedInt64(long value) {
-        copyOnWrite();
-        instance.addRepeatedInt64(value);
-        return this;
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @param values The repeatedInt64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedInt64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedInt64(values);
-        return this;
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedInt64() {
-        copyOnWrite();
-        instance.clearRepeatedInt64();
-        return this;
-      }
-
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @return A list containing the repeatedUint32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedUint32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedUint32List());
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @return The count of repeatedUint32.
-       */
-      @java.lang.Override
-      public int getRepeatedUint32Count() {
-        return instance.getRepeatedUint32Count();
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedUint32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedUint32(int index) {
-        return instance.getRepeatedUint32(index);
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @param value The repeatedUint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedUint32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedUint32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @param value The repeatedUint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedUint32(int value) {
-        copyOnWrite();
-        instance.addRepeatedUint32(value);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @param values The repeatedUint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedUint32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedUint32(values);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedUint32() {
-        copyOnWrite();
-        instance.clearRepeatedUint32();
-        return this;
-      }
-
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @return A list containing the repeatedUint64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedUint64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedUint64List());
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @return The count of repeatedUint64.
-       */
-      @java.lang.Override
-      public int getRepeatedUint64Count() {
-        return instance.getRepeatedUint64Count();
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedUint64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedUint64(int index) {
-        return instance.getRepeatedUint64(index);
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @param value The repeatedUint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedUint64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedUint64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @param value The repeatedUint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedUint64(long value) {
-        copyOnWrite();
-        instance.addRepeatedUint64(value);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @param values The repeatedUint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedUint64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedUint64(values);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedUint64() {
-        copyOnWrite();
-        instance.clearRepeatedUint64();
-        return this;
-      }
-
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @return A list containing the repeatedSint32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedSint32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedSint32List());
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @return The count of repeatedSint32.
-       */
-      @java.lang.Override
-      public int getRepeatedSint32Count() {
-        return instance.getRepeatedSint32Count();
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedSint32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedSint32(int index) {
-        return instance.getRepeatedSint32(index);
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @param value The repeatedSint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedSint32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedSint32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @param value The repeatedSint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedSint32(int value) {
-        copyOnWrite();
-        instance.addRepeatedSint32(value);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @param values The repeatedSint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedSint32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedSint32(values);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedSint32() {
-        copyOnWrite();
-        instance.clearRepeatedSint32();
-        return this;
-      }
-
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @return A list containing the repeatedSint64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedSint64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedSint64List());
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @return The count of repeatedSint64.
-       */
-      @java.lang.Override
-      public int getRepeatedSint64Count() {
-        return instance.getRepeatedSint64Count();
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedSint64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedSint64(int index) {
-        return instance.getRepeatedSint64(index);
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @param value The repeatedSint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedSint64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedSint64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @param value The repeatedSint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedSint64(long value) {
-        copyOnWrite();
-        instance.addRepeatedSint64(value);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @param values The repeatedSint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedSint64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedSint64(values);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedSint64() {
-        copyOnWrite();
-        instance.clearRepeatedSint64();
-        return this;
-      }
-
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @return A list containing the repeatedFixed32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedFixed32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedFixed32List());
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @return The count of repeatedFixed32.
-       */
-      @java.lang.Override
-      public int getRepeatedFixed32Count() {
-        return instance.getRepeatedFixed32Count();
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedFixed32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedFixed32(int index) {
-        return instance.getRepeatedFixed32(index);
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @param value The repeatedFixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedFixed32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedFixed32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @param value The repeatedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedFixed32(int value) {
-        copyOnWrite();
-        instance.addRepeatedFixed32(value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @param values The repeatedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedFixed32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedFixed32(values);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedFixed32() {
-        copyOnWrite();
-        instance.clearRepeatedFixed32();
-        return this;
-      }
-
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @return A list containing the repeatedFixed64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedFixed64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedFixed64List());
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @return The count of repeatedFixed64.
-       */
-      @java.lang.Override
-      public int getRepeatedFixed64Count() {
-        return instance.getRepeatedFixed64Count();
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedFixed64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedFixed64(int index) {
-        return instance.getRepeatedFixed64(index);
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @param value The repeatedFixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedFixed64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedFixed64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @param value The repeatedFixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedFixed64(long value) {
-        copyOnWrite();
-        instance.addRepeatedFixed64(value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @param values The repeatedFixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedFixed64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedFixed64(values);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedFixed64() {
-        copyOnWrite();
-        instance.clearRepeatedFixed64();
-        return this;
-      }
-
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @return A list containing the repeatedSfixed32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedSfixed32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedSfixed32List());
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @return The count of repeatedSfixed32.
-       */
-      @java.lang.Override
-      public int getRepeatedSfixed32Count() {
-        return instance.getRepeatedSfixed32Count();
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedSfixed32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedSfixed32(int index) {
-        return instance.getRepeatedSfixed32(index);
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @param value The repeatedSfixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedSfixed32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedSfixed32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @param value The repeatedSfixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedSfixed32(int value) {
-        copyOnWrite();
-        instance.addRepeatedSfixed32(value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @param values The repeatedSfixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedSfixed32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedSfixed32(values);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedSfixed32() {
-        copyOnWrite();
-        instance.clearRepeatedSfixed32();
-        return this;
-      }
-
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @return A list containing the repeatedSfixed64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedSfixed64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedSfixed64List());
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @return The count of repeatedSfixed64.
-       */
-      @java.lang.Override
-      public int getRepeatedSfixed64Count() {
-        return instance.getRepeatedSfixed64Count();
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedSfixed64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedSfixed64(int index) {
-        return instance.getRepeatedSfixed64(index);
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @param value The repeatedSfixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedSfixed64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedSfixed64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @param value The repeatedSfixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedSfixed64(long value) {
-        copyOnWrite();
-        instance.addRepeatedSfixed64(value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @param values The repeatedSfixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedSfixed64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedSfixed64(values);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedSfixed64() {
-        copyOnWrite();
-        instance.clearRepeatedSfixed64();
-        return this;
-      }
-
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @return A list containing the repeatedFloat.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Float>
-          getRepeatedFloatList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedFloatList());
-      }
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @return The count of repeatedFloat.
-       */
-      @java.lang.Override
-      public int getRepeatedFloatCount() {
-        return instance.getRepeatedFloatCount();
-      }
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedFloat at the given index.
-       */
-      @java.lang.Override
-      public float getRepeatedFloat(int index) {
-        return instance.getRepeatedFloat(index);
-      }
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @param value The repeatedFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedFloat(
-          int index, float value) {
-        copyOnWrite();
-        instance.setRepeatedFloat(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @param value The repeatedFloat to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedFloat(float value) {
-        copyOnWrite();
-        instance.addRepeatedFloat(value);
-        return this;
-      }
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @param values The repeatedFloat to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedFloat(
-          java.lang.Iterable<? extends java.lang.Float> values) {
-        copyOnWrite();
-        instance.addAllRepeatedFloat(values);
-        return this;
-      }
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedFloat() {
-        copyOnWrite();
-        instance.clearRepeatedFloat();
-        return this;
-      }
-
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @return A list containing the repeatedDouble.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Double>
-          getRepeatedDoubleList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedDoubleList());
-      }
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @return The count of repeatedDouble.
-       */
-      @java.lang.Override
-      public int getRepeatedDoubleCount() {
-        return instance.getRepeatedDoubleCount();
-      }
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedDouble at the given index.
-       */
-      @java.lang.Override
-      public double getRepeatedDouble(int index) {
-        return instance.getRepeatedDouble(index);
-      }
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @param value The repeatedDouble to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedDouble(
-          int index, double value) {
-        copyOnWrite();
-        instance.setRepeatedDouble(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @param value The repeatedDouble to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedDouble(double value) {
-        copyOnWrite();
-        instance.addRepeatedDouble(value);
-        return this;
-      }
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @param values The repeatedDouble to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedDouble(
-          java.lang.Iterable<? extends java.lang.Double> values) {
-        copyOnWrite();
-        instance.addAllRepeatedDouble(values);
-        return this;
-      }
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedDouble() {
-        copyOnWrite();
-        instance.clearRepeatedDouble();
-        return this;
-      }
-
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @return A list containing the repeatedBool.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Boolean>
-          getRepeatedBoolList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedBoolList());
-      }
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @return The count of repeatedBool.
-       */
-      @java.lang.Override
-      public int getRepeatedBoolCount() {
-        return instance.getRepeatedBoolCount();
-      }
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedBool at the given index.
-       */
-      @java.lang.Override
-      public boolean getRepeatedBool(int index) {
-        return instance.getRepeatedBool(index);
-      }
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @param value The repeatedBool to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedBool(
-          int index, boolean value) {
-        copyOnWrite();
-        instance.setRepeatedBool(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @param value The repeatedBool to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedBool(boolean value) {
-        copyOnWrite();
-        instance.addRepeatedBool(value);
-        return this;
-      }
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @param values The repeatedBool to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedBool(
-          java.lang.Iterable<? extends java.lang.Boolean> values) {
-        copyOnWrite();
-        instance.addAllRepeatedBool(values);
-        return this;
-      }
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedBool() {
-        copyOnWrite();
-        instance.clearRepeatedBool();
-        return this;
-      }
-
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @return A list containing the repeatedString.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getRepeatedStringList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedStringList());
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @return The count of repeatedString.
-       */
-      @java.lang.Override
-      public int getRepeatedStringCount() {
-        return instance.getRepeatedStringCount();
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedString at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getRepeatedString(int index) {
-        return instance.getRepeatedString(index);
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the repeatedString at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getRepeatedStringBytes(int index) {
-        return instance.getRepeatedStringBytes(index);
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedString(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setRepeatedString(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @param value The repeatedString to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addRepeatedString(value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @param values The repeatedString to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedString(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllRepeatedString(values);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedString() {
-        copyOnWrite();
-        instance.clearRepeatedString();
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @param value The bytes of the repeatedString to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addRepeatedStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @return A list containing the repeatedBytes.
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.ByteString>
-          getRepeatedBytesList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedBytesList());
-      }
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @return The count of repeatedBytes.
-       */
-      @java.lang.Override
-      public int getRepeatedBytesCount() {
-        return instance.getRepeatedBytesCount();
-      }
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedBytes at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getRepeatedBytes(int index) {
-        return instance.getRepeatedBytes(index);
-      }
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @param value The repeatedBytes to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedBytes(
-          int index, com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setRepeatedBytes(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @param value The repeatedBytes to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedBytes(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addRepeatedBytes(value);
-        return this;
-      }
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @param values The repeatedBytes to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedBytes(
-          java.lang.Iterable<? extends com.google.protobuf.ByteString> values) {
-        copyOnWrite();
-        instance.addAllRepeatedBytes(values);
-        return this;
-      }
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedBytes() {
-        copyOnWrite();
-        instance.clearRepeatedBytes();
-        return this;
-      }
-
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      @java.lang.Override
-      public java.util.List<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage> getRepeatedNestedMessageList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedNestedMessageList());
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      @java.lang.Override
-      public int getRepeatedNestedMessageCount() {
-        return instance.getRepeatedNestedMessageCount();
-      }/**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      @java.lang.Override
-      public proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage getRepeatedNestedMessage(int index) {
-        return instance.getRepeatedNestedMessage(index);
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder setRepeatedNestedMessage(
-          int index, proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.setRepeatedNestedMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder setRepeatedNestedMessage(
-          int index, proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedNestedMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder addRepeatedNestedMessage(proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.addRepeatedNestedMessage(value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder addRepeatedNestedMessage(
-          int index, proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.addRepeatedNestedMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder addRepeatedNestedMessage(
-          proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedNestedMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder addRepeatedNestedMessage(
-          int index, proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedNestedMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder addAllRepeatedNestedMessage(
-          java.lang.Iterable<? extends proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage> values) {
-        copyOnWrite();
-        instance.addAllRepeatedNestedMessage(values);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder clearRepeatedNestedMessage() {
-        copyOnWrite();
-        instance.clearRepeatedNestedMessage();
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder removeRepeatedNestedMessage(int index) {
-        copyOnWrite();
-        instance.removeRepeatedNestedMessage(index);
-        return this;
-      }
-
-      /**
-       * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      @java.lang.Override
-      public java.util.List<proto3_unittest.UnittestProto3.ForeignMessage> getRepeatedForeignMessageList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedForeignMessageList());
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      @java.lang.Override
-      public int getRepeatedForeignMessageCount() {
-        return instance.getRepeatedForeignMessageCount();
-      }/**
-       * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      @java.lang.Override
-      public proto3_unittest.UnittestProto3.ForeignMessage getRepeatedForeignMessage(int index) {
-        return instance.getRepeatedForeignMessage(index);
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      public Builder setRepeatedForeignMessage(
-          int index, proto3_unittest.UnittestProto3.ForeignMessage value) {
-        copyOnWrite();
-        instance.setRepeatedForeignMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      public Builder setRepeatedForeignMessage(
-          int index, proto3_unittest.UnittestProto3.ForeignMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedForeignMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      public Builder addRepeatedForeignMessage(proto3_unittest.UnittestProto3.ForeignMessage value) {
-        copyOnWrite();
-        instance.addRepeatedForeignMessage(value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      public Builder addRepeatedForeignMessage(
-          int index, proto3_unittest.UnittestProto3.ForeignMessage value) {
-        copyOnWrite();
-        instance.addRepeatedForeignMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      public Builder addRepeatedForeignMessage(
-          proto3_unittest.UnittestProto3.ForeignMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedForeignMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      public Builder addRepeatedForeignMessage(
-          int index, proto3_unittest.UnittestProto3.ForeignMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedForeignMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      public Builder addAllRepeatedForeignMessage(
-          java.lang.Iterable<? extends proto3_unittest.UnittestProto3.ForeignMessage> values) {
-        copyOnWrite();
-        instance.addAllRepeatedForeignMessage(values);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      public Builder clearRepeatedForeignMessage() {
-        copyOnWrite();
-        instance.clearRepeatedForeignMessage();
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      public Builder removeRepeatedForeignMessage(int index) {
-        copyOnWrite();
-        instance.removeRepeatedForeignMessage(index);
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.test.UnittestImport.ImportMessage> getRepeatedImportMessageList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedImportMessageList());
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      @java.lang.Override
-      public int getRepeatedImportMessageCount() {
-        return instance.getRepeatedImportMessageCount();
-      }/**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.test.UnittestImport.ImportMessage getRepeatedImportMessage(int index) {
-        return instance.getRepeatedImportMessage(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      public Builder setRepeatedImportMessage(
-          int index, com.google.protobuf.test.UnittestImport.ImportMessage value) {
-        copyOnWrite();
-        instance.setRepeatedImportMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      public Builder setRepeatedImportMessage(
-          int index, com.google.protobuf.test.UnittestImport.ImportMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedImportMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      public Builder addRepeatedImportMessage(com.google.protobuf.test.UnittestImport.ImportMessage value) {
-        copyOnWrite();
-        instance.addRepeatedImportMessage(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      public Builder addRepeatedImportMessage(
-          int index, com.google.protobuf.test.UnittestImport.ImportMessage value) {
-        copyOnWrite();
-        instance.addRepeatedImportMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      public Builder addRepeatedImportMessage(
-          com.google.protobuf.test.UnittestImport.ImportMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedImportMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      public Builder addRepeatedImportMessage(
-          int index, com.google.protobuf.test.UnittestImport.ImportMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedImportMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      public Builder addAllRepeatedImportMessage(
-          java.lang.Iterable<? extends com.google.protobuf.test.UnittestImport.ImportMessage> values) {
-        copyOnWrite();
-        instance.addAllRepeatedImportMessage(values);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      public Builder clearRepeatedImportMessage() {
-        copyOnWrite();
-        instance.clearRepeatedImportMessage();
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      public Builder removeRepeatedImportMessage(int index) {
-        copyOnWrite();
-        instance.removeRepeatedImportMessage(index);
-        return this;
-      }
-
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-       * @return A list containing the repeatedNestedEnum.
-       */
-      @java.lang.Override
-      public java.util.List<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum> getRepeatedNestedEnumList() {
-        return instance.getRepeatedNestedEnumList();
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-       * @return The count of repeatedNestedEnum.
-       */
-      @java.lang.Override
-      public int getRepeatedNestedEnumCount() {
-        return instance.getRepeatedNestedEnumCount();
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedNestedEnum at the given index.
-       */
-      @java.lang.Override
-      public proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum getRepeatedNestedEnum(int index) {
-        return instance.getRepeatedNestedEnum(index);
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedNestedEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedNestedEnum(
-          int index, proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum value) {
-        copyOnWrite();
-        instance.setRepeatedNestedEnum(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-       * @param value The repeatedNestedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedNestedEnum(proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum value) {
-        copyOnWrite();
-        instance.addRepeatedNestedEnum(value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-       * @param values The repeatedNestedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedNestedEnum(
-          java.lang.Iterable<? extends proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum> values) {
-        copyOnWrite();
-        instance.addAllRepeatedNestedEnum(values);  return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedNestedEnum() {
-        copyOnWrite();
-        instance.clearRepeatedNestedEnum();
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-       * @return A list containing the enum numeric values on the wire for repeatedNestedEnum.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-      getRepeatedNestedEnumValueList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedNestedEnumValueList());
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-       * @param index The index of the value to return.
-       * @return The enum numeric value on the wire of repeatedNestedEnum at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedNestedEnumValue(int index) {
-        return instance.getRepeatedNestedEnumValue(index);
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-       * @param index The index to set the value at.
-       * @param value The enum numeric value on the wire for repeatedNestedEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedNestedEnumValue(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedNestedEnumValue(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-       * @param value The enum numeric value on the wire for repeatedNestedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedNestedEnumValue(int value) {
-        instance.addRepeatedNestedEnumValue(value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-       * @param values The enum numeric values on the wire for repeatedNestedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedNestedEnumValue(
-          java.lang.Iterable<java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedNestedEnumValue(values);
-        return this;
-      }
-
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-       * @return A list containing the repeatedForeignEnum.
-       */
-      @java.lang.Override
-      public java.util.List<proto3_unittest.UnittestProto3.ForeignEnum> getRepeatedForeignEnumList() {
-        return instance.getRepeatedForeignEnumList();
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-       * @return The count of repeatedForeignEnum.
-       */
-      @java.lang.Override
-      public int getRepeatedForeignEnumCount() {
-        return instance.getRepeatedForeignEnumCount();
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedForeignEnum at the given index.
-       */
-      @java.lang.Override
-      public proto3_unittest.UnittestProto3.ForeignEnum getRepeatedForeignEnum(int index) {
-        return instance.getRepeatedForeignEnum(index);
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedForeignEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedForeignEnum(
-          int index, proto3_unittest.UnittestProto3.ForeignEnum value) {
-        copyOnWrite();
-        instance.setRepeatedForeignEnum(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-       * @param value The repeatedForeignEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedForeignEnum(proto3_unittest.UnittestProto3.ForeignEnum value) {
-        copyOnWrite();
-        instance.addRepeatedForeignEnum(value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-       * @param values The repeatedForeignEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedForeignEnum(
-          java.lang.Iterable<? extends proto3_unittest.UnittestProto3.ForeignEnum> values) {
-        copyOnWrite();
-        instance.addAllRepeatedForeignEnum(values);  return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedForeignEnum() {
-        copyOnWrite();
-        instance.clearRepeatedForeignEnum();
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-       * @return A list containing the enum numeric values on the wire for repeatedForeignEnum.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-      getRepeatedForeignEnumValueList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedForeignEnumValueList());
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-       * @param index The index of the value to return.
-       * @return The enum numeric value on the wire of repeatedForeignEnum at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedForeignEnumValue(int index) {
-        return instance.getRepeatedForeignEnumValue(index);
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-       * @param index The index to set the value at.
-       * @param value The enum numeric value on the wire for repeatedForeignEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedForeignEnumValue(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedForeignEnumValue(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-       * @param value The enum numeric value on the wire for repeatedForeignEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedForeignEnumValue(int value) {
-        instance.addRepeatedForeignEnumValue(value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-       * @param values The enum numeric values on the wire for repeatedForeignEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedForeignEnumValue(
-          java.lang.Iterable<java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedForeignEnumValue(values);
-        return this;
-      }
-
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @return A list containing the repeatedStringPiece.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getRepeatedStringPieceList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedStringPieceList());
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @return The count of repeatedStringPiece.
-       */
-      @java.lang.Override
-      public int getRepeatedStringPieceCount() {
-        return instance.getRepeatedStringPieceCount();
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedStringPiece at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getRepeatedStringPiece(int index) {
-        return instance.getRepeatedStringPiece(index);
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the repeatedStringPiece at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getRepeatedStringPieceBytes(int index) {
-        return instance.getRepeatedStringPieceBytes(index);
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedStringPiece(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setRepeatedStringPiece(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @param value The repeatedStringPiece to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedStringPiece(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addRepeatedStringPiece(value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @param values The repeatedStringPiece to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedStringPiece(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllRepeatedStringPiece(values);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedStringPiece() {
-        copyOnWrite();
-        instance.clearRepeatedStringPiece();
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @param value The bytes of the repeatedStringPiece to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedStringPieceBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addRepeatedStringPieceBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @return A list containing the repeatedCord.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getRepeatedCordList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedCordList());
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @return The count of repeatedCord.
-       */
-      @java.lang.Override
-      public int getRepeatedCordCount() {
-        return instance.getRepeatedCordCount();
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedCord at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getRepeatedCord(int index) {
-        return instance.getRepeatedCord(index);
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the repeatedCord at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getRepeatedCordBytes(int index) {
-        return instance.getRepeatedCordBytes(index);
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedCord(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setRepeatedCord(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @param value The repeatedCord to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedCord(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addRepeatedCord(value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @param values The repeatedCord to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedCord(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllRepeatedCord(values);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedCord() {
-        copyOnWrite();
-        instance.clearRepeatedCord();
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @param value The bytes of the repeatedCord to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedCordBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addRepeatedCordBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public java.util.List<proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage> getRepeatedLazyMessageList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedLazyMessageList());
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public int getRepeatedLazyMessageCount() {
-        return instance.getRepeatedLazyMessageCount();
-      }/**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage getRepeatedLazyMessage(int index) {
-        return instance.getRepeatedLazyMessage(index);
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder setRepeatedLazyMessage(
-          int index, proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.setRepeatedLazyMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder setRepeatedLazyMessage(
-          int index, proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedLazyMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder addRepeatedLazyMessage(proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.addRepeatedLazyMessage(value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder addRepeatedLazyMessage(
-          int index, proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.addRepeatedLazyMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder addRepeatedLazyMessage(
-          proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedLazyMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder addRepeatedLazyMessage(
-          int index, proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedLazyMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder addAllRepeatedLazyMessage(
-          java.lang.Iterable<? extends proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage> values) {
-        copyOnWrite();
-        instance.addAllRepeatedLazyMessage(values);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder clearRepeatedLazyMessage() {
-        copyOnWrite();
-        instance.clearRepeatedLazyMessage();
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder removeRepeatedLazyMessage(int index) {
-        copyOnWrite();
-        instance.removeRepeatedLazyMessage(index);
-        return this;
-      }
-
-      /**
-       * <code>uint32 oneof_uint32 = 111;</code>
-       * @return Whether the oneofUint32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofUint32() {
-        return instance.hasOneofUint32();
-      }
-      /**
-       * <code>uint32 oneof_uint32 = 111;</code>
-       * @return The oneofUint32.
-       */
-      @java.lang.Override
-      public int getOneofUint32() {
-        return instance.getOneofUint32();
-      }
-      /**
-       * <code>uint32 oneof_uint32 = 111;</code>
-       * @param value The oneofUint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofUint32(int value) {
-        copyOnWrite();
-        instance.setOneofUint32(value);
-        return this;
-      }
-      /**
-       * <code>uint32 oneof_uint32 = 111;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofUint32() {
-        copyOnWrite();
-        instance.clearOneofUint32();
-        return this;
-      }
-
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-       */
-      @java.lang.Override
-      public boolean hasOneofNestedMessage() {
-        return instance.hasOneofNestedMessage();
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-       */
-      @java.lang.Override
-      public proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage getOneofNestedMessage() {
-        return instance.getOneofNestedMessage();
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-       */
-      public Builder setOneofNestedMessage(proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.setOneofNestedMessage(value);
-        return this;
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-       */
-      public Builder setOneofNestedMessage(
-          proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOneofNestedMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-       */
-      public Builder mergeOneofNestedMessage(proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.mergeOneofNestedMessage(value);
-        return this;
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-       */
-      public Builder clearOneofNestedMessage() {
-        copyOnWrite();
-        instance.clearOneofNestedMessage();
-        return this;
-      }
-
-      /**
-       * <code>string oneof_string = 113;</code>
-       * @return Whether the oneofString field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofString() {
-        return instance.hasOneofString();
-      }
-      /**
-       * <code>string oneof_string = 113;</code>
-       * @return The oneofString.
-       */
-      @java.lang.Override
-      public java.lang.String getOneofString() {
-        return instance.getOneofString();
-      }
-      /**
-       * <code>string oneof_string = 113;</code>
-       * @return The bytes for oneofString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getOneofStringBytes() {
-        return instance.getOneofStringBytes();
-      }
-      /**
-       * <code>string oneof_string = 113;</code>
-       * @param value The oneofString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setOneofString(value);
-        return this;
-      }
-      /**
-       * <code>string oneof_string = 113;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofString() {
-        copyOnWrite();
-        instance.clearOneofString();
-        return this;
-      }
-      /**
-       * <code>string oneof_string = 113;</code>
-       * @param value The bytes for oneofString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOneofStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>bytes oneof_bytes = 114;</code>
-       * @return Whether the oneofBytes field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofBytes() {
-        return instance.hasOneofBytes();
-      }
-      /**
-       * <code>bytes oneof_bytes = 114;</code>
-       * @return The oneofBytes.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getOneofBytes() {
-        return instance.getOneofBytes();
-      }
-      /**
-       * <code>bytes oneof_bytes = 114;</code>
-       * @param value The oneofBytes to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofBytes(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOneofBytes(value);
-        return this;
-      }
-      /**
-       * <code>bytes oneof_bytes = 114;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofBytes() {
-        copyOnWrite();
-        instance.clearOneofBytes();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:proto3_unittest.TestAllTypes)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new proto3_unittest.UnittestProto3.TestAllTypes();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "oneofField_",
-              "oneofFieldCase_",
-              "optionalInt32_",
-              "optionalInt64_",
-              "optionalUint32_",
-              "optionalUint64_",
-              "optionalSint32_",
-              "optionalSint64_",
-              "optionalFixed32_",
-              "optionalFixed64_",
-              "optionalSfixed32_",
-              "optionalSfixed64_",
-              "optionalFloat_",
-              "optionalDouble_",
-              "optionalBool_",
-              "optionalString_",
-              "optionalBytes_",
-              "optionalNestedMessage_",
-              "optionalForeignMessage_",
-              "optionalImportMessage_",
-              "optionalNestedEnum_",
-              "optionalForeignEnum_",
-              "optionalStringPiece_",
-              "optionalCord_",
-              "optionalPublicImportMessage_",
-              "optionalLazyMessage_",
-              "repeatedInt32_",
-              "repeatedInt64_",
-              "repeatedUint32_",
-              "repeatedUint64_",
-              "repeatedSint32_",
-              "repeatedSint64_",
-              "repeatedFixed32_",
-              "repeatedFixed64_",
-              "repeatedSfixed32_",
-              "repeatedSfixed64_",
-              "repeatedFloat_",
-              "repeatedDouble_",
-              "repeatedBool_",
-              "repeatedString_",
-              "repeatedBytes_",
-              "repeatedNestedMessage_",
-              proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.class,
-              "repeatedForeignMessage_",
-              proto3_unittest.UnittestProto3.ForeignMessage.class,
-              "repeatedImportMessage_",
-              com.google.protobuf.test.UnittestImport.ImportMessage.class,
-              "repeatedNestedEnum_",
-              "repeatedForeignEnum_",
-              "repeatedStringPiece_",
-              "repeatedCord_",
-              "repeatedLazyMessage_",
-              proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.class,
-              proto3_unittest.UnittestProto3.TestAllTypes.NestedMessage.class,
-              "optionalLazyImportMessage_",
-            };
-            java.lang.String info =
-                "\u00004\u0001\u0000\u0001s4\u0000\u0017\u0000\u0001\u0004\u0002\u0002\u0003\u000b" +
-                "\u0004\u0003\u0005\u000f\u0006\u0010\u0007\u0006\b\u0005\t\r\n\u000e\u000b\u0001" +
-                "\f\u0000\r\u0007\u000e\u0208\u000f\n\u0012\t\u0013\t\u0014\t\u0015\f\u0016\f\u0018" +
-                "\u0208\u0019\u0208\u001a\t\u001b\t\u001f\' %!+\"&#/$0%)&(\'-(.)$*#+*,\u021a-\u001c" +
-                "0\u001b1\u001b2\u001b3,4,6\u021a7\u021a9\u001bo>\u0000p<\u0000q\u023b\u0000r=\u0000" +
-                "s\t";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<proto3_unittest.UnittestProto3.TestAllTypes> parser = PARSER;
-          if (parser == null) {
-            synchronized (proto3_unittest.UnittestProto3.TestAllTypes.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<proto3_unittest.UnittestProto3.TestAllTypes>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:proto3_unittest.TestAllTypes)
-    private static final proto3_unittest.UnittestProto3.TestAllTypes DEFAULT_INSTANCE;
-    static {
-      TestAllTypes defaultInstance = new TestAllTypes();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestAllTypes.class, defaultInstance);
-    }
-
-    public static proto3_unittest.UnittestProto3.TestAllTypes getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestAllTypes> PARSER;
-
-    public static com.google.protobuf.Parser<TestAllTypes> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestPackedTypesOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:proto3_unittest.TestPackedTypes)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @return A list containing the packedInt32.
-     */
-    java.util.List<java.lang.Integer> getPackedInt32List();
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @return The count of packedInt32.
-     */
-    int getPackedInt32Count();
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedInt32 at the given index.
-     */
-    int getPackedInt32(int index);
-
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @return A list containing the packedInt64.
-     */
-    java.util.List<java.lang.Long> getPackedInt64List();
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @return The count of packedInt64.
-     */
-    int getPackedInt64Count();
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedInt64 at the given index.
-     */
-    long getPackedInt64(int index);
-
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @return A list containing the packedUint32.
-     */
-    java.util.List<java.lang.Integer> getPackedUint32List();
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @return The count of packedUint32.
-     */
-    int getPackedUint32Count();
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedUint32 at the given index.
-     */
-    int getPackedUint32(int index);
-
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @return A list containing the packedUint64.
-     */
-    java.util.List<java.lang.Long> getPackedUint64List();
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @return The count of packedUint64.
-     */
-    int getPackedUint64Count();
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedUint64 at the given index.
-     */
-    long getPackedUint64(int index);
-
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @return A list containing the packedSint32.
-     */
-    java.util.List<java.lang.Integer> getPackedSint32List();
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @return The count of packedSint32.
-     */
-    int getPackedSint32Count();
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSint32 at the given index.
-     */
-    int getPackedSint32(int index);
-
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @return A list containing the packedSint64.
-     */
-    java.util.List<java.lang.Long> getPackedSint64List();
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @return The count of packedSint64.
-     */
-    int getPackedSint64Count();
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSint64 at the given index.
-     */
-    long getPackedSint64(int index);
-
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @return A list containing the packedFixed32.
-     */
-    java.util.List<java.lang.Integer> getPackedFixed32List();
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @return The count of packedFixed32.
-     */
-    int getPackedFixed32Count();
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedFixed32 at the given index.
-     */
-    int getPackedFixed32(int index);
-
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @return A list containing the packedFixed64.
-     */
-    java.util.List<java.lang.Long> getPackedFixed64List();
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @return The count of packedFixed64.
-     */
-    int getPackedFixed64Count();
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedFixed64 at the given index.
-     */
-    long getPackedFixed64(int index);
-
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @return A list containing the packedSfixed32.
-     */
-    java.util.List<java.lang.Integer> getPackedSfixed32List();
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @return The count of packedSfixed32.
-     */
-    int getPackedSfixed32Count();
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSfixed32 at the given index.
-     */
-    int getPackedSfixed32(int index);
-
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @return A list containing the packedSfixed64.
-     */
-    java.util.List<java.lang.Long> getPackedSfixed64List();
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @return The count of packedSfixed64.
-     */
-    int getPackedSfixed64Count();
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSfixed64 at the given index.
-     */
-    long getPackedSfixed64(int index);
-
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @return A list containing the packedFloat.
-     */
-    java.util.List<java.lang.Float> getPackedFloatList();
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @return The count of packedFloat.
-     */
-    int getPackedFloatCount();
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedFloat at the given index.
-     */
-    float getPackedFloat(int index);
-
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @return A list containing the packedDouble.
-     */
-    java.util.List<java.lang.Double> getPackedDoubleList();
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @return The count of packedDouble.
-     */
-    int getPackedDoubleCount();
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedDouble at the given index.
-     */
-    double getPackedDouble(int index);
-
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @return A list containing the packedBool.
-     */
-    java.util.List<java.lang.Boolean> getPackedBoolList();
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @return The count of packedBool.
-     */
-    int getPackedBoolCount();
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedBool at the given index.
-     */
-    boolean getPackedBool(int index);
-
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @return A list containing the packedEnum.
-     */
-    java.util.List<proto3_unittest.UnittestProto3.ForeignEnum> getPackedEnumList();
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @return The count of packedEnum.
-     */
-    int getPackedEnumCount();
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedEnum at the given index.
-     */
-    proto3_unittest.UnittestProto3.ForeignEnum getPackedEnum(int index);
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @return A list containing the enum numeric values on the wire for packedEnum.
-     */
-    java.util.List<java.lang.Integer>
-    getPackedEnumValueList();
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param index The index of the value to return.
-     * @return The enum numeric value on the wire of packedEnum at the given index.
-     */
-    int getPackedEnumValue(int index);
-  }
-  /**
-   * Protobuf type {@code proto3_unittest.TestPackedTypes}
-   */
-  public  static final class TestPackedTypes extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestPackedTypes, TestPackedTypes.Builder> implements
-      // @@protoc_insertion_point(message_implements:proto3_unittest.TestPackedTypes)
-      TestPackedTypesOrBuilder {
-    private TestPackedTypes() {
-      packedInt32_ = emptyIntList();
-      packedInt64_ = emptyLongList();
-      packedUint32_ = emptyIntList();
-      packedUint64_ = emptyLongList();
-      packedSint32_ = emptyIntList();
-      packedSint64_ = emptyLongList();
-      packedFixed32_ = emptyIntList();
-      packedFixed64_ = emptyLongList();
-      packedSfixed32_ = emptyIntList();
-      packedSfixed64_ = emptyLongList();
-      packedFloat_ = emptyFloatList();
-      packedDouble_ = emptyDoubleList();
-      packedBool_ = emptyBooleanList();
-      packedEnum_ = emptyIntList();
-    }
-    public static final int PACKED_INT32_FIELD_NUMBER = 90;
-    private com.google.protobuf.Internal.IntList packedInt32_;
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @return A list containing the packedInt32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getPackedInt32List() {
-      return packedInt32_;
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @return The count of packedInt32.
-     */
-    @java.lang.Override
-    public int getPackedInt32Count() {
-      return packedInt32_.size();
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedInt32 at the given index.
-     */
-    @java.lang.Override
-    public int getPackedInt32(int index) {
-      return packedInt32_.getInt(index);
-    }
-    private int packedInt32MemoizedSerializedSize = -1;
-    private void ensurePackedInt32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedInt32_;
-      if (!tmp.isModifiable()) {
-        packedInt32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedInt32 to set.
-     */
-    private void setPackedInt32(
-        int index, int value) {
-      ensurePackedInt32IsMutable();
-      packedInt32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param value The packedInt32 to add.
-     */
-    private void addPackedInt32(int value) {
-      ensurePackedInt32IsMutable();
-      packedInt32_.addInt(value);
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param values The packedInt32 to add.
-     */
-    private void addAllPackedInt32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensurePackedInt32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedInt32_);
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     */
-    private void clearPackedInt32() {
-      packedInt32_ = emptyIntList();
-    }
-
-    public static final int PACKED_INT64_FIELD_NUMBER = 91;
-    private com.google.protobuf.Internal.LongList packedInt64_;
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @return A list containing the packedInt64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getPackedInt64List() {
-      return packedInt64_;
-    }
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @return The count of packedInt64.
-     */
-    @java.lang.Override
-    public int getPackedInt64Count() {
-      return packedInt64_.size();
-    }
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedInt64 at the given index.
-     */
-    @java.lang.Override
-    public long getPackedInt64(int index) {
-      return packedInt64_.getLong(index);
-    }
-    private int packedInt64MemoizedSerializedSize = -1;
-    private void ensurePackedInt64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = packedInt64_;
-      if (!tmp.isModifiable()) {
-        packedInt64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedInt64 to set.
-     */
-    private void setPackedInt64(
-        int index, long value) {
-      ensurePackedInt64IsMutable();
-      packedInt64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param value The packedInt64 to add.
-     */
-    private void addPackedInt64(long value) {
-      ensurePackedInt64IsMutable();
-      packedInt64_.addLong(value);
-    }
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param values The packedInt64 to add.
-     */
-    private void addAllPackedInt64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensurePackedInt64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedInt64_);
-    }
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     */
-    private void clearPackedInt64() {
-      packedInt64_ = emptyLongList();
-    }
-
-    public static final int PACKED_UINT32_FIELD_NUMBER = 92;
-    private com.google.protobuf.Internal.IntList packedUint32_;
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @return A list containing the packedUint32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getPackedUint32List() {
-      return packedUint32_;
-    }
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @return The count of packedUint32.
-     */
-    @java.lang.Override
-    public int getPackedUint32Count() {
-      return packedUint32_.size();
-    }
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedUint32 at the given index.
-     */
-    @java.lang.Override
-    public int getPackedUint32(int index) {
-      return packedUint32_.getInt(index);
-    }
-    private int packedUint32MemoizedSerializedSize = -1;
-    private void ensurePackedUint32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedUint32_;
-      if (!tmp.isModifiable()) {
-        packedUint32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedUint32 to set.
-     */
-    private void setPackedUint32(
-        int index, int value) {
-      ensurePackedUint32IsMutable();
-      packedUint32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param value The packedUint32 to add.
-     */
-    private void addPackedUint32(int value) {
-      ensurePackedUint32IsMutable();
-      packedUint32_.addInt(value);
-    }
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param values The packedUint32 to add.
-     */
-    private void addAllPackedUint32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensurePackedUint32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedUint32_);
-    }
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     */
-    private void clearPackedUint32() {
-      packedUint32_ = emptyIntList();
-    }
-
-    public static final int PACKED_UINT64_FIELD_NUMBER = 93;
-    private com.google.protobuf.Internal.LongList packedUint64_;
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @return A list containing the packedUint64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getPackedUint64List() {
-      return packedUint64_;
-    }
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @return The count of packedUint64.
-     */
-    @java.lang.Override
-    public int getPackedUint64Count() {
-      return packedUint64_.size();
-    }
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedUint64 at the given index.
-     */
-    @java.lang.Override
-    public long getPackedUint64(int index) {
-      return packedUint64_.getLong(index);
-    }
-    private int packedUint64MemoizedSerializedSize = -1;
-    private void ensurePackedUint64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = packedUint64_;
-      if (!tmp.isModifiable()) {
-        packedUint64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedUint64 to set.
-     */
-    private void setPackedUint64(
-        int index, long value) {
-      ensurePackedUint64IsMutable();
-      packedUint64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param value The packedUint64 to add.
-     */
-    private void addPackedUint64(long value) {
-      ensurePackedUint64IsMutable();
-      packedUint64_.addLong(value);
-    }
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param values The packedUint64 to add.
-     */
-    private void addAllPackedUint64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensurePackedUint64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedUint64_);
-    }
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     */
-    private void clearPackedUint64() {
-      packedUint64_ = emptyLongList();
-    }
-
-    public static final int PACKED_SINT32_FIELD_NUMBER = 94;
-    private com.google.protobuf.Internal.IntList packedSint32_;
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @return A list containing the packedSint32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getPackedSint32List() {
-      return packedSint32_;
-    }
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @return The count of packedSint32.
-     */
-    @java.lang.Override
-    public int getPackedSint32Count() {
-      return packedSint32_.size();
-    }
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSint32 at the given index.
-     */
-    @java.lang.Override
-    public int getPackedSint32(int index) {
-      return packedSint32_.getInt(index);
-    }
-    private int packedSint32MemoizedSerializedSize = -1;
-    private void ensurePackedSint32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedSint32_;
-      if (!tmp.isModifiable()) {
-        packedSint32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSint32 to set.
-     */
-    private void setPackedSint32(
-        int index, int value) {
-      ensurePackedSint32IsMutable();
-      packedSint32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param value The packedSint32 to add.
-     */
-    private void addPackedSint32(int value) {
-      ensurePackedSint32IsMutable();
-      packedSint32_.addInt(value);
-    }
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param values The packedSint32 to add.
-     */
-    private void addAllPackedSint32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensurePackedSint32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedSint32_);
-    }
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     */
-    private void clearPackedSint32() {
-      packedSint32_ = emptyIntList();
-    }
-
-    public static final int PACKED_SINT64_FIELD_NUMBER = 95;
-    private com.google.protobuf.Internal.LongList packedSint64_;
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @return A list containing the packedSint64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getPackedSint64List() {
-      return packedSint64_;
-    }
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @return The count of packedSint64.
-     */
-    @java.lang.Override
-    public int getPackedSint64Count() {
-      return packedSint64_.size();
-    }
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSint64 at the given index.
-     */
-    @java.lang.Override
-    public long getPackedSint64(int index) {
-      return packedSint64_.getLong(index);
-    }
-    private int packedSint64MemoizedSerializedSize = -1;
-    private void ensurePackedSint64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = packedSint64_;
-      if (!tmp.isModifiable()) {
-        packedSint64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSint64 to set.
-     */
-    private void setPackedSint64(
-        int index, long value) {
-      ensurePackedSint64IsMutable();
-      packedSint64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param value The packedSint64 to add.
-     */
-    private void addPackedSint64(long value) {
-      ensurePackedSint64IsMutable();
-      packedSint64_.addLong(value);
-    }
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param values The packedSint64 to add.
-     */
-    private void addAllPackedSint64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensurePackedSint64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedSint64_);
-    }
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     */
-    private void clearPackedSint64() {
-      packedSint64_ = emptyLongList();
-    }
-
-    public static final int PACKED_FIXED32_FIELD_NUMBER = 96;
-    private com.google.protobuf.Internal.IntList packedFixed32_;
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @return A list containing the packedFixed32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getPackedFixed32List() {
-      return packedFixed32_;
-    }
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @return The count of packedFixed32.
-     */
-    @java.lang.Override
-    public int getPackedFixed32Count() {
-      return packedFixed32_.size();
-    }
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedFixed32 at the given index.
-     */
-    @java.lang.Override
-    public int getPackedFixed32(int index) {
-      return packedFixed32_.getInt(index);
-    }
-    private int packedFixed32MemoizedSerializedSize = -1;
-    private void ensurePackedFixed32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedFixed32_;
-      if (!tmp.isModifiable()) {
-        packedFixed32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedFixed32 to set.
-     */
-    private void setPackedFixed32(
-        int index, int value) {
-      ensurePackedFixed32IsMutable();
-      packedFixed32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param value The packedFixed32 to add.
-     */
-    private void addPackedFixed32(int value) {
-      ensurePackedFixed32IsMutable();
-      packedFixed32_.addInt(value);
-    }
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param values The packedFixed32 to add.
-     */
-    private void addAllPackedFixed32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensurePackedFixed32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedFixed32_);
-    }
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     */
-    private void clearPackedFixed32() {
-      packedFixed32_ = emptyIntList();
-    }
-
-    public static final int PACKED_FIXED64_FIELD_NUMBER = 97;
-    private com.google.protobuf.Internal.LongList packedFixed64_;
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @return A list containing the packedFixed64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getPackedFixed64List() {
-      return packedFixed64_;
-    }
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @return The count of packedFixed64.
-     */
-    @java.lang.Override
-    public int getPackedFixed64Count() {
-      return packedFixed64_.size();
-    }
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedFixed64 at the given index.
-     */
-    @java.lang.Override
-    public long getPackedFixed64(int index) {
-      return packedFixed64_.getLong(index);
-    }
-    private int packedFixed64MemoizedSerializedSize = -1;
-    private void ensurePackedFixed64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = packedFixed64_;
-      if (!tmp.isModifiable()) {
-        packedFixed64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedFixed64 to set.
-     */
-    private void setPackedFixed64(
-        int index, long value) {
-      ensurePackedFixed64IsMutable();
-      packedFixed64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param value The packedFixed64 to add.
-     */
-    private void addPackedFixed64(long value) {
-      ensurePackedFixed64IsMutable();
-      packedFixed64_.addLong(value);
-    }
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param values The packedFixed64 to add.
-     */
-    private void addAllPackedFixed64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensurePackedFixed64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedFixed64_);
-    }
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     */
-    private void clearPackedFixed64() {
-      packedFixed64_ = emptyLongList();
-    }
-
-    public static final int PACKED_SFIXED32_FIELD_NUMBER = 98;
-    private com.google.protobuf.Internal.IntList packedSfixed32_;
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @return A list containing the packedSfixed32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getPackedSfixed32List() {
-      return packedSfixed32_;
-    }
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @return The count of packedSfixed32.
-     */
-    @java.lang.Override
-    public int getPackedSfixed32Count() {
-      return packedSfixed32_.size();
-    }
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSfixed32 at the given index.
-     */
-    @java.lang.Override
-    public int getPackedSfixed32(int index) {
-      return packedSfixed32_.getInt(index);
-    }
-    private int packedSfixed32MemoizedSerializedSize = -1;
-    private void ensurePackedSfixed32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedSfixed32_;
-      if (!tmp.isModifiable()) {
-        packedSfixed32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSfixed32 to set.
-     */
-    private void setPackedSfixed32(
-        int index, int value) {
-      ensurePackedSfixed32IsMutable();
-      packedSfixed32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param value The packedSfixed32 to add.
-     */
-    private void addPackedSfixed32(int value) {
-      ensurePackedSfixed32IsMutable();
-      packedSfixed32_.addInt(value);
-    }
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param values The packedSfixed32 to add.
-     */
-    private void addAllPackedSfixed32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensurePackedSfixed32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedSfixed32_);
-    }
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     */
-    private void clearPackedSfixed32() {
-      packedSfixed32_ = emptyIntList();
-    }
-
-    public static final int PACKED_SFIXED64_FIELD_NUMBER = 99;
-    private com.google.protobuf.Internal.LongList packedSfixed64_;
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @return A list containing the packedSfixed64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getPackedSfixed64List() {
-      return packedSfixed64_;
-    }
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @return The count of packedSfixed64.
-     */
-    @java.lang.Override
-    public int getPackedSfixed64Count() {
-      return packedSfixed64_.size();
-    }
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSfixed64 at the given index.
-     */
-    @java.lang.Override
-    public long getPackedSfixed64(int index) {
-      return packedSfixed64_.getLong(index);
-    }
-    private int packedSfixed64MemoizedSerializedSize = -1;
-    private void ensurePackedSfixed64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = packedSfixed64_;
-      if (!tmp.isModifiable()) {
-        packedSfixed64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSfixed64 to set.
-     */
-    private void setPackedSfixed64(
-        int index, long value) {
-      ensurePackedSfixed64IsMutable();
-      packedSfixed64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param value The packedSfixed64 to add.
-     */
-    private void addPackedSfixed64(long value) {
-      ensurePackedSfixed64IsMutable();
-      packedSfixed64_.addLong(value);
-    }
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param values The packedSfixed64 to add.
-     */
-    private void addAllPackedSfixed64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensurePackedSfixed64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedSfixed64_);
-    }
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     */
-    private void clearPackedSfixed64() {
-      packedSfixed64_ = emptyLongList();
-    }
-
-    public static final int PACKED_FLOAT_FIELD_NUMBER = 100;
-    private com.google.protobuf.Internal.FloatList packedFloat_;
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @return A list containing the packedFloat.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Float>
-        getPackedFloatList() {
-      return packedFloat_;
-    }
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @return The count of packedFloat.
-     */
-    @java.lang.Override
-    public int getPackedFloatCount() {
-      return packedFloat_.size();
-    }
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedFloat at the given index.
-     */
-    @java.lang.Override
-    public float getPackedFloat(int index) {
-      return packedFloat_.getFloat(index);
-    }
-    private int packedFloatMemoizedSerializedSize = -1;
-    private void ensurePackedFloatIsMutable() {
-      com.google.protobuf.Internal.FloatList tmp = packedFloat_;
-      if (!tmp.isModifiable()) {
-        packedFloat_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedFloat to set.
-     */
-    private void setPackedFloat(
-        int index, float value) {
-      ensurePackedFloatIsMutable();
-      packedFloat_.setFloat(index, value);
-    }
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param value The packedFloat to add.
-     */
-    private void addPackedFloat(float value) {
-      ensurePackedFloatIsMutable();
-      packedFloat_.addFloat(value);
-    }
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param values The packedFloat to add.
-     */
-    private void addAllPackedFloat(
-        java.lang.Iterable<? extends java.lang.Float> values) {
-      ensurePackedFloatIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedFloat_);
-    }
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     */
-    private void clearPackedFloat() {
-      packedFloat_ = emptyFloatList();
-    }
-
-    public static final int PACKED_DOUBLE_FIELD_NUMBER = 101;
-    private com.google.protobuf.Internal.DoubleList packedDouble_;
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @return A list containing the packedDouble.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Double>
-        getPackedDoubleList() {
-      return packedDouble_;
-    }
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @return The count of packedDouble.
-     */
-    @java.lang.Override
-    public int getPackedDoubleCount() {
-      return packedDouble_.size();
-    }
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedDouble at the given index.
-     */
-    @java.lang.Override
-    public double getPackedDouble(int index) {
-      return packedDouble_.getDouble(index);
-    }
-    private int packedDoubleMemoizedSerializedSize = -1;
-    private void ensurePackedDoubleIsMutable() {
-      com.google.protobuf.Internal.DoubleList tmp = packedDouble_;
-      if (!tmp.isModifiable()) {
-        packedDouble_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedDouble to set.
-     */
-    private void setPackedDouble(
-        int index, double value) {
-      ensurePackedDoubleIsMutable();
-      packedDouble_.setDouble(index, value);
-    }
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param value The packedDouble to add.
-     */
-    private void addPackedDouble(double value) {
-      ensurePackedDoubleIsMutable();
-      packedDouble_.addDouble(value);
-    }
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param values The packedDouble to add.
-     */
-    private void addAllPackedDouble(
-        java.lang.Iterable<? extends java.lang.Double> values) {
-      ensurePackedDoubleIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedDouble_);
-    }
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     */
-    private void clearPackedDouble() {
-      packedDouble_ = emptyDoubleList();
-    }
-
-    public static final int PACKED_BOOL_FIELD_NUMBER = 102;
-    private com.google.protobuf.Internal.BooleanList packedBool_;
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @return A list containing the packedBool.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Boolean>
-        getPackedBoolList() {
-      return packedBool_;
-    }
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @return The count of packedBool.
-     */
-    @java.lang.Override
-    public int getPackedBoolCount() {
-      return packedBool_.size();
-    }
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedBool at the given index.
-     */
-    @java.lang.Override
-    public boolean getPackedBool(int index) {
-      return packedBool_.getBoolean(index);
-    }
-    private int packedBoolMemoizedSerializedSize = -1;
-    private void ensurePackedBoolIsMutable() {
-      com.google.protobuf.Internal.BooleanList tmp = packedBool_;
-      if (!tmp.isModifiable()) {
-        packedBool_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedBool to set.
-     */
-    private void setPackedBool(
-        int index, boolean value) {
-      ensurePackedBoolIsMutable();
-      packedBool_.setBoolean(index, value);
-    }
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param value The packedBool to add.
-     */
-    private void addPackedBool(boolean value) {
-      ensurePackedBoolIsMutable();
-      packedBool_.addBoolean(value);
-    }
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param values The packedBool to add.
-     */
-    private void addAllPackedBool(
-        java.lang.Iterable<? extends java.lang.Boolean> values) {
-      ensurePackedBoolIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedBool_);
-    }
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     */
-    private void clearPackedBool() {
-      packedBool_ = emptyBooleanList();
-    }
-
-    public static final int PACKED_ENUM_FIELD_NUMBER = 103;
-    private com.google.protobuf.Internal.IntList packedEnum_;
-    private static final com.google.protobuf.Internal.ListAdapter.Converter<
-        java.lang.Integer, proto3_unittest.UnittestProto3.ForeignEnum> packedEnum_converter_ =
-            new com.google.protobuf.Internal.ListAdapter.Converter<
-                java.lang.Integer, proto3_unittest.UnittestProto3.ForeignEnum>() {
-              @java.lang.Override
-              public proto3_unittest.UnittestProto3.ForeignEnum convert(java.lang.Integer from) {
-                proto3_unittest.UnittestProto3.ForeignEnum result = proto3_unittest.UnittestProto3.ForeignEnum.forNumber(from);
-                return result == null ? proto3_unittest.UnittestProto3.ForeignEnum.UNRECOGNIZED : result;
-              }
-            };
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @return A list containing the packedEnum.
-     */
-    @java.lang.Override
-    public java.util.List<proto3_unittest.UnittestProto3.ForeignEnum> getPackedEnumList() {
-      return new com.google.protobuf.Internal.ListAdapter<
-          java.lang.Integer, proto3_unittest.UnittestProto3.ForeignEnum>(packedEnum_, packedEnum_converter_);
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @return The count of packedEnum.
-     */
-    @java.lang.Override
-    public int getPackedEnumCount() {
-      return packedEnum_.size();
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedEnum at the given index.
-     */
-    @java.lang.Override
-    public proto3_unittest.UnittestProto3.ForeignEnum getPackedEnum(int index) {
-      return packedEnum_converter_.convert(packedEnum_.getInt(index));
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @return A list containing the enum numeric values on the wire for packedEnum.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-    getPackedEnumValueList() {
-      return packedEnum_;
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param index The index of the value to return.
-     * @return The enum numeric value on the wire of packedEnum at the given index.
-     */
-    @java.lang.Override
-    public int getPackedEnumValue(int index) {
-      return packedEnum_.getInt(index);
-    }
-    private int packedEnumMemoizedSerializedSize;
-    private void ensurePackedEnumIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedEnum_;
-      if (!tmp.isModifiable()) {
-        packedEnum_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-      }
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedEnum to set.
-     */
-    private void setPackedEnum(
-        int index, proto3_unittest.UnittestProto3.ForeignEnum value) {
-      value.getClass();
-  ensurePackedEnumIsMutable();
-      packedEnum_.setInt(index, value.getNumber());
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param value The packedEnum to add.
-     */
-    private void addPackedEnum(proto3_unittest.UnittestProto3.ForeignEnum value) {
-      value.getClass();
-  ensurePackedEnumIsMutable();
-      packedEnum_.addInt(value.getNumber());
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param values The packedEnum to add.
-     */
-    private void addAllPackedEnum(
-        java.lang.Iterable<? extends proto3_unittest.UnittestProto3.ForeignEnum> values) {
-      ensurePackedEnumIsMutable();
-      for (proto3_unittest.UnittestProto3.ForeignEnum value : values) {
-        packedEnum_.addInt(value.getNumber());
-      }
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     */
-    private void clearPackedEnum() {
-      packedEnum_ = emptyIntList();
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param value The enum numeric value on the wire for packedEnum to set.
-     */
-    private void setPackedEnumValue(
-        int index, int value) {
-      ensurePackedEnumIsMutable();
-      packedEnum_.setInt(index, value);
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param value The enum numeric value on the wire for packedEnum to add.
-     */
-    private void addPackedEnumValue(int value) {
-      ensurePackedEnumIsMutable();
-      packedEnum_.addInt(value);
-    }
-    /**
-     * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param values The enum numeric values on the wire for packedEnum to add.
-     */
-    private void addAllPackedEnumValue(
-        java.lang.Iterable<java.lang.Integer> values) {
-      ensurePackedEnumIsMutable();
-      for (int value : values) {
-        packedEnum_.addInt(value);
-      }
-    }
-
-    public static proto3_unittest.UnittestProto3.TestPackedTypes parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.TestPackedTypes parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestPackedTypes parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.TestPackedTypes parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestPackedTypes parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.TestPackedTypes parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestPackedTypes parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.TestPackedTypes parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestPackedTypes parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.TestPackedTypes parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestPackedTypes parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.TestPackedTypes parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(proto3_unittest.UnittestProto3.TestPackedTypes prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code proto3_unittest.TestPackedTypes}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          proto3_unittest.UnittestProto3.TestPackedTypes, Builder> implements
-        // @@protoc_insertion_point(builder_implements:proto3_unittest.TestPackedTypes)
-        proto3_unittest.UnittestProto3.TestPackedTypesOrBuilder {
-      // Construct using proto3_unittest.UnittestProto3.TestPackedTypes.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @return A list containing the packedInt32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getPackedInt32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedInt32List());
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @return The count of packedInt32.
-       */
-      @java.lang.Override
-      public int getPackedInt32Count() {
-        return instance.getPackedInt32Count();
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedInt32 at the given index.
-       */
-      @java.lang.Override
-      public int getPackedInt32(int index) {
-        return instance.getPackedInt32(index);
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @param value The packedInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedInt32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setPackedInt32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @param value The packedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedInt32(int value) {
-        copyOnWrite();
-        instance.addPackedInt32(value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @param values The packedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedInt32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllPackedInt32(values);
-        return this;
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedInt32() {
-        copyOnWrite();
-        instance.clearPackedInt32();
-        return this;
-      }
-
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @return A list containing the packedInt64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getPackedInt64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedInt64List());
-      }
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @return The count of packedInt64.
-       */
-      @java.lang.Override
-      public int getPackedInt64Count() {
-        return instance.getPackedInt64Count();
-      }
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedInt64 at the given index.
-       */
-      @java.lang.Override
-      public long getPackedInt64(int index) {
-        return instance.getPackedInt64(index);
-      }
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @param value The packedInt64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedInt64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setPackedInt64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @param value The packedInt64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedInt64(long value) {
-        copyOnWrite();
-        instance.addPackedInt64(value);
-        return this;
-      }
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @param values The packedInt64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedInt64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllPackedInt64(values);
-        return this;
-      }
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedInt64() {
-        copyOnWrite();
-        instance.clearPackedInt64();
-        return this;
-      }
-
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @return A list containing the packedUint32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getPackedUint32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedUint32List());
-      }
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @return The count of packedUint32.
-       */
-      @java.lang.Override
-      public int getPackedUint32Count() {
-        return instance.getPackedUint32Count();
-      }
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedUint32 at the given index.
-       */
-      @java.lang.Override
-      public int getPackedUint32(int index) {
-        return instance.getPackedUint32(index);
-      }
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @param value The packedUint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedUint32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setPackedUint32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @param value The packedUint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedUint32(int value) {
-        copyOnWrite();
-        instance.addPackedUint32(value);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @param values The packedUint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedUint32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllPackedUint32(values);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedUint32() {
-        copyOnWrite();
-        instance.clearPackedUint32();
-        return this;
-      }
-
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @return A list containing the packedUint64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getPackedUint64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedUint64List());
-      }
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @return The count of packedUint64.
-       */
-      @java.lang.Override
-      public int getPackedUint64Count() {
-        return instance.getPackedUint64Count();
-      }
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedUint64 at the given index.
-       */
-      @java.lang.Override
-      public long getPackedUint64(int index) {
-        return instance.getPackedUint64(index);
-      }
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @param value The packedUint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedUint64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setPackedUint64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @param value The packedUint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedUint64(long value) {
-        copyOnWrite();
-        instance.addPackedUint64(value);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @param values The packedUint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedUint64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllPackedUint64(values);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedUint64() {
-        copyOnWrite();
-        instance.clearPackedUint64();
-        return this;
-      }
-
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @return A list containing the packedSint32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getPackedSint32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedSint32List());
-      }
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @return The count of packedSint32.
-       */
-      @java.lang.Override
-      public int getPackedSint32Count() {
-        return instance.getPackedSint32Count();
-      }
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedSint32 at the given index.
-       */
-      @java.lang.Override
-      public int getPackedSint32(int index) {
-        return instance.getPackedSint32(index);
-      }
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @param value The packedSint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedSint32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setPackedSint32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @param value The packedSint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedSint32(int value) {
-        copyOnWrite();
-        instance.addPackedSint32(value);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @param values The packedSint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedSint32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllPackedSint32(values);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedSint32() {
-        copyOnWrite();
-        instance.clearPackedSint32();
-        return this;
-      }
-
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @return A list containing the packedSint64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getPackedSint64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedSint64List());
-      }
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @return The count of packedSint64.
-       */
-      @java.lang.Override
-      public int getPackedSint64Count() {
-        return instance.getPackedSint64Count();
-      }
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedSint64 at the given index.
-       */
-      @java.lang.Override
-      public long getPackedSint64(int index) {
-        return instance.getPackedSint64(index);
-      }
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @param value The packedSint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedSint64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setPackedSint64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @param value The packedSint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedSint64(long value) {
-        copyOnWrite();
-        instance.addPackedSint64(value);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @param values The packedSint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedSint64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllPackedSint64(values);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedSint64() {
-        copyOnWrite();
-        instance.clearPackedSint64();
-        return this;
-      }
-
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @return A list containing the packedFixed32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getPackedFixed32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedFixed32List());
-      }
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @return The count of packedFixed32.
-       */
-      @java.lang.Override
-      public int getPackedFixed32Count() {
-        return instance.getPackedFixed32Count();
-      }
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedFixed32 at the given index.
-       */
-      @java.lang.Override
-      public int getPackedFixed32(int index) {
-        return instance.getPackedFixed32(index);
-      }
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @param value The packedFixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedFixed32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setPackedFixed32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @param value The packedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedFixed32(int value) {
-        copyOnWrite();
-        instance.addPackedFixed32(value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @param values The packedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedFixed32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllPackedFixed32(values);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedFixed32() {
-        copyOnWrite();
-        instance.clearPackedFixed32();
-        return this;
-      }
-
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @return A list containing the packedFixed64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getPackedFixed64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedFixed64List());
-      }
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @return The count of packedFixed64.
-       */
-      @java.lang.Override
-      public int getPackedFixed64Count() {
-        return instance.getPackedFixed64Count();
-      }
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedFixed64 at the given index.
-       */
-      @java.lang.Override
-      public long getPackedFixed64(int index) {
-        return instance.getPackedFixed64(index);
-      }
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @param value The packedFixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedFixed64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setPackedFixed64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @param value The packedFixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedFixed64(long value) {
-        copyOnWrite();
-        instance.addPackedFixed64(value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @param values The packedFixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedFixed64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllPackedFixed64(values);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedFixed64() {
-        copyOnWrite();
-        instance.clearPackedFixed64();
-        return this;
-      }
-
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @return A list containing the packedSfixed32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getPackedSfixed32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedSfixed32List());
-      }
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @return The count of packedSfixed32.
-       */
-      @java.lang.Override
-      public int getPackedSfixed32Count() {
-        return instance.getPackedSfixed32Count();
-      }
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedSfixed32 at the given index.
-       */
-      @java.lang.Override
-      public int getPackedSfixed32(int index) {
-        return instance.getPackedSfixed32(index);
-      }
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @param value The packedSfixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedSfixed32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setPackedSfixed32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @param value The packedSfixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedSfixed32(int value) {
-        copyOnWrite();
-        instance.addPackedSfixed32(value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @param values The packedSfixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedSfixed32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllPackedSfixed32(values);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedSfixed32() {
-        copyOnWrite();
-        instance.clearPackedSfixed32();
-        return this;
-      }
-
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @return A list containing the packedSfixed64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getPackedSfixed64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedSfixed64List());
-      }
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @return The count of packedSfixed64.
-       */
-      @java.lang.Override
-      public int getPackedSfixed64Count() {
-        return instance.getPackedSfixed64Count();
-      }
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedSfixed64 at the given index.
-       */
-      @java.lang.Override
-      public long getPackedSfixed64(int index) {
-        return instance.getPackedSfixed64(index);
-      }
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @param value The packedSfixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedSfixed64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setPackedSfixed64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @param value The packedSfixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedSfixed64(long value) {
-        copyOnWrite();
-        instance.addPackedSfixed64(value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @param values The packedSfixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedSfixed64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllPackedSfixed64(values);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedSfixed64() {
-        copyOnWrite();
-        instance.clearPackedSfixed64();
-        return this;
-      }
-
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @return A list containing the packedFloat.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Float>
-          getPackedFloatList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedFloatList());
-      }
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @return The count of packedFloat.
-       */
-      @java.lang.Override
-      public int getPackedFloatCount() {
-        return instance.getPackedFloatCount();
-      }
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedFloat at the given index.
-       */
-      @java.lang.Override
-      public float getPackedFloat(int index) {
-        return instance.getPackedFloat(index);
-      }
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @param value The packedFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedFloat(
-          int index, float value) {
-        copyOnWrite();
-        instance.setPackedFloat(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @param value The packedFloat to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedFloat(float value) {
-        copyOnWrite();
-        instance.addPackedFloat(value);
-        return this;
-      }
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @param values The packedFloat to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedFloat(
-          java.lang.Iterable<? extends java.lang.Float> values) {
-        copyOnWrite();
-        instance.addAllPackedFloat(values);
-        return this;
-      }
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedFloat() {
-        copyOnWrite();
-        instance.clearPackedFloat();
-        return this;
-      }
-
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @return A list containing the packedDouble.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Double>
-          getPackedDoubleList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedDoubleList());
-      }
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @return The count of packedDouble.
-       */
-      @java.lang.Override
-      public int getPackedDoubleCount() {
-        return instance.getPackedDoubleCount();
-      }
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedDouble at the given index.
-       */
-      @java.lang.Override
-      public double getPackedDouble(int index) {
-        return instance.getPackedDouble(index);
-      }
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @param value The packedDouble to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedDouble(
-          int index, double value) {
-        copyOnWrite();
-        instance.setPackedDouble(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @param value The packedDouble to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedDouble(double value) {
-        copyOnWrite();
-        instance.addPackedDouble(value);
-        return this;
-      }
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @param values The packedDouble to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedDouble(
-          java.lang.Iterable<? extends java.lang.Double> values) {
-        copyOnWrite();
-        instance.addAllPackedDouble(values);
-        return this;
-      }
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedDouble() {
-        copyOnWrite();
-        instance.clearPackedDouble();
-        return this;
-      }
-
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @return A list containing the packedBool.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Boolean>
-          getPackedBoolList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedBoolList());
-      }
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @return The count of packedBool.
-       */
-      @java.lang.Override
-      public int getPackedBoolCount() {
-        return instance.getPackedBoolCount();
-      }
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedBool at the given index.
-       */
-      @java.lang.Override
-      public boolean getPackedBool(int index) {
-        return instance.getPackedBool(index);
-      }
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @param value The packedBool to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedBool(
-          int index, boolean value) {
-        copyOnWrite();
-        instance.setPackedBool(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @param value The packedBool to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedBool(boolean value) {
-        copyOnWrite();
-        instance.addPackedBool(value);
-        return this;
-      }
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @param values The packedBool to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedBool(
-          java.lang.Iterable<? extends java.lang.Boolean> values) {
-        copyOnWrite();
-        instance.addAllPackedBool(values);
-        return this;
-      }
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedBool() {
-        copyOnWrite();
-        instance.clearPackedBool();
-        return this;
-      }
-
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-       * @return A list containing the packedEnum.
-       */
-      @java.lang.Override
-      public java.util.List<proto3_unittest.UnittestProto3.ForeignEnum> getPackedEnumList() {
-        return instance.getPackedEnumList();
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-       * @return The count of packedEnum.
-       */
-      @java.lang.Override
-      public int getPackedEnumCount() {
-        return instance.getPackedEnumCount();
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedEnum at the given index.
-       */
-      @java.lang.Override
-      public proto3_unittest.UnittestProto3.ForeignEnum getPackedEnum(int index) {
-        return instance.getPackedEnum(index);
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-       * @param index The index to set the value at.
-       * @param value The packedEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedEnum(
-          int index, proto3_unittest.UnittestProto3.ForeignEnum value) {
-        copyOnWrite();
-        instance.setPackedEnum(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-       * @param value The packedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedEnum(proto3_unittest.UnittestProto3.ForeignEnum value) {
-        copyOnWrite();
-        instance.addPackedEnum(value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-       * @param values The packedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedEnum(
-          java.lang.Iterable<? extends proto3_unittest.UnittestProto3.ForeignEnum> values) {
-        copyOnWrite();
-        instance.addAllPackedEnum(values);  return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedEnum() {
-        copyOnWrite();
-        instance.clearPackedEnum();
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-       * @return A list containing the enum numeric values on the wire for packedEnum.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-      getPackedEnumValueList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedEnumValueList());
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-       * @param index The index of the value to return.
-       * @return The enum numeric value on the wire of packedEnum at the given index.
-       */
-      @java.lang.Override
-      public int getPackedEnumValue(int index) {
-        return instance.getPackedEnumValue(index);
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-       * @param index The index to set the value at.
-       * @param value The enum numeric value on the wire for packedEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedEnumValue(
-          int index, int value) {
-        copyOnWrite();
-        instance.setPackedEnumValue(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-       * @param value The enum numeric value on the wire for packedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedEnumValue(int value) {
-        instance.addPackedEnumValue(value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-       * @param values The enum numeric values on the wire for packedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedEnumValue(
-          java.lang.Iterable<java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllPackedEnumValue(values);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:proto3_unittest.TestPackedTypes)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new proto3_unittest.UnittestProto3.TestPackedTypes();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "packedInt32_",
-              "packedInt64_",
-              "packedUint32_",
-              "packedUint64_",
-              "packedSint32_",
-              "packedSint64_",
-              "packedFixed32_",
-              "packedFixed64_",
-              "packedSfixed32_",
-              "packedSfixed64_",
-              "packedFloat_",
-              "packedDouble_",
-              "packedBool_",
-              "packedEnum_",
-            };
-            java.lang.String info =
-                "\u0000\u000e\u0000\u0000Zg\u000e\u0000\u000e\u0000Z\'[%\\+]&^/_0`)a(b-c.d$e#f*g," +
-                "";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<proto3_unittest.UnittestProto3.TestPackedTypes> parser = PARSER;
-          if (parser == null) {
-            synchronized (proto3_unittest.UnittestProto3.TestPackedTypes.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<proto3_unittest.UnittestProto3.TestPackedTypes>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:proto3_unittest.TestPackedTypes)
-    private static final proto3_unittest.UnittestProto3.TestPackedTypes DEFAULT_INSTANCE;
-    static {
-      TestPackedTypes defaultInstance = new TestPackedTypes();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestPackedTypes.class, defaultInstance);
-    }
-
-    public static proto3_unittest.UnittestProto3.TestPackedTypes getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestPackedTypes> PARSER;
-
-    public static com.google.protobuf.Parser<TestPackedTypes> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestUnpackedTypesOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:proto3_unittest.TestUnpackedTypes)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-     * @return A list containing the repeatedInt32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedInt32List();
-    /**
-     * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-     * @return The count of repeatedInt32.
-     */
-    int getRepeatedInt32Count();
-    /**
-     * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt32 at the given index.
-     */
-    int getRepeatedInt32(int index);
-
-    /**
-     * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-     * @return A list containing the repeatedInt64.
-     */
-    java.util.List<java.lang.Long> getRepeatedInt64List();
-    /**
-     * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-     * @return The count of repeatedInt64.
-     */
-    int getRepeatedInt64Count();
-    /**
-     * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt64 at the given index.
-     */
-    long getRepeatedInt64(int index);
-
-    /**
-     * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-     * @return A list containing the repeatedUint32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedUint32List();
-    /**
-     * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-     * @return The count of repeatedUint32.
-     */
-    int getRepeatedUint32Count();
-    /**
-     * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedUint32 at the given index.
-     */
-    int getRepeatedUint32(int index);
-
-    /**
-     * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-     * @return A list containing the repeatedUint64.
-     */
-    java.util.List<java.lang.Long> getRepeatedUint64List();
-    /**
-     * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-     * @return The count of repeatedUint64.
-     */
-    int getRepeatedUint64Count();
-    /**
-     * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedUint64 at the given index.
-     */
-    long getRepeatedUint64(int index);
-
-    /**
-     * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-     * @return A list containing the repeatedSint32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedSint32List();
-    /**
-     * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-     * @return The count of repeatedSint32.
-     */
-    int getRepeatedSint32Count();
-    /**
-     * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSint32 at the given index.
-     */
-    int getRepeatedSint32(int index);
-
-    /**
-     * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-     * @return A list containing the repeatedSint64.
-     */
-    java.util.List<java.lang.Long> getRepeatedSint64List();
-    /**
-     * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-     * @return The count of repeatedSint64.
-     */
-    int getRepeatedSint64Count();
-    /**
-     * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSint64 at the given index.
-     */
-    long getRepeatedSint64(int index);
-
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-     * @return A list containing the repeatedFixed32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedFixed32List();
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-     * @return The count of repeatedFixed32.
-     */
-    int getRepeatedFixed32Count();
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed32 at the given index.
-     */
-    int getRepeatedFixed32(int index);
-
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-     * @return A list containing the repeatedFixed64.
-     */
-    java.util.List<java.lang.Long> getRepeatedFixed64List();
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-     * @return The count of repeatedFixed64.
-     */
-    int getRepeatedFixed64Count();
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed64 at the given index.
-     */
-    long getRepeatedFixed64(int index);
-
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-     * @return A list containing the repeatedSfixed32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedSfixed32List();
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-     * @return The count of repeatedSfixed32.
-     */
-    int getRepeatedSfixed32Count();
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSfixed32 at the given index.
-     */
-    int getRepeatedSfixed32(int index);
-
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-     * @return A list containing the repeatedSfixed64.
-     */
-    java.util.List<java.lang.Long> getRepeatedSfixed64List();
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-     * @return The count of repeatedSfixed64.
-     */
-    int getRepeatedSfixed64Count();
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSfixed64 at the given index.
-     */
-    long getRepeatedSfixed64(int index);
-
-    /**
-     * <code>repeated float repeated_float = 11 [packed = false];</code>
-     * @return A list containing the repeatedFloat.
-     */
-    java.util.List<java.lang.Float> getRepeatedFloatList();
-    /**
-     * <code>repeated float repeated_float = 11 [packed = false];</code>
-     * @return The count of repeatedFloat.
-     */
-    int getRepeatedFloatCount();
-    /**
-     * <code>repeated float repeated_float = 11 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFloat at the given index.
-     */
-    float getRepeatedFloat(int index);
-
-    /**
-     * <code>repeated double repeated_double = 12 [packed = false];</code>
-     * @return A list containing the repeatedDouble.
-     */
-    java.util.List<java.lang.Double> getRepeatedDoubleList();
-    /**
-     * <code>repeated double repeated_double = 12 [packed = false];</code>
-     * @return The count of repeatedDouble.
-     */
-    int getRepeatedDoubleCount();
-    /**
-     * <code>repeated double repeated_double = 12 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedDouble at the given index.
-     */
-    double getRepeatedDouble(int index);
-
-    /**
-     * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-     * @return A list containing the repeatedBool.
-     */
-    java.util.List<java.lang.Boolean> getRepeatedBoolList();
-    /**
-     * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-     * @return The count of repeatedBool.
-     */
-    int getRepeatedBoolCount();
-    /**
-     * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedBool at the given index.
-     */
-    boolean getRepeatedBool(int index);
-
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @return A list containing the repeatedNestedEnum.
-     */
-    java.util.List<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum> getRepeatedNestedEnumList();
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @return The count of repeatedNestedEnum.
-     */
-    int getRepeatedNestedEnumCount();
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedNestedEnum at the given index.
-     */
-    proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum getRepeatedNestedEnum(int index);
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @return A list containing the enum numeric values on the wire for repeatedNestedEnum.
-     */
-    java.util.List<java.lang.Integer>
-    getRepeatedNestedEnumValueList();
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @param index The index of the value to return.
-     * @return The enum numeric value on the wire of repeatedNestedEnum at the given index.
-     */
-    int getRepeatedNestedEnumValue(int index);
-  }
-  /**
-   * <pre>
-   * Explicitly set packed to false
-   * </pre>
-   *
-   * Protobuf type {@code proto3_unittest.TestUnpackedTypes}
-   */
-  public  static final class TestUnpackedTypes extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestUnpackedTypes, TestUnpackedTypes.Builder> implements
-      // @@protoc_insertion_point(message_implements:proto3_unittest.TestUnpackedTypes)
-      TestUnpackedTypesOrBuilder {
-    private TestUnpackedTypes() {
-      repeatedInt32_ = emptyIntList();
-      repeatedInt64_ = emptyLongList();
-      repeatedUint32_ = emptyIntList();
-      repeatedUint64_ = emptyLongList();
-      repeatedSint32_ = emptyIntList();
-      repeatedSint64_ = emptyLongList();
-      repeatedFixed32_ = emptyIntList();
-      repeatedFixed64_ = emptyLongList();
-      repeatedSfixed32_ = emptyIntList();
-      repeatedSfixed64_ = emptyLongList();
-      repeatedFloat_ = emptyFloatList();
-      repeatedDouble_ = emptyDoubleList();
-      repeatedBool_ = emptyBooleanList();
-      repeatedNestedEnum_ = emptyIntList();
-    }
-    public static final int REPEATED_INT32_FIELD_NUMBER = 1;
-    private com.google.protobuf.Internal.IntList repeatedInt32_;
-    /**
-     * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-     * @return A list containing the repeatedInt32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedInt32List() {
-      return repeatedInt32_;
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-     * @return The count of repeatedInt32.
-     */
-    @java.lang.Override
-    public int getRepeatedInt32Count() {
-      return repeatedInt32_.size();
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedInt32(int index) {
-      return repeatedInt32_.getInt(index);
-    }
-    private void ensureRepeatedInt32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedInt32_;
-      if (!tmp.isModifiable()) {
-        repeatedInt32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt32 to set.
-     */
-    private void setRepeatedInt32(
-        int index, int value) {
-      ensureRepeatedInt32IsMutable();
-      repeatedInt32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-     * @param value The repeatedInt32 to add.
-     */
-    private void addRepeatedInt32(int value) {
-      ensureRepeatedInt32IsMutable();
-      repeatedInt32_.addInt(value);
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-     * @param values The repeatedInt32 to add.
-     */
-    private void addAllRepeatedInt32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedInt32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedInt32_);
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-     */
-    private void clearRepeatedInt32() {
-      repeatedInt32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_INT64_FIELD_NUMBER = 2;
-    private com.google.protobuf.Internal.LongList repeatedInt64_;
-    /**
-     * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-     * @return A list containing the repeatedInt64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedInt64List() {
-      return repeatedInt64_;
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-     * @return The count of repeatedInt64.
-     */
-    @java.lang.Override
-    public int getRepeatedInt64Count() {
-      return repeatedInt64_.size();
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedInt64(int index) {
-      return repeatedInt64_.getLong(index);
-    }
-    private void ensureRepeatedInt64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedInt64_;
-      if (!tmp.isModifiable()) {
-        repeatedInt64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt64 to set.
-     */
-    private void setRepeatedInt64(
-        int index, long value) {
-      ensureRepeatedInt64IsMutable();
-      repeatedInt64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-     * @param value The repeatedInt64 to add.
-     */
-    private void addRepeatedInt64(long value) {
-      ensureRepeatedInt64IsMutable();
-      repeatedInt64_.addLong(value);
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-     * @param values The repeatedInt64 to add.
-     */
-    private void addAllRepeatedInt64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedInt64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedInt64_);
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-     */
-    private void clearRepeatedInt64() {
-      repeatedInt64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_UINT32_FIELD_NUMBER = 3;
-    private com.google.protobuf.Internal.IntList repeatedUint32_;
-    /**
-     * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-     * @return A list containing the repeatedUint32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedUint32List() {
-      return repeatedUint32_;
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-     * @return The count of repeatedUint32.
-     */
-    @java.lang.Override
-    public int getRepeatedUint32Count() {
-      return repeatedUint32_.size();
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedUint32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedUint32(int index) {
-      return repeatedUint32_.getInt(index);
-    }
-    private void ensureRepeatedUint32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedUint32_;
-      if (!tmp.isModifiable()) {
-        repeatedUint32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedUint32 to set.
-     */
-    private void setRepeatedUint32(
-        int index, int value) {
-      ensureRepeatedUint32IsMutable();
-      repeatedUint32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-     * @param value The repeatedUint32 to add.
-     */
-    private void addRepeatedUint32(int value) {
-      ensureRepeatedUint32IsMutable();
-      repeatedUint32_.addInt(value);
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-     * @param values The repeatedUint32 to add.
-     */
-    private void addAllRepeatedUint32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedUint32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedUint32_);
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-     */
-    private void clearRepeatedUint32() {
-      repeatedUint32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_UINT64_FIELD_NUMBER = 4;
-    private com.google.protobuf.Internal.LongList repeatedUint64_;
-    /**
-     * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-     * @return A list containing the repeatedUint64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedUint64List() {
-      return repeatedUint64_;
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-     * @return The count of repeatedUint64.
-     */
-    @java.lang.Override
-    public int getRepeatedUint64Count() {
-      return repeatedUint64_.size();
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedUint64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedUint64(int index) {
-      return repeatedUint64_.getLong(index);
-    }
-    private void ensureRepeatedUint64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedUint64_;
-      if (!tmp.isModifiable()) {
-        repeatedUint64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedUint64 to set.
-     */
-    private void setRepeatedUint64(
-        int index, long value) {
-      ensureRepeatedUint64IsMutable();
-      repeatedUint64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-     * @param value The repeatedUint64 to add.
-     */
-    private void addRepeatedUint64(long value) {
-      ensureRepeatedUint64IsMutable();
-      repeatedUint64_.addLong(value);
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-     * @param values The repeatedUint64 to add.
-     */
-    private void addAllRepeatedUint64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedUint64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedUint64_);
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-     */
-    private void clearRepeatedUint64() {
-      repeatedUint64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_SINT32_FIELD_NUMBER = 5;
-    private com.google.protobuf.Internal.IntList repeatedSint32_;
-    /**
-     * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-     * @return A list containing the repeatedSint32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedSint32List() {
-      return repeatedSint32_;
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-     * @return The count of repeatedSint32.
-     */
-    @java.lang.Override
-    public int getRepeatedSint32Count() {
-      return repeatedSint32_.size();
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSint32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedSint32(int index) {
-      return repeatedSint32_.getInt(index);
-    }
-    private void ensureRepeatedSint32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedSint32_;
-      if (!tmp.isModifiable()) {
-        repeatedSint32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSint32 to set.
-     */
-    private void setRepeatedSint32(
-        int index, int value) {
-      ensureRepeatedSint32IsMutable();
-      repeatedSint32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-     * @param value The repeatedSint32 to add.
-     */
-    private void addRepeatedSint32(int value) {
-      ensureRepeatedSint32IsMutable();
-      repeatedSint32_.addInt(value);
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-     * @param values The repeatedSint32 to add.
-     */
-    private void addAllRepeatedSint32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedSint32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedSint32_);
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-     */
-    private void clearRepeatedSint32() {
-      repeatedSint32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_SINT64_FIELD_NUMBER = 6;
-    private com.google.protobuf.Internal.LongList repeatedSint64_;
-    /**
-     * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-     * @return A list containing the repeatedSint64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedSint64List() {
-      return repeatedSint64_;
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-     * @return The count of repeatedSint64.
-     */
-    @java.lang.Override
-    public int getRepeatedSint64Count() {
-      return repeatedSint64_.size();
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSint64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedSint64(int index) {
-      return repeatedSint64_.getLong(index);
-    }
-    private void ensureRepeatedSint64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedSint64_;
-      if (!tmp.isModifiable()) {
-        repeatedSint64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSint64 to set.
-     */
-    private void setRepeatedSint64(
-        int index, long value) {
-      ensureRepeatedSint64IsMutable();
-      repeatedSint64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-     * @param value The repeatedSint64 to add.
-     */
-    private void addRepeatedSint64(long value) {
-      ensureRepeatedSint64IsMutable();
-      repeatedSint64_.addLong(value);
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-     * @param values The repeatedSint64 to add.
-     */
-    private void addAllRepeatedSint64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedSint64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedSint64_);
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-     */
-    private void clearRepeatedSint64() {
-      repeatedSint64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_FIXED32_FIELD_NUMBER = 7;
-    private com.google.protobuf.Internal.IntList repeatedFixed32_;
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-     * @return A list containing the repeatedFixed32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedFixed32List() {
-      return repeatedFixed32_;
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-     * @return The count of repeatedFixed32.
-     */
-    @java.lang.Override
-    public int getRepeatedFixed32Count() {
-      return repeatedFixed32_.size();
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedFixed32(int index) {
-      return repeatedFixed32_.getInt(index);
-    }
-    private void ensureRepeatedFixed32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedFixed32_;
-      if (!tmp.isModifiable()) {
-        repeatedFixed32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed32 to set.
-     */
-    private void setRepeatedFixed32(
-        int index, int value) {
-      ensureRepeatedFixed32IsMutable();
-      repeatedFixed32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-     * @param value The repeatedFixed32 to add.
-     */
-    private void addRepeatedFixed32(int value) {
-      ensureRepeatedFixed32IsMutable();
-      repeatedFixed32_.addInt(value);
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-     * @param values The repeatedFixed32 to add.
-     */
-    private void addAllRepeatedFixed32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedFixed32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedFixed32_);
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-     */
-    private void clearRepeatedFixed32() {
-      repeatedFixed32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_FIXED64_FIELD_NUMBER = 8;
-    private com.google.protobuf.Internal.LongList repeatedFixed64_;
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-     * @return A list containing the repeatedFixed64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedFixed64List() {
-      return repeatedFixed64_;
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-     * @return The count of repeatedFixed64.
-     */
-    @java.lang.Override
-    public int getRepeatedFixed64Count() {
-      return repeatedFixed64_.size();
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedFixed64(int index) {
-      return repeatedFixed64_.getLong(index);
-    }
-    private void ensureRepeatedFixed64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedFixed64_;
-      if (!tmp.isModifiable()) {
-        repeatedFixed64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed64 to set.
-     */
-    private void setRepeatedFixed64(
-        int index, long value) {
-      ensureRepeatedFixed64IsMutable();
-      repeatedFixed64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-     * @param value The repeatedFixed64 to add.
-     */
-    private void addRepeatedFixed64(long value) {
-      ensureRepeatedFixed64IsMutable();
-      repeatedFixed64_.addLong(value);
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-     * @param values The repeatedFixed64 to add.
-     */
-    private void addAllRepeatedFixed64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedFixed64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedFixed64_);
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-     */
-    private void clearRepeatedFixed64() {
-      repeatedFixed64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_SFIXED32_FIELD_NUMBER = 9;
-    private com.google.protobuf.Internal.IntList repeatedSfixed32_;
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-     * @return A list containing the repeatedSfixed32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedSfixed32List() {
-      return repeatedSfixed32_;
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-     * @return The count of repeatedSfixed32.
-     */
-    @java.lang.Override
-    public int getRepeatedSfixed32Count() {
-      return repeatedSfixed32_.size();
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSfixed32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedSfixed32(int index) {
-      return repeatedSfixed32_.getInt(index);
-    }
-    private void ensureRepeatedSfixed32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedSfixed32_;
-      if (!tmp.isModifiable()) {
-        repeatedSfixed32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSfixed32 to set.
-     */
-    private void setRepeatedSfixed32(
-        int index, int value) {
-      ensureRepeatedSfixed32IsMutable();
-      repeatedSfixed32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-     * @param value The repeatedSfixed32 to add.
-     */
-    private void addRepeatedSfixed32(int value) {
-      ensureRepeatedSfixed32IsMutable();
-      repeatedSfixed32_.addInt(value);
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-     * @param values The repeatedSfixed32 to add.
-     */
-    private void addAllRepeatedSfixed32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedSfixed32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedSfixed32_);
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-     */
-    private void clearRepeatedSfixed32() {
-      repeatedSfixed32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_SFIXED64_FIELD_NUMBER = 10;
-    private com.google.protobuf.Internal.LongList repeatedSfixed64_;
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-     * @return A list containing the repeatedSfixed64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedSfixed64List() {
-      return repeatedSfixed64_;
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-     * @return The count of repeatedSfixed64.
-     */
-    @java.lang.Override
-    public int getRepeatedSfixed64Count() {
-      return repeatedSfixed64_.size();
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSfixed64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedSfixed64(int index) {
-      return repeatedSfixed64_.getLong(index);
-    }
-    private void ensureRepeatedSfixed64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedSfixed64_;
-      if (!tmp.isModifiable()) {
-        repeatedSfixed64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSfixed64 to set.
-     */
-    private void setRepeatedSfixed64(
-        int index, long value) {
-      ensureRepeatedSfixed64IsMutable();
-      repeatedSfixed64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-     * @param value The repeatedSfixed64 to add.
-     */
-    private void addRepeatedSfixed64(long value) {
-      ensureRepeatedSfixed64IsMutable();
-      repeatedSfixed64_.addLong(value);
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-     * @param values The repeatedSfixed64 to add.
-     */
-    private void addAllRepeatedSfixed64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedSfixed64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedSfixed64_);
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-     */
-    private void clearRepeatedSfixed64() {
-      repeatedSfixed64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_FLOAT_FIELD_NUMBER = 11;
-    private com.google.protobuf.Internal.FloatList repeatedFloat_;
-    /**
-     * <code>repeated float repeated_float = 11 [packed = false];</code>
-     * @return A list containing the repeatedFloat.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Float>
-        getRepeatedFloatList() {
-      return repeatedFloat_;
-    }
-    /**
-     * <code>repeated float repeated_float = 11 [packed = false];</code>
-     * @return The count of repeatedFloat.
-     */
-    @java.lang.Override
-    public int getRepeatedFloatCount() {
-      return repeatedFloat_.size();
-    }
-    /**
-     * <code>repeated float repeated_float = 11 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFloat at the given index.
-     */
-    @java.lang.Override
-    public float getRepeatedFloat(int index) {
-      return repeatedFloat_.getFloat(index);
-    }
-    private void ensureRepeatedFloatIsMutable() {
-      com.google.protobuf.Internal.FloatList tmp = repeatedFloat_;
-      if (!tmp.isModifiable()) {
-        repeatedFloat_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated float repeated_float = 11 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFloat to set.
-     */
-    private void setRepeatedFloat(
-        int index, float value) {
-      ensureRepeatedFloatIsMutable();
-      repeatedFloat_.setFloat(index, value);
-    }
-    /**
-     * <code>repeated float repeated_float = 11 [packed = false];</code>
-     * @param value The repeatedFloat to add.
-     */
-    private void addRepeatedFloat(float value) {
-      ensureRepeatedFloatIsMutable();
-      repeatedFloat_.addFloat(value);
-    }
-    /**
-     * <code>repeated float repeated_float = 11 [packed = false];</code>
-     * @param values The repeatedFloat to add.
-     */
-    private void addAllRepeatedFloat(
-        java.lang.Iterable<? extends java.lang.Float> values) {
-      ensureRepeatedFloatIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedFloat_);
-    }
-    /**
-     * <code>repeated float repeated_float = 11 [packed = false];</code>
-     */
-    private void clearRepeatedFloat() {
-      repeatedFloat_ = emptyFloatList();
-    }
-
-    public static final int REPEATED_DOUBLE_FIELD_NUMBER = 12;
-    private com.google.protobuf.Internal.DoubleList repeatedDouble_;
-    /**
-     * <code>repeated double repeated_double = 12 [packed = false];</code>
-     * @return A list containing the repeatedDouble.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Double>
-        getRepeatedDoubleList() {
-      return repeatedDouble_;
-    }
-    /**
-     * <code>repeated double repeated_double = 12 [packed = false];</code>
-     * @return The count of repeatedDouble.
-     */
-    @java.lang.Override
-    public int getRepeatedDoubleCount() {
-      return repeatedDouble_.size();
-    }
-    /**
-     * <code>repeated double repeated_double = 12 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedDouble at the given index.
-     */
-    @java.lang.Override
-    public double getRepeatedDouble(int index) {
-      return repeatedDouble_.getDouble(index);
-    }
-    private void ensureRepeatedDoubleIsMutable() {
-      com.google.protobuf.Internal.DoubleList tmp = repeatedDouble_;
-      if (!tmp.isModifiable()) {
-        repeatedDouble_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated double repeated_double = 12 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedDouble to set.
-     */
-    private void setRepeatedDouble(
-        int index, double value) {
-      ensureRepeatedDoubleIsMutable();
-      repeatedDouble_.setDouble(index, value);
-    }
-    /**
-     * <code>repeated double repeated_double = 12 [packed = false];</code>
-     * @param value The repeatedDouble to add.
-     */
-    private void addRepeatedDouble(double value) {
-      ensureRepeatedDoubleIsMutable();
-      repeatedDouble_.addDouble(value);
-    }
-    /**
-     * <code>repeated double repeated_double = 12 [packed = false];</code>
-     * @param values The repeatedDouble to add.
-     */
-    private void addAllRepeatedDouble(
-        java.lang.Iterable<? extends java.lang.Double> values) {
-      ensureRepeatedDoubleIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedDouble_);
-    }
-    /**
-     * <code>repeated double repeated_double = 12 [packed = false];</code>
-     */
-    private void clearRepeatedDouble() {
-      repeatedDouble_ = emptyDoubleList();
-    }
-
-    public static final int REPEATED_BOOL_FIELD_NUMBER = 13;
-    private com.google.protobuf.Internal.BooleanList repeatedBool_;
-    /**
-     * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-     * @return A list containing the repeatedBool.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Boolean>
-        getRepeatedBoolList() {
-      return repeatedBool_;
-    }
-    /**
-     * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-     * @return The count of repeatedBool.
-     */
-    @java.lang.Override
-    public int getRepeatedBoolCount() {
-      return repeatedBool_.size();
-    }
-    /**
-     * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedBool at the given index.
-     */
-    @java.lang.Override
-    public boolean getRepeatedBool(int index) {
-      return repeatedBool_.getBoolean(index);
-    }
-    private void ensureRepeatedBoolIsMutable() {
-      com.google.protobuf.Internal.BooleanList tmp = repeatedBool_;
-      if (!tmp.isModifiable()) {
-        repeatedBool_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedBool to set.
-     */
-    private void setRepeatedBool(
-        int index, boolean value) {
-      ensureRepeatedBoolIsMutable();
-      repeatedBool_.setBoolean(index, value);
-    }
-    /**
-     * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-     * @param value The repeatedBool to add.
-     */
-    private void addRepeatedBool(boolean value) {
-      ensureRepeatedBoolIsMutable();
-      repeatedBool_.addBoolean(value);
-    }
-    /**
-     * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-     * @param values The repeatedBool to add.
-     */
-    private void addAllRepeatedBool(
-        java.lang.Iterable<? extends java.lang.Boolean> values) {
-      ensureRepeatedBoolIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedBool_);
-    }
-    /**
-     * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-     */
-    private void clearRepeatedBool() {
-      repeatedBool_ = emptyBooleanList();
-    }
-
-    public static final int REPEATED_NESTED_ENUM_FIELD_NUMBER = 14;
-    private com.google.protobuf.Internal.IntList repeatedNestedEnum_;
-    private static final com.google.protobuf.Internal.ListAdapter.Converter<
-        java.lang.Integer, proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum> repeatedNestedEnum_converter_ =
-            new com.google.protobuf.Internal.ListAdapter.Converter<
-                java.lang.Integer, proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum>() {
-              @java.lang.Override
-              public proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum convert(java.lang.Integer from) {
-                proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum result = proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum.forNumber(from);
-                return result == null ? proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum.UNRECOGNIZED : result;
-              }
-            };
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @return A list containing the repeatedNestedEnum.
-     */
-    @java.lang.Override
-    public java.util.List<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum> getRepeatedNestedEnumList() {
-      return new com.google.protobuf.Internal.ListAdapter<
-          java.lang.Integer, proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum>(repeatedNestedEnum_, repeatedNestedEnum_converter_);
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @return The count of repeatedNestedEnum.
-     */
-    @java.lang.Override
-    public int getRepeatedNestedEnumCount() {
-      return repeatedNestedEnum_.size();
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedNestedEnum at the given index.
-     */
-    @java.lang.Override
-    public proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum getRepeatedNestedEnum(int index) {
-      return repeatedNestedEnum_converter_.convert(repeatedNestedEnum_.getInt(index));
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @return A list containing the enum numeric values on the wire for repeatedNestedEnum.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-    getRepeatedNestedEnumValueList() {
-      return repeatedNestedEnum_;
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @param index The index of the value to return.
-     * @return The enum numeric value on the wire of repeatedNestedEnum at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedNestedEnumValue(int index) {
-      return repeatedNestedEnum_.getInt(index);
-    }
-    private void ensureRepeatedNestedEnumIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedNestedEnum_;
-      if (!tmp.isModifiable()) {
-        repeatedNestedEnum_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-      }
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedNestedEnum to set.
-     */
-    private void setRepeatedNestedEnum(
-        int index, proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum value) {
-      value.getClass();
-  ensureRepeatedNestedEnumIsMutable();
-      repeatedNestedEnum_.setInt(index, value.getNumber());
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @param value The repeatedNestedEnum to add.
-     */
-    private void addRepeatedNestedEnum(proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum value) {
-      value.getClass();
-  ensureRepeatedNestedEnumIsMutable();
-      repeatedNestedEnum_.addInt(value.getNumber());
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @param values The repeatedNestedEnum to add.
-     */
-    private void addAllRepeatedNestedEnum(
-        java.lang.Iterable<? extends proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum> values) {
-      ensureRepeatedNestedEnumIsMutable();
-      for (proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum value : values) {
-        repeatedNestedEnum_.addInt(value.getNumber());
-      }
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     */
-    private void clearRepeatedNestedEnum() {
-      repeatedNestedEnum_ = emptyIntList();
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @param value The enum numeric value on the wire for repeatedNestedEnum to set.
-     */
-    private void setRepeatedNestedEnumValue(
-        int index, int value) {
-      ensureRepeatedNestedEnumIsMutable();
-      repeatedNestedEnum_.setInt(index, value);
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @param value The enum numeric value on the wire for repeatedNestedEnum to add.
-     */
-    private void addRepeatedNestedEnumValue(int value) {
-      ensureRepeatedNestedEnumIsMutable();
-      repeatedNestedEnum_.addInt(value);
-    }
-    /**
-     * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-     * @param values The enum numeric values on the wire for repeatedNestedEnum to add.
-     */
-    private void addAllRepeatedNestedEnumValue(
-        java.lang.Iterable<java.lang.Integer> values) {
-      ensureRepeatedNestedEnumIsMutable();
-      for (int value : values) {
-        repeatedNestedEnum_.addInt(value);
-      }
-    }
-
-    public static proto3_unittest.UnittestProto3.TestUnpackedTypes parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.TestUnpackedTypes parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestUnpackedTypes parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.TestUnpackedTypes parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestUnpackedTypes parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.TestUnpackedTypes parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestUnpackedTypes parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.TestUnpackedTypes parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestUnpackedTypes parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.TestUnpackedTypes parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestUnpackedTypes parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.TestUnpackedTypes parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(proto3_unittest.UnittestProto3.TestUnpackedTypes prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Explicitly set packed to false
-     * </pre>
-     *
-     * Protobuf type {@code proto3_unittest.TestUnpackedTypes}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          proto3_unittest.UnittestProto3.TestUnpackedTypes, Builder> implements
-        // @@protoc_insertion_point(builder_implements:proto3_unittest.TestUnpackedTypes)
-        proto3_unittest.UnittestProto3.TestUnpackedTypesOrBuilder {
-      // Construct using proto3_unittest.UnittestProto3.TestUnpackedTypes.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-       * @return A list containing the repeatedInt32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedInt32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedInt32List());
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-       * @return The count of repeatedInt32.
-       */
-      @java.lang.Override
-      public int getRepeatedInt32Count() {
-        return instance.getRepeatedInt32Count();
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedInt32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedInt32(int index) {
-        return instance.getRepeatedInt32(index);
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-       * @param value The repeatedInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedInt32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedInt32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-       * @param value The repeatedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedInt32(int value) {
-        copyOnWrite();
-        instance.addRepeatedInt32(value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-       * @param values The repeatedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedInt32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedInt32(values);
-        return this;
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 1 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedInt32() {
-        copyOnWrite();
-        instance.clearRepeatedInt32();
-        return this;
-      }
-
-      /**
-       * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-       * @return A list containing the repeatedInt64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedInt64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedInt64List());
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-       * @return The count of repeatedInt64.
-       */
-      @java.lang.Override
-      public int getRepeatedInt64Count() {
-        return instance.getRepeatedInt64Count();
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedInt64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedInt64(int index) {
-        return instance.getRepeatedInt64(index);
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-       * @param value The repeatedInt64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedInt64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedInt64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-       * @param value The repeatedInt64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedInt64(long value) {
-        copyOnWrite();
-        instance.addRepeatedInt64(value);
-        return this;
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-       * @param values The repeatedInt64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedInt64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedInt64(values);
-        return this;
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 2 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedInt64() {
-        copyOnWrite();
-        instance.clearRepeatedInt64();
-        return this;
-      }
-
-      /**
-       * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-       * @return A list containing the repeatedUint32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedUint32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedUint32List());
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-       * @return The count of repeatedUint32.
-       */
-      @java.lang.Override
-      public int getRepeatedUint32Count() {
-        return instance.getRepeatedUint32Count();
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedUint32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedUint32(int index) {
-        return instance.getRepeatedUint32(index);
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-       * @param value The repeatedUint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedUint32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedUint32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-       * @param value The repeatedUint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedUint32(int value) {
-        copyOnWrite();
-        instance.addRepeatedUint32(value);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-       * @param values The repeatedUint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedUint32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedUint32(values);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 3 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedUint32() {
-        copyOnWrite();
-        instance.clearRepeatedUint32();
-        return this;
-      }
-
-      /**
-       * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-       * @return A list containing the repeatedUint64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedUint64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedUint64List());
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-       * @return The count of repeatedUint64.
-       */
-      @java.lang.Override
-      public int getRepeatedUint64Count() {
-        return instance.getRepeatedUint64Count();
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedUint64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedUint64(int index) {
-        return instance.getRepeatedUint64(index);
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-       * @param value The repeatedUint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedUint64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedUint64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-       * @param value The repeatedUint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedUint64(long value) {
-        copyOnWrite();
-        instance.addRepeatedUint64(value);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-       * @param values The repeatedUint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedUint64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedUint64(values);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 4 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedUint64() {
-        copyOnWrite();
-        instance.clearRepeatedUint64();
-        return this;
-      }
-
-      /**
-       * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-       * @return A list containing the repeatedSint32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedSint32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedSint32List());
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-       * @return The count of repeatedSint32.
-       */
-      @java.lang.Override
-      public int getRepeatedSint32Count() {
-        return instance.getRepeatedSint32Count();
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedSint32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedSint32(int index) {
-        return instance.getRepeatedSint32(index);
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-       * @param value The repeatedSint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedSint32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedSint32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-       * @param value The repeatedSint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedSint32(int value) {
-        copyOnWrite();
-        instance.addRepeatedSint32(value);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-       * @param values The repeatedSint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedSint32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedSint32(values);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 5 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedSint32() {
-        copyOnWrite();
-        instance.clearRepeatedSint32();
-        return this;
-      }
-
-      /**
-       * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-       * @return A list containing the repeatedSint64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedSint64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedSint64List());
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-       * @return The count of repeatedSint64.
-       */
-      @java.lang.Override
-      public int getRepeatedSint64Count() {
-        return instance.getRepeatedSint64Count();
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedSint64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedSint64(int index) {
-        return instance.getRepeatedSint64(index);
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-       * @param value The repeatedSint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedSint64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedSint64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-       * @param value The repeatedSint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedSint64(long value) {
-        copyOnWrite();
-        instance.addRepeatedSint64(value);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-       * @param values The repeatedSint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedSint64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedSint64(values);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 6 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedSint64() {
-        copyOnWrite();
-        instance.clearRepeatedSint64();
-        return this;
-      }
-
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-       * @return A list containing the repeatedFixed32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedFixed32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedFixed32List());
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-       * @return The count of repeatedFixed32.
-       */
-      @java.lang.Override
-      public int getRepeatedFixed32Count() {
-        return instance.getRepeatedFixed32Count();
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedFixed32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedFixed32(int index) {
-        return instance.getRepeatedFixed32(index);
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-       * @param value The repeatedFixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedFixed32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedFixed32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-       * @param value The repeatedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedFixed32(int value) {
-        copyOnWrite();
-        instance.addRepeatedFixed32(value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-       * @param values The repeatedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedFixed32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedFixed32(values);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 7 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedFixed32() {
-        copyOnWrite();
-        instance.clearRepeatedFixed32();
-        return this;
-      }
-
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-       * @return A list containing the repeatedFixed64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedFixed64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedFixed64List());
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-       * @return The count of repeatedFixed64.
-       */
-      @java.lang.Override
-      public int getRepeatedFixed64Count() {
-        return instance.getRepeatedFixed64Count();
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedFixed64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedFixed64(int index) {
-        return instance.getRepeatedFixed64(index);
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-       * @param value The repeatedFixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedFixed64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedFixed64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-       * @param value The repeatedFixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedFixed64(long value) {
-        copyOnWrite();
-        instance.addRepeatedFixed64(value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-       * @param values The repeatedFixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedFixed64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedFixed64(values);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 8 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedFixed64() {
-        copyOnWrite();
-        instance.clearRepeatedFixed64();
-        return this;
-      }
-
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-       * @return A list containing the repeatedSfixed32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedSfixed32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedSfixed32List());
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-       * @return The count of repeatedSfixed32.
-       */
-      @java.lang.Override
-      public int getRepeatedSfixed32Count() {
-        return instance.getRepeatedSfixed32Count();
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedSfixed32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedSfixed32(int index) {
-        return instance.getRepeatedSfixed32(index);
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-       * @param value The repeatedSfixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedSfixed32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedSfixed32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-       * @param value The repeatedSfixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedSfixed32(int value) {
-        copyOnWrite();
-        instance.addRepeatedSfixed32(value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-       * @param values The repeatedSfixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedSfixed32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedSfixed32(values);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 9 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedSfixed32() {
-        copyOnWrite();
-        instance.clearRepeatedSfixed32();
-        return this;
-      }
-
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-       * @return A list containing the repeatedSfixed64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedSfixed64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedSfixed64List());
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-       * @return The count of repeatedSfixed64.
-       */
-      @java.lang.Override
-      public int getRepeatedSfixed64Count() {
-        return instance.getRepeatedSfixed64Count();
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedSfixed64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedSfixed64(int index) {
-        return instance.getRepeatedSfixed64(index);
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-       * @param value The repeatedSfixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedSfixed64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedSfixed64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-       * @param value The repeatedSfixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedSfixed64(long value) {
-        copyOnWrite();
-        instance.addRepeatedSfixed64(value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-       * @param values The repeatedSfixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedSfixed64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedSfixed64(values);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 10 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedSfixed64() {
-        copyOnWrite();
-        instance.clearRepeatedSfixed64();
-        return this;
-      }
-
-      /**
-       * <code>repeated float repeated_float = 11 [packed = false];</code>
-       * @return A list containing the repeatedFloat.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Float>
-          getRepeatedFloatList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedFloatList());
-      }
-      /**
-       * <code>repeated float repeated_float = 11 [packed = false];</code>
-       * @return The count of repeatedFloat.
-       */
-      @java.lang.Override
-      public int getRepeatedFloatCount() {
-        return instance.getRepeatedFloatCount();
-      }
-      /**
-       * <code>repeated float repeated_float = 11 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedFloat at the given index.
-       */
-      @java.lang.Override
-      public float getRepeatedFloat(int index) {
-        return instance.getRepeatedFloat(index);
-      }
-      /**
-       * <code>repeated float repeated_float = 11 [packed = false];</code>
-       * @param value The repeatedFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedFloat(
-          int index, float value) {
-        copyOnWrite();
-        instance.setRepeatedFloat(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated float repeated_float = 11 [packed = false];</code>
-       * @param value The repeatedFloat to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedFloat(float value) {
-        copyOnWrite();
-        instance.addRepeatedFloat(value);
-        return this;
-      }
-      /**
-       * <code>repeated float repeated_float = 11 [packed = false];</code>
-       * @param values The repeatedFloat to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedFloat(
-          java.lang.Iterable<? extends java.lang.Float> values) {
-        copyOnWrite();
-        instance.addAllRepeatedFloat(values);
-        return this;
-      }
-      /**
-       * <code>repeated float repeated_float = 11 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedFloat() {
-        copyOnWrite();
-        instance.clearRepeatedFloat();
-        return this;
-      }
-
-      /**
-       * <code>repeated double repeated_double = 12 [packed = false];</code>
-       * @return A list containing the repeatedDouble.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Double>
-          getRepeatedDoubleList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedDoubleList());
-      }
-      /**
-       * <code>repeated double repeated_double = 12 [packed = false];</code>
-       * @return The count of repeatedDouble.
-       */
-      @java.lang.Override
-      public int getRepeatedDoubleCount() {
-        return instance.getRepeatedDoubleCount();
-      }
-      /**
-       * <code>repeated double repeated_double = 12 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedDouble at the given index.
-       */
-      @java.lang.Override
-      public double getRepeatedDouble(int index) {
-        return instance.getRepeatedDouble(index);
-      }
-      /**
-       * <code>repeated double repeated_double = 12 [packed = false];</code>
-       * @param value The repeatedDouble to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedDouble(
-          int index, double value) {
-        copyOnWrite();
-        instance.setRepeatedDouble(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated double repeated_double = 12 [packed = false];</code>
-       * @param value The repeatedDouble to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedDouble(double value) {
-        copyOnWrite();
-        instance.addRepeatedDouble(value);
-        return this;
-      }
-      /**
-       * <code>repeated double repeated_double = 12 [packed = false];</code>
-       * @param values The repeatedDouble to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedDouble(
-          java.lang.Iterable<? extends java.lang.Double> values) {
-        copyOnWrite();
-        instance.addAllRepeatedDouble(values);
-        return this;
-      }
-      /**
-       * <code>repeated double repeated_double = 12 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedDouble() {
-        copyOnWrite();
-        instance.clearRepeatedDouble();
-        return this;
-      }
-
-      /**
-       * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-       * @return A list containing the repeatedBool.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Boolean>
-          getRepeatedBoolList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedBoolList());
-      }
-      /**
-       * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-       * @return The count of repeatedBool.
-       */
-      @java.lang.Override
-      public int getRepeatedBoolCount() {
-        return instance.getRepeatedBoolCount();
-      }
-      /**
-       * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedBool at the given index.
-       */
-      @java.lang.Override
-      public boolean getRepeatedBool(int index) {
-        return instance.getRepeatedBool(index);
-      }
-      /**
-       * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-       * @param value The repeatedBool to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedBool(
-          int index, boolean value) {
-        copyOnWrite();
-        instance.setRepeatedBool(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-       * @param value The repeatedBool to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedBool(boolean value) {
-        copyOnWrite();
-        instance.addRepeatedBool(value);
-        return this;
-      }
-      /**
-       * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-       * @param values The repeatedBool to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedBool(
-          java.lang.Iterable<? extends java.lang.Boolean> values) {
-        copyOnWrite();
-        instance.addAllRepeatedBool(values);
-        return this;
-      }
-      /**
-       * <code>repeated bool repeated_bool = 13 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedBool() {
-        copyOnWrite();
-        instance.clearRepeatedBool();
-        return this;
-      }
-
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-       * @return A list containing the repeatedNestedEnum.
-       */
-      @java.lang.Override
-      public java.util.List<proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum> getRepeatedNestedEnumList() {
-        return instance.getRepeatedNestedEnumList();
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-       * @return The count of repeatedNestedEnum.
-       */
-      @java.lang.Override
-      public int getRepeatedNestedEnumCount() {
-        return instance.getRepeatedNestedEnumCount();
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedNestedEnum at the given index.
-       */
-      @java.lang.Override
-      public proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum getRepeatedNestedEnum(int index) {
-        return instance.getRepeatedNestedEnum(index);
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedNestedEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedNestedEnum(
-          int index, proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum value) {
-        copyOnWrite();
-        instance.setRepeatedNestedEnum(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-       * @param value The repeatedNestedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedNestedEnum(proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum value) {
-        copyOnWrite();
-        instance.addRepeatedNestedEnum(value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-       * @param values The repeatedNestedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedNestedEnum(
-          java.lang.Iterable<? extends proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum> values) {
-        copyOnWrite();
-        instance.addAllRepeatedNestedEnum(values);  return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedNestedEnum() {
-        copyOnWrite();
-        instance.clearRepeatedNestedEnum();
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-       * @return A list containing the enum numeric values on the wire for repeatedNestedEnum.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-      getRepeatedNestedEnumValueList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedNestedEnumValueList());
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-       * @param index The index of the value to return.
-       * @return The enum numeric value on the wire of repeatedNestedEnum at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedNestedEnumValue(int index) {
-        return instance.getRepeatedNestedEnumValue(index);
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-       * @param index The index to set the value at.
-       * @param value The enum numeric value on the wire for repeatedNestedEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedNestedEnumValue(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedNestedEnumValue(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-       * @param value The enum numeric value on the wire for repeatedNestedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedNestedEnumValue(int value) {
-        instance.addRepeatedNestedEnumValue(value);
-        return this;
-      }
-      /**
-       * <code>repeated .proto3_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];</code>
-       * @param values The enum numeric values on the wire for repeatedNestedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedNestedEnumValue(
-          java.lang.Iterable<java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedNestedEnumValue(values);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:proto3_unittest.TestUnpackedTypes)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new proto3_unittest.UnittestProto3.TestUnpackedTypes();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "repeatedInt32_",
-              "repeatedInt64_",
-              "repeatedUint32_",
-              "repeatedUint64_",
-              "repeatedSint32_",
-              "repeatedSint64_",
-              "repeatedFixed32_",
-              "repeatedFixed64_",
-              "repeatedSfixed32_",
-              "repeatedSfixed64_",
-              "repeatedFloat_",
-              "repeatedDouble_",
-              "repeatedBool_",
-              "repeatedNestedEnum_",
-            };
-            java.lang.String info =
-                "\u0000\u000e\u0000\u0000\u0001\u000e\u000e\u0000\u000e\u0000\u0001\u0016\u0002\u0014" +
-                "\u0003\u001d\u0004\u0015\u0005!\u0006\"\u0007\u0018\b\u0017\t\u001f\n \u000b\u0013" +
-                "\f\u0012\r\u0019\u000e\u001e";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<proto3_unittest.UnittestProto3.TestUnpackedTypes> parser = PARSER;
-          if (parser == null) {
-            synchronized (proto3_unittest.UnittestProto3.TestUnpackedTypes.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<proto3_unittest.UnittestProto3.TestUnpackedTypes>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:proto3_unittest.TestUnpackedTypes)
-    private static final proto3_unittest.UnittestProto3.TestUnpackedTypes DEFAULT_INSTANCE;
-    static {
-      TestUnpackedTypes defaultInstance = new TestUnpackedTypes();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestUnpackedTypes.class, defaultInstance);
-    }
-
-    public static proto3_unittest.UnittestProto3.TestUnpackedTypes getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestUnpackedTypes> PARSER;
-
-    public static com.google.protobuf.Parser<TestUnpackedTypes> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface NestedTestAllTypesOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:proto3_unittest.NestedTestAllTypes)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>.proto3_unittest.NestedTestAllTypes child = 1;</code>
-     * @return Whether the child field is set.
-     */
-    boolean hasChild();
-    /**
-     * <code>.proto3_unittest.NestedTestAllTypes child = 1;</code>
-     * @return The child.
-     */
-    proto3_unittest.UnittestProto3.NestedTestAllTypes getChild();
-
-    /**
-     * <code>.proto3_unittest.TestAllTypes payload = 2;</code>
-     * @return Whether the payload field is set.
-     */
-    boolean hasPayload();
-    /**
-     * <code>.proto3_unittest.TestAllTypes payload = 2;</code>
-     * @return The payload.
-     */
-    proto3_unittest.UnittestProto3.TestAllTypes getPayload();
-  }
-  /**
-   * <pre>
-   * This proto includes a recursively nested message.
-   * </pre>
-   *
-   * Protobuf type {@code proto3_unittest.NestedTestAllTypes}
-   */
-  public  static final class NestedTestAllTypes extends
-      com.google.protobuf.GeneratedMessageLite<
-          NestedTestAllTypes, NestedTestAllTypes.Builder> implements
-      // @@protoc_insertion_point(message_implements:proto3_unittest.NestedTestAllTypes)
-      NestedTestAllTypesOrBuilder {
-    private NestedTestAllTypes() {
-    }
-    public static final int CHILD_FIELD_NUMBER = 1;
-    private proto3_unittest.UnittestProto3.NestedTestAllTypes child_;
-    /**
-     * <code>.proto3_unittest.NestedTestAllTypes child = 1;</code>
-     */
-    @java.lang.Override
-    public boolean hasChild() {
-      return child_ != null;
-    }
-    /**
-     * <code>.proto3_unittest.NestedTestAllTypes child = 1;</code>
-     */
-    @java.lang.Override
-    public proto3_unittest.UnittestProto3.NestedTestAllTypes getChild() {
-      return child_ == null ? proto3_unittest.UnittestProto3.NestedTestAllTypes.getDefaultInstance() : child_;
-    }
-    /**
-     * <code>.proto3_unittest.NestedTestAllTypes child = 1;</code>
-     */
-    private void setChild(proto3_unittest.UnittestProto3.NestedTestAllTypes value) {
-      value.getClass();
-  child_ = value;
-      
-      }
-    /**
-     * <code>.proto3_unittest.NestedTestAllTypes child = 1;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeChild(proto3_unittest.UnittestProto3.NestedTestAllTypes value) {
-      value.getClass();
-  if (child_ != null &&
-          child_ != proto3_unittest.UnittestProto3.NestedTestAllTypes.getDefaultInstance()) {
-        child_ =
-          proto3_unittest.UnittestProto3.NestedTestAllTypes.newBuilder(child_).mergeFrom(value).buildPartial();
-      } else {
-        child_ = value;
-      }
-      
-    }
-    /**
-     * <code>.proto3_unittest.NestedTestAllTypes child = 1;</code>
-     */
-    private void clearChild() {  child_ = null;
-      
-    }
-
-    public static final int PAYLOAD_FIELD_NUMBER = 2;
-    private proto3_unittest.UnittestProto3.TestAllTypes payload_;
-    /**
-     * <code>.proto3_unittest.TestAllTypes payload = 2;</code>
-     */
-    @java.lang.Override
-    public boolean hasPayload() {
-      return payload_ != null;
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes payload = 2;</code>
-     */
-    @java.lang.Override
-    public proto3_unittest.UnittestProto3.TestAllTypes getPayload() {
-      return payload_ == null ? proto3_unittest.UnittestProto3.TestAllTypes.getDefaultInstance() : payload_;
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes payload = 2;</code>
-     */
-    private void setPayload(proto3_unittest.UnittestProto3.TestAllTypes value) {
-      value.getClass();
-  payload_ = value;
-      
-      }
-    /**
-     * <code>.proto3_unittest.TestAllTypes payload = 2;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergePayload(proto3_unittest.UnittestProto3.TestAllTypes value) {
-      value.getClass();
-  if (payload_ != null &&
-          payload_ != proto3_unittest.UnittestProto3.TestAllTypes.getDefaultInstance()) {
-        payload_ =
-          proto3_unittest.UnittestProto3.TestAllTypes.newBuilder(payload_).mergeFrom(value).buildPartial();
-      } else {
-        payload_ = value;
-      }
-      
-    }
-    /**
-     * <code>.proto3_unittest.TestAllTypes payload = 2;</code>
-     */
-    private void clearPayload() {  payload_ = null;
-      
-    }
-
-    public static proto3_unittest.UnittestProto3.NestedTestAllTypes parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.NestedTestAllTypes parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.NestedTestAllTypes parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.NestedTestAllTypes parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.NestedTestAllTypes parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.NestedTestAllTypes parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.NestedTestAllTypes parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.NestedTestAllTypes parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.NestedTestAllTypes parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.NestedTestAllTypes parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.NestedTestAllTypes parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.NestedTestAllTypes parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(proto3_unittest.UnittestProto3.NestedTestAllTypes prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * This proto includes a recursively nested message.
-     * </pre>
-     *
-     * Protobuf type {@code proto3_unittest.NestedTestAllTypes}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          proto3_unittest.UnittestProto3.NestedTestAllTypes, Builder> implements
-        // @@protoc_insertion_point(builder_implements:proto3_unittest.NestedTestAllTypes)
-        proto3_unittest.UnittestProto3.NestedTestAllTypesOrBuilder {
-      // Construct using proto3_unittest.UnittestProto3.NestedTestAllTypes.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>.proto3_unittest.NestedTestAllTypes child = 1;</code>
-       */
-      @java.lang.Override
-      public boolean hasChild() {
-        return instance.hasChild();
-      }
-      /**
-       * <code>.proto3_unittest.NestedTestAllTypes child = 1;</code>
-       */
-      @java.lang.Override
-      public proto3_unittest.UnittestProto3.NestedTestAllTypes getChild() {
-        return instance.getChild();
-      }
-      /**
-       * <code>.proto3_unittest.NestedTestAllTypes child = 1;</code>
-       */
-      public Builder setChild(proto3_unittest.UnittestProto3.NestedTestAllTypes value) {
-        copyOnWrite();
-        instance.setChild(value);
-        return this;
-        }
-      /**
-       * <code>.proto3_unittest.NestedTestAllTypes child = 1;</code>
-       */
-      public Builder setChild(
-          proto3_unittest.UnittestProto3.NestedTestAllTypes.Builder builderForValue) {
-        copyOnWrite();
-        instance.setChild(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.proto3_unittest.NestedTestAllTypes child = 1;</code>
-       */
-      public Builder mergeChild(proto3_unittest.UnittestProto3.NestedTestAllTypes value) {
-        copyOnWrite();
-        instance.mergeChild(value);
-        return this;
-      }
-      /**
-       * <code>.proto3_unittest.NestedTestAllTypes child = 1;</code>
-       */
-      public Builder clearChild() {  copyOnWrite();
-        instance.clearChild();
-        return this;
-      }
-
-      /**
-       * <code>.proto3_unittest.TestAllTypes payload = 2;</code>
-       */
-      @java.lang.Override
-      public boolean hasPayload() {
-        return instance.hasPayload();
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes payload = 2;</code>
-       */
-      @java.lang.Override
-      public proto3_unittest.UnittestProto3.TestAllTypes getPayload() {
-        return instance.getPayload();
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes payload = 2;</code>
-       */
-      public Builder setPayload(proto3_unittest.UnittestProto3.TestAllTypes value) {
-        copyOnWrite();
-        instance.setPayload(value);
-        return this;
-        }
-      /**
-       * <code>.proto3_unittest.TestAllTypes payload = 2;</code>
-       */
-      public Builder setPayload(
-          proto3_unittest.UnittestProto3.TestAllTypes.Builder builderForValue) {
-        copyOnWrite();
-        instance.setPayload(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes payload = 2;</code>
-       */
-      public Builder mergePayload(proto3_unittest.UnittestProto3.TestAllTypes value) {
-        copyOnWrite();
-        instance.mergePayload(value);
-        return this;
-      }
-      /**
-       * <code>.proto3_unittest.TestAllTypes payload = 2;</code>
-       */
-      public Builder clearPayload() {  copyOnWrite();
-        instance.clearPayload();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:proto3_unittest.NestedTestAllTypes)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new proto3_unittest.UnittestProto3.NestedTestAllTypes();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "child_",
-              "payload_",
-            };
-            java.lang.String info =
-                "\u0000\u0002\u0000\u0000\u0001\u0002\u0002\u0000\u0000\u0000\u0001\t\u0002\t";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<proto3_unittest.UnittestProto3.NestedTestAllTypes> parser = PARSER;
-          if (parser == null) {
-            synchronized (proto3_unittest.UnittestProto3.NestedTestAllTypes.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<proto3_unittest.UnittestProto3.NestedTestAllTypes>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:proto3_unittest.NestedTestAllTypes)
-    private static final proto3_unittest.UnittestProto3.NestedTestAllTypes DEFAULT_INSTANCE;
-    static {
-      NestedTestAllTypes defaultInstance = new NestedTestAllTypes();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        NestedTestAllTypes.class, defaultInstance);
-    }
-
-    public static proto3_unittest.UnittestProto3.NestedTestAllTypes getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<NestedTestAllTypes> PARSER;
-
-    public static com.google.protobuf.Parser<NestedTestAllTypes> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface ForeignMessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:proto3_unittest.ForeignMessage)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>int32 c = 1;</code>
-     * @return The c.
-     */
-    int getC();
-  }
-  /**
-   * <pre>
-   * Define these after TestAllTypes to make sure the compiler can handle
-   * that.
-   * </pre>
-   *
-   * Protobuf type {@code proto3_unittest.ForeignMessage}
-   */
-  public  static final class ForeignMessage extends
-      com.google.protobuf.GeneratedMessageLite<
-          ForeignMessage, ForeignMessage.Builder> implements
-      // @@protoc_insertion_point(message_implements:proto3_unittest.ForeignMessage)
-      ForeignMessageOrBuilder {
-    private ForeignMessage() {
-    }
-    public static final int C_FIELD_NUMBER = 1;
-    private int c_;
-    /**
-     * <code>int32 c = 1;</code>
-     * @return The c.
-     */
-    @java.lang.Override
-    public int getC() {
-      return c_;
-    }
-    /**
-     * <code>int32 c = 1;</code>
-     * @param value The c to set.
-     */
-    private void setC(int value) {
-      
-      c_ = value;
-    }
-    /**
-     * <code>int32 c = 1;</code>
-     */
-    private void clearC() {
-      
-      c_ = 0;
-    }
-
-    public static proto3_unittest.UnittestProto3.ForeignMessage parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.ForeignMessage parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.ForeignMessage parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.ForeignMessage parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.ForeignMessage parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.ForeignMessage parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.ForeignMessage parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.ForeignMessage parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.ForeignMessage parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.ForeignMessage parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.ForeignMessage parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.ForeignMessage parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(proto3_unittest.UnittestProto3.ForeignMessage prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Define these after TestAllTypes to make sure the compiler can handle
-     * that.
-     * </pre>
-     *
-     * Protobuf type {@code proto3_unittest.ForeignMessage}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          proto3_unittest.UnittestProto3.ForeignMessage, Builder> implements
-        // @@protoc_insertion_point(builder_implements:proto3_unittest.ForeignMessage)
-        proto3_unittest.UnittestProto3.ForeignMessageOrBuilder {
-      // Construct using proto3_unittest.UnittestProto3.ForeignMessage.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>int32 c = 1;</code>
-       * @return The c.
-       */
-      @java.lang.Override
-      public int getC() {
-        return instance.getC();
-      }
-      /**
-       * <code>int32 c = 1;</code>
-       * @param value The c to set.
-       * @return This builder for chaining.
-       */
-      public Builder setC(int value) {
-        copyOnWrite();
-        instance.setC(value);
-        return this;
-      }
-      /**
-       * <code>int32 c = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearC() {
-        copyOnWrite();
-        instance.clearC();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:proto3_unittest.ForeignMessage)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new proto3_unittest.UnittestProto3.ForeignMessage();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "c_",
-            };
-            java.lang.String info =
-                "\u0000\u0001\u0000\u0000\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u0004";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<proto3_unittest.UnittestProto3.ForeignMessage> parser = PARSER;
-          if (parser == null) {
-            synchronized (proto3_unittest.UnittestProto3.ForeignMessage.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<proto3_unittest.UnittestProto3.ForeignMessage>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:proto3_unittest.ForeignMessage)
-    private static final proto3_unittest.UnittestProto3.ForeignMessage DEFAULT_INSTANCE;
-    static {
-      ForeignMessage defaultInstance = new ForeignMessage();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        ForeignMessage.class, defaultInstance);
-    }
-
-    public static proto3_unittest.UnittestProto3.ForeignMessage getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<ForeignMessage> PARSER;
-
-    public static com.google.protobuf.Parser<ForeignMessage> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestEmptyMessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:proto3_unittest.TestEmptyMessage)
-      com.google.protobuf.MessageLiteOrBuilder {
-  }
-  /**
-   * <pre>
-   * TestEmptyMessage is used to test behavior of unknown fields.
-   * </pre>
-   *
-   * Protobuf type {@code proto3_unittest.TestEmptyMessage}
-   */
-  public  static final class TestEmptyMessage extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestEmptyMessage, TestEmptyMessage.Builder> implements
-      // @@protoc_insertion_point(message_implements:proto3_unittest.TestEmptyMessage)
-      TestEmptyMessageOrBuilder {
-    private TestEmptyMessage() {
-    }
-    public static proto3_unittest.UnittestProto3.TestEmptyMessage parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.TestEmptyMessage parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestEmptyMessage parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.TestEmptyMessage parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestEmptyMessage parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.TestEmptyMessage parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestEmptyMessage parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.TestEmptyMessage parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestEmptyMessage parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.TestEmptyMessage parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestEmptyMessage parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.TestEmptyMessage parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(proto3_unittest.UnittestProto3.TestEmptyMessage prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * TestEmptyMessage is used to test behavior of unknown fields.
-     * </pre>
-     *
-     * Protobuf type {@code proto3_unittest.TestEmptyMessage}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          proto3_unittest.UnittestProto3.TestEmptyMessage, Builder> implements
-        // @@protoc_insertion_point(builder_implements:proto3_unittest.TestEmptyMessage)
-        proto3_unittest.UnittestProto3.TestEmptyMessageOrBuilder {
-      // Construct using proto3_unittest.UnittestProto3.TestEmptyMessage.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:proto3_unittest.TestEmptyMessage)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new proto3_unittest.UnittestProto3.TestEmptyMessage();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0000\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<proto3_unittest.UnittestProto3.TestEmptyMessage> parser = PARSER;
-          if (parser == null) {
-            synchronized (proto3_unittest.UnittestProto3.TestEmptyMessage.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<proto3_unittest.UnittestProto3.TestEmptyMessage>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:proto3_unittest.TestEmptyMessage)
-    private static final proto3_unittest.UnittestProto3.TestEmptyMessage DEFAULT_INSTANCE;
-    static {
-      TestEmptyMessage defaultInstance = new TestEmptyMessage();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestEmptyMessage.class, defaultInstance);
-    }
-
-    public static proto3_unittest.UnittestProto3.TestEmptyMessage getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestEmptyMessage> PARSER;
-
-    public static com.google.protobuf.Parser<TestEmptyMessage> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestMessageWithDummyOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:proto3_unittest.TestMessageWithDummy)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <pre>
-     * This field is only here for triggering copy-on-write; it's not intended to
-     * be serialized.
-     * </pre>
-     *
-     * <code>bool dummy = 536870911;</code>
-     * @return The dummy.
-     */
-    boolean getDummy();
-  }
-  /**
-   * <pre>
-   * TestMessageWithDummy is also used to test behavior of unknown fields.
-   * </pre>
-   *
-   * Protobuf type {@code proto3_unittest.TestMessageWithDummy}
-   */
-  public  static final class TestMessageWithDummy extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestMessageWithDummy, TestMessageWithDummy.Builder> implements
-      // @@protoc_insertion_point(message_implements:proto3_unittest.TestMessageWithDummy)
-      TestMessageWithDummyOrBuilder {
-    private TestMessageWithDummy() {
-    }
-    public static final int DUMMY_FIELD_NUMBER = 536870911;
-    private boolean dummy_;
-    /**
-     * <pre>
-     * This field is only here for triggering copy-on-write; it's not intended to
-     * be serialized.
-     * </pre>
-     *
-     * <code>bool dummy = 536870911;</code>
-     * @return The dummy.
-     */
-    @java.lang.Override
-    public boolean getDummy() {
-      return dummy_;
-    }
-    /**
-     * <pre>
-     * This field is only here for triggering copy-on-write; it's not intended to
-     * be serialized.
-     * </pre>
-     *
-     * <code>bool dummy = 536870911;</code>
-     * @param value The dummy to set.
-     */
-    private void setDummy(boolean value) {
-      
-      dummy_ = value;
-    }
-    /**
-     * <pre>
-     * This field is only here for triggering copy-on-write; it's not intended to
-     * be serialized.
-     * </pre>
-     *
-     * <code>bool dummy = 536870911;</code>
-     */
-    private void clearDummy() {
-      
-      dummy_ = false;
-    }
-
-    public static proto3_unittest.UnittestProto3.TestMessageWithDummy parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.TestMessageWithDummy parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestMessageWithDummy parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.TestMessageWithDummy parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestMessageWithDummy parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.TestMessageWithDummy parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestMessageWithDummy parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.TestMessageWithDummy parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestMessageWithDummy parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.TestMessageWithDummy parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestMessageWithDummy parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.TestMessageWithDummy parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(proto3_unittest.UnittestProto3.TestMessageWithDummy prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * TestMessageWithDummy is also used to test behavior of unknown fields.
-     * </pre>
-     *
-     * Protobuf type {@code proto3_unittest.TestMessageWithDummy}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          proto3_unittest.UnittestProto3.TestMessageWithDummy, Builder> implements
-        // @@protoc_insertion_point(builder_implements:proto3_unittest.TestMessageWithDummy)
-        proto3_unittest.UnittestProto3.TestMessageWithDummyOrBuilder {
-      // Construct using proto3_unittest.UnittestProto3.TestMessageWithDummy.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <pre>
-       * This field is only here for triggering copy-on-write; it's not intended to
-       * be serialized.
-       * </pre>
-       *
-       * <code>bool dummy = 536870911;</code>
-       * @return The dummy.
-       */
-      @java.lang.Override
-      public boolean getDummy() {
-        return instance.getDummy();
-      }
-      /**
-       * <pre>
-       * This field is only here for triggering copy-on-write; it's not intended to
-       * be serialized.
-       * </pre>
-       *
-       * <code>bool dummy = 536870911;</code>
-       * @param value The dummy to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy(boolean value) {
-        copyOnWrite();
-        instance.setDummy(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * This field is only here for triggering copy-on-write; it's not intended to
-       * be serialized.
-       * </pre>
-       *
-       * <code>bool dummy = 536870911;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy() {
-        copyOnWrite();
-        instance.clearDummy();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:proto3_unittest.TestMessageWithDummy)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new proto3_unittest.UnittestProto3.TestMessageWithDummy();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "dummy_",
-            };
-            java.lang.String info =
-                "\u0000\u0001\u0000\u0000\uffff\uffff\u0007\uffff\uffff\u0007\u0001\u0000\u0000\u0000" +
-                "\uffff\uffff\u0007\u0007";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<proto3_unittest.UnittestProto3.TestMessageWithDummy> parser = PARSER;
-          if (parser == null) {
-            synchronized (proto3_unittest.UnittestProto3.TestMessageWithDummy.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<proto3_unittest.UnittestProto3.TestMessageWithDummy>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:proto3_unittest.TestMessageWithDummy)
-    private static final proto3_unittest.UnittestProto3.TestMessageWithDummy DEFAULT_INSTANCE;
-    static {
-      TestMessageWithDummy defaultInstance = new TestMessageWithDummy();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestMessageWithDummy.class, defaultInstance);
-    }
-
-    public static proto3_unittest.UnittestProto3.TestMessageWithDummy getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestMessageWithDummy> PARSER;
-
-    public static com.google.protobuf.Parser<TestMessageWithDummy> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestOneof2OrBuilder extends
-      // @@protoc_insertion_point(interface_extends:proto3_unittest.TestOneof2)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>.proto3_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-     * @return Whether the fooEnum field is set.
-     */
-    boolean hasFooEnum();
-    /**
-     * <code>.proto3_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-     * @return The enum numeric value on the wire for fooEnum.
-     */
-    int getFooEnumValue();
-    /**
-     * <code>.proto3_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-     * @return The fooEnum.
-     */
-    proto3_unittest.UnittestProto3.TestOneof2.NestedEnum getFooEnum();
-
-    public proto3_unittest.UnittestProto3.TestOneof2.FooCase getFooCase();
-  }
-  /**
-   * <pre>
-   * Same layout as TestOneof2 in unittest.proto to test unknown enum value
-   * parsing behavior in oneof.
-   * </pre>
-   *
-   * Protobuf type {@code proto3_unittest.TestOneof2}
-   */
-  public  static final class TestOneof2 extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestOneof2, TestOneof2.Builder> implements
-      // @@protoc_insertion_point(message_implements:proto3_unittest.TestOneof2)
-      TestOneof2OrBuilder {
-    private TestOneof2() {
-    }
-    /**
-     * Protobuf enum {@code proto3_unittest.TestOneof2.NestedEnum}
-     */
-    public enum NestedEnum
-        implements com.google.protobuf.Internal.EnumLite {
-      /**
-       * <code>UNKNOWN = 0;</code>
-       */
-      UNKNOWN(0),
-      /**
-       * <code>FOO = 1;</code>
-       */
-      FOO(1),
-      /**
-       * <code>BAR = 2;</code>
-       */
-      BAR(2),
-      /**
-       * <code>BAZ = 3;</code>
-       */
-      BAZ(3),
-      UNRECOGNIZED(-1),
-      ;
-
-      /**
-       * <code>UNKNOWN = 0;</code>
-       */
-      public static final int UNKNOWN_VALUE = 0;
-      /**
-       * <code>FOO = 1;</code>
-       */
-      public static final int FOO_VALUE = 1;
-      /**
-       * <code>BAR = 2;</code>
-       */
-      public static final int BAR_VALUE = 2;
-      /**
-       * <code>BAZ = 3;</code>
-       */
-      public static final int BAZ_VALUE = 3;
-
-
-      @java.lang.Override
-      public final int getNumber() {
-        if (this == UNRECOGNIZED) {
-          throw new java.lang.IllegalArgumentException(
-              "Can't get the number of an unknown enum value.");
-        }
-        return value;
-      }
-
-      /**
-       * @param value The number of the enum to look for.
-       * @return The enum associated with the given number.
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static NestedEnum valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static NestedEnum forNumber(int value) {
-        switch (value) {
-          case 0: return UNKNOWN;
-          case 1: return FOO;
-          case 2: return BAR;
-          case 3: return BAZ;
-          default: return null;
-        }
-      }
-
-      public static com.google.protobuf.Internal.EnumLiteMap<NestedEnum>
-          internalGetValueMap() {
-        return internalValueMap;
-      }
-      private static final com.google.protobuf.Internal.EnumLiteMap<
-          NestedEnum> internalValueMap =
-            new com.google.protobuf.Internal.EnumLiteMap<NestedEnum>() {
-              @java.lang.Override
-              public NestedEnum findValueByNumber(int number) {
-                return NestedEnum.forNumber(number);
-              }
-            };
-
-      public static com.google.protobuf.Internal.EnumVerifier 
-          internalGetVerifier() {
-        return NestedEnumVerifier.INSTANCE;
-      }
-
-      private static final class NestedEnumVerifier implements 
-           com.google.protobuf.Internal.EnumVerifier { 
-              static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new NestedEnumVerifier();
-              @java.lang.Override
-              public boolean isInRange(int number) {
-                return NestedEnum.forNumber(number) != null;
-              }
-            };
-
-      private final int value;
-
-      private NestedEnum(int value) {
-        this.value = value;
-      }
-
-      // @@protoc_insertion_point(enum_scope:proto3_unittest.TestOneof2.NestedEnum)
-    }
-
-    private int fooCase_ = 0;
-    private java.lang.Object foo_;
-    public enum FooCase {
-      FOO_ENUM(6),
-      FOO_NOT_SET(0);
-      private final int value;
-      private FooCase(int value) {
-        this.value = value;
-      }
-      /**
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static FooCase valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static FooCase forNumber(int value) {
-        switch (value) {
-          case 6: return FOO_ENUM;
-          case 0: return FOO_NOT_SET;
-          default: return null;
-        }
-      }
-      public int getNumber() {
-        return this.value;
-      }
-    };
-
-    @java.lang.Override
-    public FooCase
-    getFooCase() {
-      return FooCase.forNumber(
-          fooCase_);
-    }
-
-    private void clearFoo() {
-      fooCase_ = 0;
-      foo_ = null;
-    }
-
-    public static final int FOO_ENUM_FIELD_NUMBER = 6;
-    /**
-     * <code>.proto3_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-     * @return Whether the fooEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasFooEnum() {
-      return fooCase_ == 6;
-    }
-    /**
-     * <code>.proto3_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-     * @return The enum numeric value on the wire for fooEnum.
-     */
-    @java.lang.Override
-    public int getFooEnumValue() {
-      if (fooCase_ == 6) {
-        return (java.lang.Integer) foo_;
-      }
-      return 0;
-    }
-    /**
-     * <code>.proto3_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-     * @return The fooEnum.
-     */
-    @java.lang.Override
-    public proto3_unittest.UnittestProto3.TestOneof2.NestedEnum getFooEnum() {
-      if (fooCase_ == 6) {
-        proto3_unittest.UnittestProto3.TestOneof2.NestedEnum result = proto3_unittest.UnittestProto3.TestOneof2.NestedEnum.forNumber((java.lang.Integer) foo_);
-        return result == null ? proto3_unittest.UnittestProto3.TestOneof2.NestedEnum.UNRECOGNIZED : result;
-      }
-      return proto3_unittest.UnittestProto3.TestOneof2.NestedEnum.UNKNOWN;
-    }
-    /**
-     * <code>.proto3_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-     * @param value The enum numeric value on the wire for fooEnum to set.
-     */
-    private void setFooEnumValue(int value) {
-      fooCase_ = 6;
-      foo_ = value;
-    }
-    /**
-     * <code>.proto3_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-     * @param value The fooEnum to set.
-     */
-    private void setFooEnum(proto3_unittest.UnittestProto3.TestOneof2.NestedEnum value) {
-      foo_ = value.getNumber();
-      fooCase_ = 6;
-    }
-    /**
-     * <code>.proto3_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-     */
-    private void clearFooEnum() {
-      if (fooCase_ == 6) {
-        fooCase_ = 0;
-        foo_ = null;
-      }
-    }
-
-    public static proto3_unittest.UnittestProto3.TestOneof2 parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.TestOneof2 parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestOneof2 parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.TestOneof2 parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestOneof2 parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static proto3_unittest.UnittestProto3.TestOneof2 parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestOneof2 parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.TestOneof2 parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestOneof2 parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.TestOneof2 parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static proto3_unittest.UnittestProto3.TestOneof2 parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static proto3_unittest.UnittestProto3.TestOneof2 parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(proto3_unittest.UnittestProto3.TestOneof2 prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Same layout as TestOneof2 in unittest.proto to test unknown enum value
-     * parsing behavior in oneof.
-     * </pre>
-     *
-     * Protobuf type {@code proto3_unittest.TestOneof2}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          proto3_unittest.UnittestProto3.TestOneof2, Builder> implements
-        // @@protoc_insertion_point(builder_implements:proto3_unittest.TestOneof2)
-        proto3_unittest.UnittestProto3.TestOneof2OrBuilder {
-      // Construct using proto3_unittest.UnittestProto3.TestOneof2.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-      @java.lang.Override
-      public FooCase
-          getFooCase() {
-        return instance.getFooCase();
-      }
-
-      public Builder clearFoo() {
-        copyOnWrite();
-        instance.clearFoo();
-        return this;
-      }
-
-
-      /**
-       * <code>.proto3_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-       * @return Whether the fooEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasFooEnum() {
-        return instance.hasFooEnum();
-      }
-      /**
-       * <code>.proto3_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-       * @return The enum numeric value on the wire for fooEnum.
-       */
-      @java.lang.Override
-      public int getFooEnumValue() {
-        return instance.getFooEnumValue();
-      }
-      /**
-       * <code>.proto3_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-       * @param value The enum numeric value on the wire for fooEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooEnumValue(int value) {
-        copyOnWrite();
-        instance.setFooEnumValue(value);
-        return this;
-      }
-      /**
-       * <code>.proto3_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-       * @return The fooEnum.
-       */
-      @java.lang.Override
-      public proto3_unittest.UnittestProto3.TestOneof2.NestedEnum getFooEnum() {
-        return instance.getFooEnum();
-      }
-      /**
-       * <code>.proto3_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-       * @param value The fooEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooEnum(proto3_unittest.UnittestProto3.TestOneof2.NestedEnum value) {
-        copyOnWrite();
-        instance.setFooEnum(value);
-        return this;
-      }
-      /**
-       * <code>.proto3_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFooEnum() {
-        copyOnWrite();
-        instance.clearFooEnum();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:proto3_unittest.TestOneof2)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new proto3_unittest.UnittestProto3.TestOneof2();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "foo_",
-              "fooCase_",
-            };
-            java.lang.String info =
-                "\u0000\u0001\u0001\u0000\u0006\u0006\u0001\u0000\u0000\u0000\u0006?\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<proto3_unittest.UnittestProto3.TestOneof2> parser = PARSER;
-          if (parser == null) {
-            synchronized (proto3_unittest.UnittestProto3.TestOneof2.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<proto3_unittest.UnittestProto3.TestOneof2>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:proto3_unittest.TestOneof2)
-    private static final proto3_unittest.UnittestProto3.TestOneof2 DEFAULT_INSTANCE;
-    static {
-      TestOneof2 defaultInstance = new TestOneof2();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestOneof2.class, defaultInstance);
-    }
-
-    public static proto3_unittest.UnittestProto3.TestOneof2 getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestOneof2> PARSER;
-
-    public static com.google.protobuf.Parser<TestOneof2> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/UnittestProto3Kt.kt b/java/kotlin-lite/target/generated-test-sources/proto3_unittest/UnittestProto3Kt.kt
deleted file mode 100644
index e69de29..0000000
--- a/java/kotlin-lite/target/generated-test-sources/proto3_unittest/UnittestProto3Kt.kt
+++ /dev/null
diff --git a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/ForeignMessageArenaLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/ForeignMessageArenaLiteKt.kt
deleted file mode 100644
index 7ab8c0f..0000000
--- a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/ForeignMessageArenaLiteKt.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/map_lite_unittest.proto
-
-package protobuf_unittest;
-
-@kotlin.jvm.JvmSynthetic
-inline fun foreignMessageArenaLite(block: protobuf_unittest.ForeignMessageArenaLiteKt.Dsl.() -> Unit): protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite =
-  protobuf_unittest.ForeignMessageArenaLiteKt.Dsl._create(protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite.newBuilder()).apply { block() }._build()
-object ForeignMessageArenaLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite = _builder.build()
-
-    /**
-     * <code>optional int32 c = 1;</code>
-     */
-    var c: kotlin.Int
-      @JvmName("getC")
-      get() = _builder.getC()
-      @JvmName("setC")
-      set(value) {
-        _builder.setC(value)
-      }
-    /**
-     * <code>optional int32 c = 1;</code>
-     */
-    fun clearC() {
-      _builder.clearC()
-    }
-    /**
-     * <code>optional int32 c = 1;</code>
-     * @return Whether the c field is set.
-     */
-    fun hasC(): kotlin.Boolean {
-      return _builder.hasC()
-    }
-  }
-}
-inline fun protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite.copy(block: protobuf_unittest.ForeignMessageArenaLiteKt.Dsl.() -> Unit): protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite =
-  protobuf_unittest.ForeignMessageArenaLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/MapLiteUnittest.java b/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/MapLiteUnittest.java
deleted file mode 100644
index 67d470c..0000000
--- a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/MapLiteUnittest.java
+++ /dev/null
@@ -1,11524 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/map_lite_unittest.proto
-
-package protobuf_unittest;
-
-public final class MapLiteUnittest {
-  private MapLiteUnittest() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-  /**
-   * Protobuf enum {@code protobuf_unittest.Proto2MapEnumLite}
-   */
-  public enum Proto2MapEnumLite
-      implements com.google.protobuf.Internal.EnumLite {
-    /**
-     * <code>PROTO2_MAP_ENUM_FOO_LITE = 0;</code>
-     */
-    PROTO2_MAP_ENUM_FOO_LITE(0),
-    /**
-     * <code>PROTO2_MAP_ENUM_BAR_LITE = 1;</code>
-     */
-    PROTO2_MAP_ENUM_BAR_LITE(1),
-    /**
-     * <code>PROTO2_MAP_ENUM_BAZ_LITE = 2;</code>
-     */
-    PROTO2_MAP_ENUM_BAZ_LITE(2),
-    ;
-
-    /**
-     * <code>PROTO2_MAP_ENUM_FOO_LITE = 0;</code>
-     */
-    public static final int PROTO2_MAP_ENUM_FOO_LITE_VALUE = 0;
-    /**
-     * <code>PROTO2_MAP_ENUM_BAR_LITE = 1;</code>
-     */
-    public static final int PROTO2_MAP_ENUM_BAR_LITE_VALUE = 1;
-    /**
-     * <code>PROTO2_MAP_ENUM_BAZ_LITE = 2;</code>
-     */
-    public static final int PROTO2_MAP_ENUM_BAZ_LITE_VALUE = 2;
-
-
-    @java.lang.Override
-    public final int getNumber() {
-      return value;
-    }
-
-    /**
-     * @param value The number of the enum to look for.
-     * @return The enum associated with the given number.
-     * @deprecated Use {@link #forNumber(int)} instead.
-     */
-    @java.lang.Deprecated
-    public static Proto2MapEnumLite valueOf(int value) {
-      return forNumber(value);
-    }
-
-    public static Proto2MapEnumLite forNumber(int value) {
-      switch (value) {
-        case 0: return PROTO2_MAP_ENUM_FOO_LITE;
-        case 1: return PROTO2_MAP_ENUM_BAR_LITE;
-        case 2: return PROTO2_MAP_ENUM_BAZ_LITE;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<Proto2MapEnumLite>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        Proto2MapEnumLite> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<Proto2MapEnumLite>() {
-            @java.lang.Override
-            public Proto2MapEnumLite findValueByNumber(int number) {
-              return Proto2MapEnumLite.forNumber(number);
-            }
-          };
-
-    public static com.google.protobuf.Internal.EnumVerifier 
-        internalGetVerifier() {
-      return Proto2MapEnumLiteVerifier.INSTANCE;
-    }
-
-    private static final class Proto2MapEnumLiteVerifier implements 
-         com.google.protobuf.Internal.EnumVerifier { 
-            static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new Proto2MapEnumLiteVerifier();
-            @java.lang.Override
-            public boolean isInRange(int number) {
-              return Proto2MapEnumLite.forNumber(number) != null;
-            }
-          };
-
-    private final int value;
-
-    private Proto2MapEnumLite(int value) {
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:protobuf_unittest.Proto2MapEnumLite)
-  }
-
-  /**
-   * Protobuf enum {@code protobuf_unittest.Proto2MapEnumPlusExtraLite}
-   */
-  public enum Proto2MapEnumPlusExtraLite
-      implements com.google.protobuf.Internal.EnumLite {
-    /**
-     * <code>E_PROTO2_MAP_ENUM_FOO_LITE = 0;</code>
-     */
-    E_PROTO2_MAP_ENUM_FOO_LITE(0),
-    /**
-     * <code>E_PROTO2_MAP_ENUM_BAR_LITE = 1;</code>
-     */
-    E_PROTO2_MAP_ENUM_BAR_LITE(1),
-    /**
-     * <code>E_PROTO2_MAP_ENUM_BAZ_LITE = 2;</code>
-     */
-    E_PROTO2_MAP_ENUM_BAZ_LITE(2),
-    /**
-     * <code>E_PROTO2_MAP_ENUM_EXTRA_LITE = 3;</code>
-     */
-    E_PROTO2_MAP_ENUM_EXTRA_LITE(3),
-    ;
-
-    /**
-     * <code>E_PROTO2_MAP_ENUM_FOO_LITE = 0;</code>
-     */
-    public static final int E_PROTO2_MAP_ENUM_FOO_LITE_VALUE = 0;
-    /**
-     * <code>E_PROTO2_MAP_ENUM_BAR_LITE = 1;</code>
-     */
-    public static final int E_PROTO2_MAP_ENUM_BAR_LITE_VALUE = 1;
-    /**
-     * <code>E_PROTO2_MAP_ENUM_BAZ_LITE = 2;</code>
-     */
-    public static final int E_PROTO2_MAP_ENUM_BAZ_LITE_VALUE = 2;
-    /**
-     * <code>E_PROTO2_MAP_ENUM_EXTRA_LITE = 3;</code>
-     */
-    public static final int E_PROTO2_MAP_ENUM_EXTRA_LITE_VALUE = 3;
-
-
-    @java.lang.Override
-    public final int getNumber() {
-      return value;
-    }
-
-    /**
-     * @param value The number of the enum to look for.
-     * @return The enum associated with the given number.
-     * @deprecated Use {@link #forNumber(int)} instead.
-     */
-    @java.lang.Deprecated
-    public static Proto2MapEnumPlusExtraLite valueOf(int value) {
-      return forNumber(value);
-    }
-
-    public static Proto2MapEnumPlusExtraLite forNumber(int value) {
-      switch (value) {
-        case 0: return E_PROTO2_MAP_ENUM_FOO_LITE;
-        case 1: return E_PROTO2_MAP_ENUM_BAR_LITE;
-        case 2: return E_PROTO2_MAP_ENUM_BAZ_LITE;
-        case 3: return E_PROTO2_MAP_ENUM_EXTRA_LITE;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<Proto2MapEnumPlusExtraLite>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        Proto2MapEnumPlusExtraLite> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<Proto2MapEnumPlusExtraLite>() {
-            @java.lang.Override
-            public Proto2MapEnumPlusExtraLite findValueByNumber(int number) {
-              return Proto2MapEnumPlusExtraLite.forNumber(number);
-            }
-          };
-
-    public static com.google.protobuf.Internal.EnumVerifier 
-        internalGetVerifier() {
-      return Proto2MapEnumPlusExtraLiteVerifier.INSTANCE;
-    }
-
-    private static final class Proto2MapEnumPlusExtraLiteVerifier implements 
-         com.google.protobuf.Internal.EnumVerifier { 
-            static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new Proto2MapEnumPlusExtraLiteVerifier();
-            @java.lang.Override
-            public boolean isInRange(int number) {
-              return Proto2MapEnumPlusExtraLite.forNumber(number) != null;
-            }
-          };
-
-    private final int value;
-
-    private Proto2MapEnumPlusExtraLite(int value) {
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:protobuf_unittest.Proto2MapEnumPlusExtraLite)
-  }
-
-  /**
-   * Protobuf enum {@code protobuf_unittest.MapEnumLite}
-   */
-  public enum MapEnumLite
-      implements com.google.protobuf.Internal.EnumLite {
-    /**
-     * <code>MAP_ENUM_FOO_LITE = 0;</code>
-     */
-    MAP_ENUM_FOO_LITE(0),
-    /**
-     * <code>MAP_ENUM_BAR_LITE = 1;</code>
-     */
-    MAP_ENUM_BAR_LITE(1),
-    /**
-     * <code>MAP_ENUM_BAZ_LITE = 2;</code>
-     */
-    MAP_ENUM_BAZ_LITE(2),
-    ;
-
-    /**
-     * <code>MAP_ENUM_FOO_LITE = 0;</code>
-     */
-    public static final int MAP_ENUM_FOO_LITE_VALUE = 0;
-    /**
-     * <code>MAP_ENUM_BAR_LITE = 1;</code>
-     */
-    public static final int MAP_ENUM_BAR_LITE_VALUE = 1;
-    /**
-     * <code>MAP_ENUM_BAZ_LITE = 2;</code>
-     */
-    public static final int MAP_ENUM_BAZ_LITE_VALUE = 2;
-
-
-    @java.lang.Override
-    public final int getNumber() {
-      return value;
-    }
-
-    /**
-     * @param value The number of the enum to look for.
-     * @return The enum associated with the given number.
-     * @deprecated Use {@link #forNumber(int)} instead.
-     */
-    @java.lang.Deprecated
-    public static MapEnumLite valueOf(int value) {
-      return forNumber(value);
-    }
-
-    public static MapEnumLite forNumber(int value) {
-      switch (value) {
-        case 0: return MAP_ENUM_FOO_LITE;
-        case 1: return MAP_ENUM_BAR_LITE;
-        case 2: return MAP_ENUM_BAZ_LITE;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<MapEnumLite>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        MapEnumLite> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<MapEnumLite>() {
-            @java.lang.Override
-            public MapEnumLite findValueByNumber(int number) {
-              return MapEnumLite.forNumber(number);
-            }
-          };
-
-    public static com.google.protobuf.Internal.EnumVerifier 
-        internalGetVerifier() {
-      return MapEnumLiteVerifier.INSTANCE;
-    }
-
-    private static final class MapEnumLiteVerifier implements 
-         com.google.protobuf.Internal.EnumVerifier { 
-            static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new MapEnumLiteVerifier();
-            @java.lang.Override
-            public boolean isInRange(int number) {
-              return MapEnumLite.forNumber(number) != null;
-            }
-          };
-
-    private final int value;
-
-    private MapEnumLite(int value) {
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:protobuf_unittest.MapEnumLite)
-  }
-
-  public interface TestMapLiteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestMapLite)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    int getMapInt32Int32Count();
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    boolean containsMapInt32Int32(
-        int key);
-    /**
-     * Use {@link #getMapInt32Int32Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapInt32Int32();
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapInt32Int32Map();
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-
-    int getMapInt32Int32OrDefault(
-        int key,
-        int defaultValue);
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-
-    int getMapInt32Int32OrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    int getMapInt64Int64Count();
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    boolean containsMapInt64Int64(
-        long key);
-    /**
-     * Use {@link #getMapInt64Int64Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapInt64Int64();
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapInt64Int64Map();
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-
-    long getMapInt64Int64OrDefault(
-        long key,
-        long defaultValue);
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-
-    long getMapInt64Int64OrThrow(
-        long key);
-
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    int getMapUint32Uint32Count();
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    boolean containsMapUint32Uint32(
-        int key);
-    /**
-     * Use {@link #getMapUint32Uint32Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapUint32Uint32();
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapUint32Uint32Map();
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-
-    int getMapUint32Uint32OrDefault(
-        int key,
-        int defaultValue);
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-
-    int getMapUint32Uint32OrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    int getMapUint64Uint64Count();
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    boolean containsMapUint64Uint64(
-        long key);
-    /**
-     * Use {@link #getMapUint64Uint64Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapUint64Uint64();
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapUint64Uint64Map();
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-
-    long getMapUint64Uint64OrDefault(
-        long key,
-        long defaultValue);
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-
-    long getMapUint64Uint64OrThrow(
-        long key);
-
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    int getMapSint32Sint32Count();
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    boolean containsMapSint32Sint32(
-        int key);
-    /**
-     * Use {@link #getMapSint32Sint32Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapSint32Sint32();
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapSint32Sint32Map();
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-
-    int getMapSint32Sint32OrDefault(
-        int key,
-        int defaultValue);
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-
-    int getMapSint32Sint32OrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    int getMapSint64Sint64Count();
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    boolean containsMapSint64Sint64(
-        long key);
-    /**
-     * Use {@link #getMapSint64Sint64Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapSint64Sint64();
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapSint64Sint64Map();
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-
-    long getMapSint64Sint64OrDefault(
-        long key,
-        long defaultValue);
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-
-    long getMapSint64Sint64OrThrow(
-        long key);
-
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    int getMapFixed32Fixed32Count();
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    boolean containsMapFixed32Fixed32(
-        int key);
-    /**
-     * Use {@link #getMapFixed32Fixed32Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapFixed32Fixed32();
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapFixed32Fixed32Map();
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-
-    int getMapFixed32Fixed32OrDefault(
-        int key,
-        int defaultValue);
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-
-    int getMapFixed32Fixed32OrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    int getMapFixed64Fixed64Count();
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    boolean containsMapFixed64Fixed64(
-        long key);
-    /**
-     * Use {@link #getMapFixed64Fixed64Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapFixed64Fixed64();
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapFixed64Fixed64Map();
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-
-    long getMapFixed64Fixed64OrDefault(
-        long key,
-        long defaultValue);
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-
-    long getMapFixed64Fixed64OrThrow(
-        long key);
-
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    int getMapSfixed32Sfixed32Count();
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    boolean containsMapSfixed32Sfixed32(
-        int key);
-    /**
-     * Use {@link #getMapSfixed32Sfixed32Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapSfixed32Sfixed32();
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapSfixed32Sfixed32Map();
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-
-    int getMapSfixed32Sfixed32OrDefault(
-        int key,
-        int defaultValue);
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-
-    int getMapSfixed32Sfixed32OrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    int getMapSfixed64Sfixed64Count();
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    boolean containsMapSfixed64Sfixed64(
-        long key);
-    /**
-     * Use {@link #getMapSfixed64Sfixed64Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapSfixed64Sfixed64();
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapSfixed64Sfixed64Map();
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-
-    long getMapSfixed64Sfixed64OrDefault(
-        long key,
-        long defaultValue);
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-
-    long getMapSfixed64Sfixed64OrThrow(
-        long key);
-
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    int getMapInt32FloatCount();
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    boolean containsMapInt32Float(
-        int key);
-    /**
-     * Use {@link #getMapInt32FloatMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Float>
-    getMapInt32Float();
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Float>
-    getMapInt32FloatMap();
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-
-    float getMapInt32FloatOrDefault(
-        int key,
-        float defaultValue);
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-
-    float getMapInt32FloatOrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    int getMapInt32DoubleCount();
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    boolean containsMapInt32Double(
-        int key);
-    /**
-     * Use {@link #getMapInt32DoubleMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Double>
-    getMapInt32Double();
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Double>
-    getMapInt32DoubleMap();
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-
-    double getMapInt32DoubleOrDefault(
-        int key,
-        double defaultValue);
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-
-    double getMapInt32DoubleOrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    int getMapBoolBoolCount();
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    boolean containsMapBoolBool(
-        boolean key);
-    /**
-     * Use {@link #getMapBoolBoolMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Boolean, java.lang.Boolean>
-    getMapBoolBool();
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    java.util.Map<java.lang.Boolean, java.lang.Boolean>
-    getMapBoolBoolMap();
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-
-    boolean getMapBoolBoolOrDefault(
-        boolean key,
-        boolean defaultValue);
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-
-    boolean getMapBoolBoolOrThrow(
-        boolean key);
-
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    int getMapStringStringCount();
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    boolean containsMapStringString(
-        java.lang.String key);
-    /**
-     * Use {@link #getMapStringStringMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.String, java.lang.String>
-    getMapStringString();
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    java.util.Map<java.lang.String, java.lang.String>
-    getMapStringStringMap();
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-
-    java.lang.String getMapStringStringOrDefault(
-        java.lang.String key,
-        java.lang.String defaultValue);
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-
-    java.lang.String getMapStringStringOrThrow(
-        java.lang.String key);
-
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    int getMapInt32BytesCount();
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    boolean containsMapInt32Bytes(
-        int key);
-    /**
-     * Use {@link #getMapInt32BytesMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, com.google.protobuf.ByteString>
-    getMapInt32Bytes();
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    java.util.Map<java.lang.Integer, com.google.protobuf.ByteString>
-    getMapInt32BytesMap();
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-
-    com.google.protobuf.ByteString getMapInt32BytesOrDefault(
-        int key,
-        com.google.protobuf.ByteString defaultValue);
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-
-    com.google.protobuf.ByteString getMapInt32BytesOrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    int getMapInt32EnumCount();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    boolean containsMapInt32Enum(
-        int key);
-    /**
-     * Use {@link #getMapInt32EnumMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite>
-    getMapInt32Enum();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite>
-    getMapInt32EnumMap();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    protobuf_unittest.MapLiteUnittest.MapEnumLite getMapInt32EnumOrDefault(
-        int key,
-        protobuf_unittest.MapLiteUnittest.MapEnumLite defaultValue);
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    protobuf_unittest.MapLiteUnittest.MapEnumLite getMapInt32EnumOrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    int getMapInt32ForeignMessageCount();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    boolean containsMapInt32ForeignMessage(
-        int key);
-    /**
-     * Use {@link #getMapInt32ForeignMessageMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.ForeignMessageLite>
-    getMapInt32ForeignMessage();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.ForeignMessageLite>
-    getMapInt32ForeignMessageMap();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-     */
-
-    com.google.protobuf.UnittestLite.ForeignMessageLite getMapInt32ForeignMessageOrDefault(
-        int key,
-        com.google.protobuf.UnittestLite.ForeignMessageLite defaultValue);
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-     */
-
-    com.google.protobuf.UnittestLite.ForeignMessageLite getMapInt32ForeignMessageOrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-     */
-    int getTeboringCount();
-    /**
-     * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-     */
-    boolean containsTeboring(
-        int key);
-    /**
-     * Use {@link #getTeboringMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getTeboring();
-    /**
-     * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getTeboringMap();
-    /**
-     * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-     */
-
-    int getTeboringOrDefault(
-        int key,
-        int defaultValue);
-    /**
-     * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-     */
-
-    int getTeboringOrThrow(
-        int key);
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestMapLite}
-   */
-  public  static final class TestMapLite extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestMapLite, TestMapLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestMapLite)
-      TestMapLiteOrBuilder {
-    private TestMapLite() {
-    }
-    public static final int MAP_INT32_INT32_FIELD_NUMBER = 1;
-    private static final class MapInt32Int32DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> mapInt32Int32_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMapInt32Int32() {
-      return mapInt32Int32_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableMapInt32Int32() {
-      if (!mapInt32Int32_.isMutable()) {
-        mapInt32Int32_ = mapInt32Int32_.mutableCopy();
-      }
-      return mapInt32Int32_;
-    }
-    @java.lang.Override
-
-    public int getMapInt32Int32Count() {
-      return internalGetMapInt32Int32().size();
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapInt32Int32(
-        int key) {
-      
-      return internalGetMapInt32Int32().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapInt32Int32Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapInt32Int32() {
-      return getMapInt32Int32Map();
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapInt32Int32Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapInt32Int32());
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    @java.lang.Override
-
-    public int getMapInt32Int32OrDefault(
-        int key,
-        int defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapInt32Int32();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    @java.lang.Override
-
-    public int getMapInt32Int32OrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapInt32Int32();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMutableMapInt32Int32Map() {
-      return internalGetMutableMapInt32Int32();
-    }
-
-    public static final int MAP_INT64_INT64_FIELD_NUMBER = 2;
-    private static final class MapInt64Int64DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Long, java.lang.Long> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Long, java.lang.Long>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT64,
-                  0L,
-                  com.google.protobuf.WireFormat.FieldType.INT64,
-                  0L);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Long, java.lang.Long> mapInt64Int64_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMapInt64Int64() {
-      return mapInt64Int64_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMutableMapInt64Int64() {
-      if (!mapInt64Int64_.isMutable()) {
-        mapInt64Int64_ = mapInt64Int64_.mutableCopy();
-      }
-      return mapInt64Int64_;
-    }
-    @java.lang.Override
-
-    public int getMapInt64Int64Count() {
-      return internalGetMapInt64Int64().size();
-    }
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapInt64Int64(
-        long key) {
-      
-      return internalGetMapInt64Int64().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapInt64Int64Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapInt64Int64() {
-      return getMapInt64Int64Map();
-    }
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapInt64Int64Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapInt64Int64());
-    }
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    @java.lang.Override
-
-    public long getMapInt64Int64OrDefault(
-        long key,
-        long defaultValue) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapInt64Int64();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    @java.lang.Override
-
-    public long getMapInt64Int64OrThrow(
-        long key) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapInt64Int64();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    private java.util.Map<java.lang.Long, java.lang.Long>
-    getMutableMapInt64Int64Map() {
-      return internalGetMutableMapInt64Int64();
-    }
-
-    public static final int MAP_UINT32_UINT32_FIELD_NUMBER = 3;
-    private static final class MapUint32Uint32DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.UINT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.UINT32,
-                  0);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> mapUint32Uint32_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMapUint32Uint32() {
-      return mapUint32Uint32_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableMapUint32Uint32() {
-      if (!mapUint32Uint32_.isMutable()) {
-        mapUint32Uint32_ = mapUint32Uint32_.mutableCopy();
-      }
-      return mapUint32Uint32_;
-    }
-    @java.lang.Override
-
-    public int getMapUint32Uint32Count() {
-      return internalGetMapUint32Uint32().size();
-    }
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapUint32Uint32(
-        int key) {
-      
-      return internalGetMapUint32Uint32().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapUint32Uint32Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapUint32Uint32() {
-      return getMapUint32Uint32Map();
-    }
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapUint32Uint32Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapUint32Uint32());
-    }
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    @java.lang.Override
-
-    public int getMapUint32Uint32OrDefault(
-        int key,
-        int defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapUint32Uint32();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    @java.lang.Override
-
-    public int getMapUint32Uint32OrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapUint32Uint32();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMutableMapUint32Uint32Map() {
-      return internalGetMutableMapUint32Uint32();
-    }
-
-    public static final int MAP_UINT64_UINT64_FIELD_NUMBER = 4;
-    private static final class MapUint64Uint64DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Long, java.lang.Long> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Long, java.lang.Long>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.UINT64,
-                  0L,
-                  com.google.protobuf.WireFormat.FieldType.UINT64,
-                  0L);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Long, java.lang.Long> mapUint64Uint64_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMapUint64Uint64() {
-      return mapUint64Uint64_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMutableMapUint64Uint64() {
-      if (!mapUint64Uint64_.isMutable()) {
-        mapUint64Uint64_ = mapUint64Uint64_.mutableCopy();
-      }
-      return mapUint64Uint64_;
-    }
-    @java.lang.Override
-
-    public int getMapUint64Uint64Count() {
-      return internalGetMapUint64Uint64().size();
-    }
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapUint64Uint64(
-        long key) {
-      
-      return internalGetMapUint64Uint64().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapUint64Uint64Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapUint64Uint64() {
-      return getMapUint64Uint64Map();
-    }
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapUint64Uint64Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapUint64Uint64());
-    }
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    @java.lang.Override
-
-    public long getMapUint64Uint64OrDefault(
-        long key,
-        long defaultValue) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapUint64Uint64();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    @java.lang.Override
-
-    public long getMapUint64Uint64OrThrow(
-        long key) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapUint64Uint64();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    private java.util.Map<java.lang.Long, java.lang.Long>
-    getMutableMapUint64Uint64Map() {
-      return internalGetMutableMapUint64Uint64();
-    }
-
-    public static final int MAP_SINT32_SINT32_FIELD_NUMBER = 5;
-    private static final class MapSint32Sint32DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.SINT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.SINT32,
-                  0);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> mapSint32Sint32_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMapSint32Sint32() {
-      return mapSint32Sint32_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableMapSint32Sint32() {
-      if (!mapSint32Sint32_.isMutable()) {
-        mapSint32Sint32_ = mapSint32Sint32_.mutableCopy();
-      }
-      return mapSint32Sint32_;
-    }
-    @java.lang.Override
-
-    public int getMapSint32Sint32Count() {
-      return internalGetMapSint32Sint32().size();
-    }
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapSint32Sint32(
-        int key) {
-      
-      return internalGetMapSint32Sint32().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapSint32Sint32Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapSint32Sint32() {
-      return getMapSint32Sint32Map();
-    }
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapSint32Sint32Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapSint32Sint32());
-    }
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    @java.lang.Override
-
-    public int getMapSint32Sint32OrDefault(
-        int key,
-        int defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapSint32Sint32();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    @java.lang.Override
-
-    public int getMapSint32Sint32OrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapSint32Sint32();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMutableMapSint32Sint32Map() {
-      return internalGetMutableMapSint32Sint32();
-    }
-
-    public static final int MAP_SINT64_SINT64_FIELD_NUMBER = 6;
-    private static final class MapSint64Sint64DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Long, java.lang.Long> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Long, java.lang.Long>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.SINT64,
-                  0L,
-                  com.google.protobuf.WireFormat.FieldType.SINT64,
-                  0L);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Long, java.lang.Long> mapSint64Sint64_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMapSint64Sint64() {
-      return mapSint64Sint64_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMutableMapSint64Sint64() {
-      if (!mapSint64Sint64_.isMutable()) {
-        mapSint64Sint64_ = mapSint64Sint64_.mutableCopy();
-      }
-      return mapSint64Sint64_;
-    }
-    @java.lang.Override
-
-    public int getMapSint64Sint64Count() {
-      return internalGetMapSint64Sint64().size();
-    }
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapSint64Sint64(
-        long key) {
-      
-      return internalGetMapSint64Sint64().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapSint64Sint64Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapSint64Sint64() {
-      return getMapSint64Sint64Map();
-    }
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapSint64Sint64Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapSint64Sint64());
-    }
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    @java.lang.Override
-
-    public long getMapSint64Sint64OrDefault(
-        long key,
-        long defaultValue) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapSint64Sint64();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    @java.lang.Override
-
-    public long getMapSint64Sint64OrThrow(
-        long key) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapSint64Sint64();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    private java.util.Map<java.lang.Long, java.lang.Long>
-    getMutableMapSint64Sint64Map() {
-      return internalGetMutableMapSint64Sint64();
-    }
-
-    public static final int MAP_FIXED32_FIXED32_FIELD_NUMBER = 7;
-    private static final class MapFixed32Fixed32DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.FIXED32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.FIXED32,
-                  0);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> mapFixed32Fixed32_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMapFixed32Fixed32() {
-      return mapFixed32Fixed32_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableMapFixed32Fixed32() {
-      if (!mapFixed32Fixed32_.isMutable()) {
-        mapFixed32Fixed32_ = mapFixed32Fixed32_.mutableCopy();
-      }
-      return mapFixed32Fixed32_;
-    }
-    @java.lang.Override
-
-    public int getMapFixed32Fixed32Count() {
-      return internalGetMapFixed32Fixed32().size();
-    }
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapFixed32Fixed32(
-        int key) {
-      
-      return internalGetMapFixed32Fixed32().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapFixed32Fixed32Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapFixed32Fixed32() {
-      return getMapFixed32Fixed32Map();
-    }
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapFixed32Fixed32Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapFixed32Fixed32());
-    }
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    @java.lang.Override
-
-    public int getMapFixed32Fixed32OrDefault(
-        int key,
-        int defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapFixed32Fixed32();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    @java.lang.Override
-
-    public int getMapFixed32Fixed32OrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapFixed32Fixed32();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMutableMapFixed32Fixed32Map() {
-      return internalGetMutableMapFixed32Fixed32();
-    }
-
-    public static final int MAP_FIXED64_FIXED64_FIELD_NUMBER = 8;
-    private static final class MapFixed64Fixed64DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Long, java.lang.Long> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Long, java.lang.Long>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.FIXED64,
-                  0L,
-                  com.google.protobuf.WireFormat.FieldType.FIXED64,
-                  0L);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Long, java.lang.Long> mapFixed64Fixed64_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMapFixed64Fixed64() {
-      return mapFixed64Fixed64_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMutableMapFixed64Fixed64() {
-      if (!mapFixed64Fixed64_.isMutable()) {
-        mapFixed64Fixed64_ = mapFixed64Fixed64_.mutableCopy();
-      }
-      return mapFixed64Fixed64_;
-    }
-    @java.lang.Override
-
-    public int getMapFixed64Fixed64Count() {
-      return internalGetMapFixed64Fixed64().size();
-    }
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapFixed64Fixed64(
-        long key) {
-      
-      return internalGetMapFixed64Fixed64().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapFixed64Fixed64Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapFixed64Fixed64() {
-      return getMapFixed64Fixed64Map();
-    }
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapFixed64Fixed64Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapFixed64Fixed64());
-    }
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    @java.lang.Override
-
-    public long getMapFixed64Fixed64OrDefault(
-        long key,
-        long defaultValue) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapFixed64Fixed64();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    @java.lang.Override
-
-    public long getMapFixed64Fixed64OrThrow(
-        long key) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapFixed64Fixed64();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    private java.util.Map<java.lang.Long, java.lang.Long>
-    getMutableMapFixed64Fixed64Map() {
-      return internalGetMutableMapFixed64Fixed64();
-    }
-
-    public static final int MAP_SFIXED32_SFIXED32_FIELD_NUMBER = 9;
-    private static final class MapSfixed32Sfixed32DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.SFIXED32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.SFIXED32,
-                  0);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> mapSfixed32Sfixed32_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMapSfixed32Sfixed32() {
-      return mapSfixed32Sfixed32_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableMapSfixed32Sfixed32() {
-      if (!mapSfixed32Sfixed32_.isMutable()) {
-        mapSfixed32Sfixed32_ = mapSfixed32Sfixed32_.mutableCopy();
-      }
-      return mapSfixed32Sfixed32_;
-    }
-    @java.lang.Override
-
-    public int getMapSfixed32Sfixed32Count() {
-      return internalGetMapSfixed32Sfixed32().size();
-    }
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapSfixed32Sfixed32(
-        int key) {
-      
-      return internalGetMapSfixed32Sfixed32().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapSfixed32Sfixed32Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapSfixed32Sfixed32() {
-      return getMapSfixed32Sfixed32Map();
-    }
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapSfixed32Sfixed32Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapSfixed32Sfixed32());
-    }
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    @java.lang.Override
-
-    public int getMapSfixed32Sfixed32OrDefault(
-        int key,
-        int defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapSfixed32Sfixed32();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    @java.lang.Override
-
-    public int getMapSfixed32Sfixed32OrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapSfixed32Sfixed32();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMutableMapSfixed32Sfixed32Map() {
-      return internalGetMutableMapSfixed32Sfixed32();
-    }
-
-    public static final int MAP_SFIXED64_SFIXED64_FIELD_NUMBER = 10;
-    private static final class MapSfixed64Sfixed64DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Long, java.lang.Long> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Long, java.lang.Long>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.SFIXED64,
-                  0L,
-                  com.google.protobuf.WireFormat.FieldType.SFIXED64,
-                  0L);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Long, java.lang.Long> mapSfixed64Sfixed64_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMapSfixed64Sfixed64() {
-      return mapSfixed64Sfixed64_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMutableMapSfixed64Sfixed64() {
-      if (!mapSfixed64Sfixed64_.isMutable()) {
-        mapSfixed64Sfixed64_ = mapSfixed64Sfixed64_.mutableCopy();
-      }
-      return mapSfixed64Sfixed64_;
-    }
-    @java.lang.Override
-
-    public int getMapSfixed64Sfixed64Count() {
-      return internalGetMapSfixed64Sfixed64().size();
-    }
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapSfixed64Sfixed64(
-        long key) {
-      
-      return internalGetMapSfixed64Sfixed64().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapSfixed64Sfixed64Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapSfixed64Sfixed64() {
-      return getMapSfixed64Sfixed64Map();
-    }
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapSfixed64Sfixed64Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapSfixed64Sfixed64());
-    }
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    @java.lang.Override
-
-    public long getMapSfixed64Sfixed64OrDefault(
-        long key,
-        long defaultValue) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapSfixed64Sfixed64();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    @java.lang.Override
-
-    public long getMapSfixed64Sfixed64OrThrow(
-        long key) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapSfixed64Sfixed64();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    private java.util.Map<java.lang.Long, java.lang.Long>
-    getMutableMapSfixed64Sfixed64Map() {
-      return internalGetMutableMapSfixed64Sfixed64();
-    }
-
-    public static final int MAP_INT32_FLOAT_FIELD_NUMBER = 11;
-    private static final class MapInt32FloatDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Float> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Float>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.FLOAT,
-                  0F);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Float> mapInt32Float_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Float>
-    internalGetMapInt32Float() {
-      return mapInt32Float_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Float>
-    internalGetMutableMapInt32Float() {
-      if (!mapInt32Float_.isMutable()) {
-        mapInt32Float_ = mapInt32Float_.mutableCopy();
-      }
-      return mapInt32Float_;
-    }
-    @java.lang.Override
-
-    public int getMapInt32FloatCount() {
-      return internalGetMapInt32Float().size();
-    }
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapInt32Float(
-        int key) {
-      
-      return internalGetMapInt32Float().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapInt32FloatMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Float> getMapInt32Float() {
-      return getMapInt32FloatMap();
-    }
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Float> getMapInt32FloatMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapInt32Float());
-    }
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    @java.lang.Override
-
-    public float getMapInt32FloatOrDefault(
-        int key,
-        float defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Float> map =
-          internalGetMapInt32Float();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    @java.lang.Override
-
-    public float getMapInt32FloatOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Float> map =
-          internalGetMapInt32Float();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Float>
-    getMutableMapInt32FloatMap() {
-      return internalGetMutableMapInt32Float();
-    }
-
-    public static final int MAP_INT32_DOUBLE_FIELD_NUMBER = 12;
-    private static final class MapInt32DoubleDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Double> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Double>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.DOUBLE,
-                  0D);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Double> mapInt32Double_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Double>
-    internalGetMapInt32Double() {
-      return mapInt32Double_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Double>
-    internalGetMutableMapInt32Double() {
-      if (!mapInt32Double_.isMutable()) {
-        mapInt32Double_ = mapInt32Double_.mutableCopy();
-      }
-      return mapInt32Double_;
-    }
-    @java.lang.Override
-
-    public int getMapInt32DoubleCount() {
-      return internalGetMapInt32Double().size();
-    }
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapInt32Double(
-        int key) {
-      
-      return internalGetMapInt32Double().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapInt32DoubleMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Double> getMapInt32Double() {
-      return getMapInt32DoubleMap();
-    }
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Double> getMapInt32DoubleMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapInt32Double());
-    }
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    @java.lang.Override
-
-    public double getMapInt32DoubleOrDefault(
-        int key,
-        double defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Double> map =
-          internalGetMapInt32Double();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    @java.lang.Override
-
-    public double getMapInt32DoubleOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Double> map =
-          internalGetMapInt32Double();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Double>
-    getMutableMapInt32DoubleMap() {
-      return internalGetMutableMapInt32Double();
-    }
-
-    public static final int MAP_BOOL_BOOL_FIELD_NUMBER = 13;
-    private static final class MapBoolBoolDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Boolean, java.lang.Boolean> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Boolean, java.lang.Boolean>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.BOOL,
-                  false,
-                  com.google.protobuf.WireFormat.FieldType.BOOL,
-                  false);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Boolean, java.lang.Boolean> mapBoolBool_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Boolean, java.lang.Boolean>
-    internalGetMapBoolBool() {
-      return mapBoolBool_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Boolean, java.lang.Boolean>
-    internalGetMutableMapBoolBool() {
-      if (!mapBoolBool_.isMutable()) {
-        mapBoolBool_ = mapBoolBool_.mutableCopy();
-      }
-      return mapBoolBool_;
-    }
-    @java.lang.Override
-
-    public int getMapBoolBoolCount() {
-      return internalGetMapBoolBool().size();
-    }
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapBoolBool(
-        boolean key) {
-      
-      return internalGetMapBoolBool().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapBoolBoolMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Boolean, java.lang.Boolean> getMapBoolBool() {
-      return getMapBoolBoolMap();
-    }
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Boolean, java.lang.Boolean> getMapBoolBoolMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapBoolBool());
-    }
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    @java.lang.Override
-
-    public boolean getMapBoolBoolOrDefault(
-        boolean key,
-        boolean defaultValue) {
-      
-      java.util.Map<java.lang.Boolean, java.lang.Boolean> map =
-          internalGetMapBoolBool();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    @java.lang.Override
-
-    public boolean getMapBoolBoolOrThrow(
-        boolean key) {
-      
-      java.util.Map<java.lang.Boolean, java.lang.Boolean> map =
-          internalGetMapBoolBool();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    private java.util.Map<java.lang.Boolean, java.lang.Boolean>
-    getMutableMapBoolBoolMap() {
-      return internalGetMutableMapBoolBool();
-    }
-
-    public static final int MAP_STRING_STRING_FIELD_NUMBER = 14;
-    private static final class MapStringStringDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.String, java.lang.String> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.String, java.lang.String>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.STRING,
-                  "",
-                  com.google.protobuf.WireFormat.FieldType.STRING,
-                  "");
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.String, java.lang.String> mapStringString_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.String, java.lang.String>
-    internalGetMapStringString() {
-      return mapStringString_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.String, java.lang.String>
-    internalGetMutableMapStringString() {
-      if (!mapStringString_.isMutable()) {
-        mapStringString_ = mapStringString_.mutableCopy();
-      }
-      return mapStringString_;
-    }
-    @java.lang.Override
-
-    public int getMapStringStringCount() {
-      return internalGetMapStringString().size();
-    }
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapStringString(
-        java.lang.String key) {
-      key.getClass();
-      return internalGetMapStringString().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapStringStringMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.String, java.lang.String> getMapStringString() {
-      return getMapStringStringMap();
-    }
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.String, java.lang.String> getMapStringStringMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapStringString());
-    }
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    @java.lang.Override
-
-    public java.lang.String getMapStringStringOrDefault(
-        java.lang.String key,
-        java.lang.String defaultValue) {
-      key.getClass();
-      java.util.Map<java.lang.String, java.lang.String> map =
-          internalGetMapStringString();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    @java.lang.Override
-
-    public java.lang.String getMapStringStringOrThrow(
-        java.lang.String key) {
-      key.getClass();
-      java.util.Map<java.lang.String, java.lang.String> map =
-          internalGetMapStringString();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    private java.util.Map<java.lang.String, java.lang.String>
-    getMutableMapStringStringMap() {
-      return internalGetMutableMapStringString();
-    }
-
-    public static final int MAP_INT32_BYTES_FIELD_NUMBER = 15;
-    private static final class MapInt32BytesDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, com.google.protobuf.ByteString> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, com.google.protobuf.ByteString>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.BYTES,
-                  com.google.protobuf.ByteString.EMPTY);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, com.google.protobuf.ByteString> mapInt32Bytes_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, com.google.protobuf.ByteString>
-    internalGetMapInt32Bytes() {
-      return mapInt32Bytes_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, com.google.protobuf.ByteString>
-    internalGetMutableMapInt32Bytes() {
-      if (!mapInt32Bytes_.isMutable()) {
-        mapInt32Bytes_ = mapInt32Bytes_.mutableCopy();
-      }
-      return mapInt32Bytes_;
-    }
-    @java.lang.Override
-
-    public int getMapInt32BytesCount() {
-      return internalGetMapInt32Bytes().size();
-    }
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapInt32Bytes(
-        int key) {
-      
-      return internalGetMapInt32Bytes().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapInt32BytesMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, com.google.protobuf.ByteString> getMapInt32Bytes() {
-      return getMapInt32BytesMap();
-    }
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, com.google.protobuf.ByteString> getMapInt32BytesMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapInt32Bytes());
-    }
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    @java.lang.Override
-
-    public com.google.protobuf.ByteString getMapInt32BytesOrDefault(
-        int key,
-        com.google.protobuf.ByteString defaultValue) {
-      
-      java.util.Map<java.lang.Integer, com.google.protobuf.ByteString> map =
-          internalGetMapInt32Bytes();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    @java.lang.Override
-
-    public com.google.protobuf.ByteString getMapInt32BytesOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, com.google.protobuf.ByteString> map =
-          internalGetMapInt32Bytes();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    private java.util.Map<java.lang.Integer, com.google.protobuf.ByteString>
-    getMutableMapInt32BytesMap() {
-      return internalGetMutableMapInt32Bytes();
-    }
-
-    public static final int MAP_INT32_ENUM_FIELD_NUMBER = 16;
-    private static final class MapInt32EnumDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.ENUM,
-                  protobuf_unittest.MapLiteUnittest.MapEnumLite.MAP_ENUM_FOO_LITE.getNumber());
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> mapInt32Enum_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMapInt32Enum() {
-      return mapInt32Enum_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableMapInt32Enum() {
-      if (!mapInt32Enum_.isMutable()) {
-        mapInt32Enum_ = mapInt32Enum_.mutableCopy();
-      }
-      return mapInt32Enum_;
-    }
-    @java.lang.Override
-
-    public int getMapInt32EnumCount() {
-      return internalGetMapInt32Enum().size();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapInt32Enum(
-        int key) {
-      
-      return internalGetMapInt32Enum().containsKey(key);
-    }
-    private static final
-    com.google.protobuf.Internal.MapAdapter.Converter<
-        java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite> mapInt32EnumValueConverter =
-            com.google.protobuf.Internal.MapAdapter.newEnumConverter(
-                protobuf_unittest.MapLiteUnittest.MapEnumLite.internalGetValueMap(),
-                protobuf_unittest.MapLiteUnittest.MapEnumLite.MAP_ENUM_FOO_LITE);
-    /**
-     * Use {@link #getMapInt32EnumMap()} instead.
-     */
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite>
-    getMapInt32Enum() {
-      return getMapInt32EnumMap();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite>
-    getMapInt32EnumMap() {
-      return java.util.Collections.unmodifiableMap(
-          new com.google.protobuf.Internal.MapAdapter<
-            java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite, java.lang.Integer>(
-                internalGetMapInt32Enum(),
-                mapInt32EnumValueConverter));
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    @java.lang.Override
-
-    public protobuf_unittest.MapLiteUnittest.MapEnumLite getMapInt32EnumOrDefault(
-        int key,
-        protobuf_unittest.MapLiteUnittest.MapEnumLite defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapInt32Enum();
-      return map.containsKey(key)
-             ? mapInt32EnumValueConverter.doForward(map.get(key))
-             : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    @java.lang.Override
-
-    public protobuf_unittest.MapLiteUnittest.MapEnumLite getMapInt32EnumOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapInt32Enum();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return mapInt32EnumValueConverter.doForward(map.get(key));
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    private java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite>
-    getMutableMapInt32EnumMap() {
-      return new com.google.protobuf.Internal.MapAdapter<
-          java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite, java.lang.Integer>(
-              internalGetMutableMapInt32Enum(),
-              mapInt32EnumValueConverter);
-    }
-
-    public static final int MAP_INT32_FOREIGN_MESSAGE_FIELD_NUMBER = 17;
-    private static final class MapInt32ForeignMessageDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, com.google.protobuf.UnittestLite.ForeignMessageLite> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, com.google.protobuf.UnittestLite.ForeignMessageLite>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.MESSAGE,
-                  com.google.protobuf.UnittestLite.ForeignMessageLite.getDefaultInstance());
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, com.google.protobuf.UnittestLite.ForeignMessageLite> mapInt32ForeignMessage_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, com.google.protobuf.UnittestLite.ForeignMessageLite>
-    internalGetMapInt32ForeignMessage() {
-      return mapInt32ForeignMessage_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, com.google.protobuf.UnittestLite.ForeignMessageLite>
-    internalGetMutableMapInt32ForeignMessage() {
-      if (!mapInt32ForeignMessage_.isMutable()) {
-        mapInt32ForeignMessage_ = mapInt32ForeignMessage_.mutableCopy();
-      }
-      return mapInt32ForeignMessage_;
-    }
-    @java.lang.Override
-
-    public int getMapInt32ForeignMessageCount() {
-      return internalGetMapInt32ForeignMessage().size();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapInt32ForeignMessage(
-        int key) {
-      
-      return internalGetMapInt32ForeignMessage().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapInt32ForeignMessageMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.ForeignMessageLite> getMapInt32ForeignMessage() {
-      return getMapInt32ForeignMessageMap();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.ForeignMessageLite> getMapInt32ForeignMessageMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapInt32ForeignMessage());
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    @java.lang.Override
-
-    public com.google.protobuf.UnittestLite.ForeignMessageLite getMapInt32ForeignMessageOrDefault(
-        int key,
-        com.google.protobuf.UnittestLite.ForeignMessageLite defaultValue) {
-      
-      java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.ForeignMessageLite> map =
-          internalGetMapInt32ForeignMessage();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    @java.lang.Override
-
-    public com.google.protobuf.UnittestLite.ForeignMessageLite getMapInt32ForeignMessageOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.ForeignMessageLite> map =
-          internalGetMapInt32ForeignMessage();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    private java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.ForeignMessageLite>
-    getMutableMapInt32ForeignMessageMap() {
-      return internalGetMutableMapInt32ForeignMessage();
-    }
-
-    public static final int TEBORING_FIELD_NUMBER = 18;
-    private static final class TeboringDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> teboring_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetTeboring() {
-      return teboring_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableTeboring() {
-      if (!teboring_.isMutable()) {
-        teboring_ = teboring_.mutableCopy();
-      }
-      return teboring_;
-    }
-    @java.lang.Override
-
-    public int getTeboringCount() {
-      return internalGetTeboring().size();
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsTeboring(
-        int key) {
-      
-      return internalGetTeboring().containsKey(key);
-    }
-    /**
-     * Use {@link #getTeboringMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getTeboring() {
-      return getTeboringMap();
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getTeboringMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetTeboring());
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-     */
-    @java.lang.Override
-
-    public int getTeboringOrDefault(
-        int key,
-        int defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetTeboring();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-     */
-    @java.lang.Override
-
-    public int getTeboringOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetTeboring();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMutableTeboringMap() {
-      return internalGetMutableTeboring();
-    }
-
-    public static protobuf_unittest.MapLiteUnittest.TestMapLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMapLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMapLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMapLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMapLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMapLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMapLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMapLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMapLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMapLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMapLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMapLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.MapLiteUnittest.TestMapLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestMapLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.MapLiteUnittest.TestMapLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestMapLite)
-        protobuf_unittest.MapLiteUnittest.TestMapLiteOrBuilder {
-      // Construct using protobuf_unittest.MapLiteUnittest.TestMapLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      @java.lang.Override
-
-      public int getMapInt32Int32Count() {
-        return instance.getMapInt32Int32Map().size();
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapInt32Int32(
-          int key) {
-        
-        return instance.getMapInt32Int32Map().containsKey(key);
-      }
-
-      public Builder clearMapInt32Int32() {
-        copyOnWrite();
-        instance.getMutableMapInt32Int32Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-       */
-
-      public Builder removeMapInt32Int32(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapInt32Int32Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapInt32Int32Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapInt32Int32() {
-        return getMapInt32Int32Map();
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapInt32Int32Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapInt32Int32Map());
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-       */
-      @java.lang.Override
-
-      public int getMapInt32Int32OrDefault(
-          int key,
-          int defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapInt32Int32Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-       */
-      @java.lang.Override
-
-      public int getMapInt32Int32OrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapInt32Int32Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-       */
-      public Builder putMapInt32Int32(
-          int key,
-          int value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapInt32Int32Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-       */
-      public Builder putAllMapInt32Int32(
-          java.util.Map<java.lang.Integer, java.lang.Integer> values) {
-        copyOnWrite();
-        instance.getMutableMapInt32Int32Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapInt64Int64Count() {
-        return instance.getMapInt64Int64Map().size();
-      }
-      /**
-       * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapInt64Int64(
-          long key) {
-        
-        return instance.getMapInt64Int64Map().containsKey(key);
-      }
-
-      public Builder clearMapInt64Int64() {
-        copyOnWrite();
-        instance.getMutableMapInt64Int64Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-       */
-
-      public Builder removeMapInt64Int64(
-          long key) {
-        
-        copyOnWrite();
-        instance.getMutableMapInt64Int64Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapInt64Int64Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapInt64Int64() {
-        return getMapInt64Int64Map();
-      }
-      /**
-       * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapInt64Int64Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapInt64Int64Map());
-      }
-      /**
-       * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-       */
-      @java.lang.Override
-
-      public long getMapInt64Int64OrDefault(
-          long key,
-          long defaultValue) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapInt64Int64Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-       */
-      @java.lang.Override
-
-      public long getMapInt64Int64OrThrow(
-          long key) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapInt64Int64Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-       */
-      public Builder putMapInt64Int64(
-          long key,
-          long value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapInt64Int64Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-       */
-      public Builder putAllMapInt64Int64(
-          java.util.Map<java.lang.Long, java.lang.Long> values) {
-        copyOnWrite();
-        instance.getMutableMapInt64Int64Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapUint32Uint32Count() {
-        return instance.getMapUint32Uint32Map().size();
-      }
-      /**
-       * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapUint32Uint32(
-          int key) {
-        
-        return instance.getMapUint32Uint32Map().containsKey(key);
-      }
-
-      public Builder clearMapUint32Uint32() {
-        copyOnWrite();
-        instance.getMutableMapUint32Uint32Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-       */
-
-      public Builder removeMapUint32Uint32(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapUint32Uint32Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapUint32Uint32Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapUint32Uint32() {
-        return getMapUint32Uint32Map();
-      }
-      /**
-       * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapUint32Uint32Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapUint32Uint32Map());
-      }
-      /**
-       * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-       */
-      @java.lang.Override
-
-      public int getMapUint32Uint32OrDefault(
-          int key,
-          int defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapUint32Uint32Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-       */
-      @java.lang.Override
-
-      public int getMapUint32Uint32OrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapUint32Uint32Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-       */
-      public Builder putMapUint32Uint32(
-          int key,
-          int value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapUint32Uint32Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-       */
-      public Builder putAllMapUint32Uint32(
-          java.util.Map<java.lang.Integer, java.lang.Integer> values) {
-        copyOnWrite();
-        instance.getMutableMapUint32Uint32Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapUint64Uint64Count() {
-        return instance.getMapUint64Uint64Map().size();
-      }
-      /**
-       * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapUint64Uint64(
-          long key) {
-        
-        return instance.getMapUint64Uint64Map().containsKey(key);
-      }
-
-      public Builder clearMapUint64Uint64() {
-        copyOnWrite();
-        instance.getMutableMapUint64Uint64Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-       */
-
-      public Builder removeMapUint64Uint64(
-          long key) {
-        
-        copyOnWrite();
-        instance.getMutableMapUint64Uint64Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapUint64Uint64Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapUint64Uint64() {
-        return getMapUint64Uint64Map();
-      }
-      /**
-       * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapUint64Uint64Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapUint64Uint64Map());
-      }
-      /**
-       * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-       */
-      @java.lang.Override
-
-      public long getMapUint64Uint64OrDefault(
-          long key,
-          long defaultValue) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapUint64Uint64Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-       */
-      @java.lang.Override
-
-      public long getMapUint64Uint64OrThrow(
-          long key) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapUint64Uint64Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-       */
-      public Builder putMapUint64Uint64(
-          long key,
-          long value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapUint64Uint64Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-       */
-      public Builder putAllMapUint64Uint64(
-          java.util.Map<java.lang.Long, java.lang.Long> values) {
-        copyOnWrite();
-        instance.getMutableMapUint64Uint64Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapSint32Sint32Count() {
-        return instance.getMapSint32Sint32Map().size();
-      }
-      /**
-       * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapSint32Sint32(
-          int key) {
-        
-        return instance.getMapSint32Sint32Map().containsKey(key);
-      }
-
-      public Builder clearMapSint32Sint32() {
-        copyOnWrite();
-        instance.getMutableMapSint32Sint32Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-       */
-
-      public Builder removeMapSint32Sint32(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapSint32Sint32Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapSint32Sint32Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapSint32Sint32() {
-        return getMapSint32Sint32Map();
-      }
-      /**
-       * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapSint32Sint32Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapSint32Sint32Map());
-      }
-      /**
-       * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-       */
-      @java.lang.Override
-
-      public int getMapSint32Sint32OrDefault(
-          int key,
-          int defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapSint32Sint32Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-       */
-      @java.lang.Override
-
-      public int getMapSint32Sint32OrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapSint32Sint32Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-       */
-      public Builder putMapSint32Sint32(
-          int key,
-          int value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapSint32Sint32Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-       */
-      public Builder putAllMapSint32Sint32(
-          java.util.Map<java.lang.Integer, java.lang.Integer> values) {
-        copyOnWrite();
-        instance.getMutableMapSint32Sint32Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapSint64Sint64Count() {
-        return instance.getMapSint64Sint64Map().size();
-      }
-      /**
-       * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapSint64Sint64(
-          long key) {
-        
-        return instance.getMapSint64Sint64Map().containsKey(key);
-      }
-
-      public Builder clearMapSint64Sint64() {
-        copyOnWrite();
-        instance.getMutableMapSint64Sint64Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-       */
-
-      public Builder removeMapSint64Sint64(
-          long key) {
-        
-        copyOnWrite();
-        instance.getMutableMapSint64Sint64Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapSint64Sint64Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapSint64Sint64() {
-        return getMapSint64Sint64Map();
-      }
-      /**
-       * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapSint64Sint64Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapSint64Sint64Map());
-      }
-      /**
-       * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-       */
-      @java.lang.Override
-
-      public long getMapSint64Sint64OrDefault(
-          long key,
-          long defaultValue) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapSint64Sint64Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-       */
-      @java.lang.Override
-
-      public long getMapSint64Sint64OrThrow(
-          long key) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapSint64Sint64Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-       */
-      public Builder putMapSint64Sint64(
-          long key,
-          long value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapSint64Sint64Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-       */
-      public Builder putAllMapSint64Sint64(
-          java.util.Map<java.lang.Long, java.lang.Long> values) {
-        copyOnWrite();
-        instance.getMutableMapSint64Sint64Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapFixed32Fixed32Count() {
-        return instance.getMapFixed32Fixed32Map().size();
-      }
-      /**
-       * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapFixed32Fixed32(
-          int key) {
-        
-        return instance.getMapFixed32Fixed32Map().containsKey(key);
-      }
-
-      public Builder clearMapFixed32Fixed32() {
-        copyOnWrite();
-        instance.getMutableMapFixed32Fixed32Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-       */
-
-      public Builder removeMapFixed32Fixed32(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapFixed32Fixed32Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapFixed32Fixed32Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapFixed32Fixed32() {
-        return getMapFixed32Fixed32Map();
-      }
-      /**
-       * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapFixed32Fixed32Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapFixed32Fixed32Map());
-      }
-      /**
-       * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-       */
-      @java.lang.Override
-
-      public int getMapFixed32Fixed32OrDefault(
-          int key,
-          int defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapFixed32Fixed32Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-       */
-      @java.lang.Override
-
-      public int getMapFixed32Fixed32OrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapFixed32Fixed32Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-       */
-      public Builder putMapFixed32Fixed32(
-          int key,
-          int value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapFixed32Fixed32Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-       */
-      public Builder putAllMapFixed32Fixed32(
-          java.util.Map<java.lang.Integer, java.lang.Integer> values) {
-        copyOnWrite();
-        instance.getMutableMapFixed32Fixed32Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapFixed64Fixed64Count() {
-        return instance.getMapFixed64Fixed64Map().size();
-      }
-      /**
-       * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapFixed64Fixed64(
-          long key) {
-        
-        return instance.getMapFixed64Fixed64Map().containsKey(key);
-      }
-
-      public Builder clearMapFixed64Fixed64() {
-        copyOnWrite();
-        instance.getMutableMapFixed64Fixed64Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-       */
-
-      public Builder removeMapFixed64Fixed64(
-          long key) {
-        
-        copyOnWrite();
-        instance.getMutableMapFixed64Fixed64Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapFixed64Fixed64Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapFixed64Fixed64() {
-        return getMapFixed64Fixed64Map();
-      }
-      /**
-       * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapFixed64Fixed64Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapFixed64Fixed64Map());
-      }
-      /**
-       * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-       */
-      @java.lang.Override
-
-      public long getMapFixed64Fixed64OrDefault(
-          long key,
-          long defaultValue) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapFixed64Fixed64Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-       */
-      @java.lang.Override
-
-      public long getMapFixed64Fixed64OrThrow(
-          long key) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapFixed64Fixed64Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-       */
-      public Builder putMapFixed64Fixed64(
-          long key,
-          long value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapFixed64Fixed64Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-       */
-      public Builder putAllMapFixed64Fixed64(
-          java.util.Map<java.lang.Long, java.lang.Long> values) {
-        copyOnWrite();
-        instance.getMutableMapFixed64Fixed64Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapSfixed32Sfixed32Count() {
-        return instance.getMapSfixed32Sfixed32Map().size();
-      }
-      /**
-       * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapSfixed32Sfixed32(
-          int key) {
-        
-        return instance.getMapSfixed32Sfixed32Map().containsKey(key);
-      }
-
-      public Builder clearMapSfixed32Sfixed32() {
-        copyOnWrite();
-        instance.getMutableMapSfixed32Sfixed32Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-       */
-
-      public Builder removeMapSfixed32Sfixed32(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapSfixed32Sfixed32Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapSfixed32Sfixed32Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapSfixed32Sfixed32() {
-        return getMapSfixed32Sfixed32Map();
-      }
-      /**
-       * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapSfixed32Sfixed32Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapSfixed32Sfixed32Map());
-      }
-      /**
-       * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-       */
-      @java.lang.Override
-
-      public int getMapSfixed32Sfixed32OrDefault(
-          int key,
-          int defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapSfixed32Sfixed32Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-       */
-      @java.lang.Override
-
-      public int getMapSfixed32Sfixed32OrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapSfixed32Sfixed32Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-       */
-      public Builder putMapSfixed32Sfixed32(
-          int key,
-          int value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapSfixed32Sfixed32Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-       */
-      public Builder putAllMapSfixed32Sfixed32(
-          java.util.Map<java.lang.Integer, java.lang.Integer> values) {
-        copyOnWrite();
-        instance.getMutableMapSfixed32Sfixed32Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapSfixed64Sfixed64Count() {
-        return instance.getMapSfixed64Sfixed64Map().size();
-      }
-      /**
-       * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapSfixed64Sfixed64(
-          long key) {
-        
-        return instance.getMapSfixed64Sfixed64Map().containsKey(key);
-      }
-
-      public Builder clearMapSfixed64Sfixed64() {
-        copyOnWrite();
-        instance.getMutableMapSfixed64Sfixed64Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-       */
-
-      public Builder removeMapSfixed64Sfixed64(
-          long key) {
-        
-        copyOnWrite();
-        instance.getMutableMapSfixed64Sfixed64Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapSfixed64Sfixed64Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapSfixed64Sfixed64() {
-        return getMapSfixed64Sfixed64Map();
-      }
-      /**
-       * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapSfixed64Sfixed64Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapSfixed64Sfixed64Map());
-      }
-      /**
-       * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-       */
-      @java.lang.Override
-
-      public long getMapSfixed64Sfixed64OrDefault(
-          long key,
-          long defaultValue) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapSfixed64Sfixed64Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-       */
-      @java.lang.Override
-
-      public long getMapSfixed64Sfixed64OrThrow(
-          long key) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapSfixed64Sfixed64Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-       */
-      public Builder putMapSfixed64Sfixed64(
-          long key,
-          long value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapSfixed64Sfixed64Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-       */
-      public Builder putAllMapSfixed64Sfixed64(
-          java.util.Map<java.lang.Long, java.lang.Long> values) {
-        copyOnWrite();
-        instance.getMutableMapSfixed64Sfixed64Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapInt32FloatCount() {
-        return instance.getMapInt32FloatMap().size();
-      }
-      /**
-       * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapInt32Float(
-          int key) {
-        
-        return instance.getMapInt32FloatMap().containsKey(key);
-      }
-
-      public Builder clearMapInt32Float() {
-        copyOnWrite();
-        instance.getMutableMapInt32FloatMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-       */
-
-      public Builder removeMapInt32Float(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapInt32FloatMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapInt32FloatMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Float> getMapInt32Float() {
-        return getMapInt32FloatMap();
-      }
-      /**
-       * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Float> getMapInt32FloatMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapInt32FloatMap());
-      }
-      /**
-       * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-       */
-      @java.lang.Override
-
-      public float getMapInt32FloatOrDefault(
-          int key,
-          float defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Float> map =
-            instance.getMapInt32FloatMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-       */
-      @java.lang.Override
-
-      public float getMapInt32FloatOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Float> map =
-            instance.getMapInt32FloatMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-       */
-      public Builder putMapInt32Float(
-          int key,
-          float value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapInt32FloatMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-       */
-      public Builder putAllMapInt32Float(
-          java.util.Map<java.lang.Integer, java.lang.Float> values) {
-        copyOnWrite();
-        instance.getMutableMapInt32FloatMap().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapInt32DoubleCount() {
-        return instance.getMapInt32DoubleMap().size();
-      }
-      /**
-       * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapInt32Double(
-          int key) {
-        
-        return instance.getMapInt32DoubleMap().containsKey(key);
-      }
-
-      public Builder clearMapInt32Double() {
-        copyOnWrite();
-        instance.getMutableMapInt32DoubleMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-       */
-
-      public Builder removeMapInt32Double(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapInt32DoubleMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapInt32DoubleMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Double> getMapInt32Double() {
-        return getMapInt32DoubleMap();
-      }
-      /**
-       * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Double> getMapInt32DoubleMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapInt32DoubleMap());
-      }
-      /**
-       * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-       */
-      @java.lang.Override
-
-      public double getMapInt32DoubleOrDefault(
-          int key,
-          double defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Double> map =
-            instance.getMapInt32DoubleMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-       */
-      @java.lang.Override
-
-      public double getMapInt32DoubleOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Double> map =
-            instance.getMapInt32DoubleMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-       */
-      public Builder putMapInt32Double(
-          int key,
-          double value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapInt32DoubleMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-       */
-      public Builder putAllMapInt32Double(
-          java.util.Map<java.lang.Integer, java.lang.Double> values) {
-        copyOnWrite();
-        instance.getMutableMapInt32DoubleMap().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapBoolBoolCount() {
-        return instance.getMapBoolBoolMap().size();
-      }
-      /**
-       * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapBoolBool(
-          boolean key) {
-        
-        return instance.getMapBoolBoolMap().containsKey(key);
-      }
-
-      public Builder clearMapBoolBool() {
-        copyOnWrite();
-        instance.getMutableMapBoolBoolMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-       */
-
-      public Builder removeMapBoolBool(
-          boolean key) {
-        
-        copyOnWrite();
-        instance.getMutableMapBoolBoolMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapBoolBoolMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Boolean, java.lang.Boolean> getMapBoolBool() {
-        return getMapBoolBoolMap();
-      }
-      /**
-       * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Boolean, java.lang.Boolean> getMapBoolBoolMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapBoolBoolMap());
-      }
-      /**
-       * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-       */
-      @java.lang.Override
-
-      public boolean getMapBoolBoolOrDefault(
-          boolean key,
-          boolean defaultValue) {
-        
-        java.util.Map<java.lang.Boolean, java.lang.Boolean> map =
-            instance.getMapBoolBoolMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-       */
-      @java.lang.Override
-
-      public boolean getMapBoolBoolOrThrow(
-          boolean key) {
-        
-        java.util.Map<java.lang.Boolean, java.lang.Boolean> map =
-            instance.getMapBoolBoolMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-       */
-      public Builder putMapBoolBool(
-          boolean key,
-          boolean value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapBoolBoolMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-       */
-      public Builder putAllMapBoolBool(
-          java.util.Map<java.lang.Boolean, java.lang.Boolean> values) {
-        copyOnWrite();
-        instance.getMutableMapBoolBoolMap().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapStringStringCount() {
-        return instance.getMapStringStringMap().size();
-      }
-      /**
-       * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapStringString(
-          java.lang.String key) {
-        key.getClass();
-        return instance.getMapStringStringMap().containsKey(key);
-      }
-
-      public Builder clearMapStringString() {
-        copyOnWrite();
-        instance.getMutableMapStringStringMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-       */
-
-      public Builder removeMapStringString(
-          java.lang.String key) {
-        key.getClass();
-        copyOnWrite();
-        instance.getMutableMapStringStringMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapStringStringMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.String, java.lang.String> getMapStringString() {
-        return getMapStringStringMap();
-      }
-      /**
-       * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.String, java.lang.String> getMapStringStringMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapStringStringMap());
-      }
-      /**
-       * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-       */
-      @java.lang.Override
-
-      public java.lang.String getMapStringStringOrDefault(
-          java.lang.String key,
-          java.lang.String defaultValue) {
-        key.getClass();
-        java.util.Map<java.lang.String, java.lang.String> map =
-            instance.getMapStringStringMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-       */
-      @java.lang.Override
-
-      public java.lang.String getMapStringStringOrThrow(
-          java.lang.String key) {
-        key.getClass();
-        java.util.Map<java.lang.String, java.lang.String> map =
-            instance.getMapStringStringMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-       */
-      public Builder putMapStringString(
-          java.lang.String key,
-          java.lang.String value) {
-        key.getClass();
-        value.getClass();
-        copyOnWrite();
-        instance.getMutableMapStringStringMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-       */
-      public Builder putAllMapStringString(
-          java.util.Map<java.lang.String, java.lang.String> values) {
-        copyOnWrite();
-        instance.getMutableMapStringStringMap().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapInt32BytesCount() {
-        return instance.getMapInt32BytesMap().size();
-      }
-      /**
-       * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapInt32Bytes(
-          int key) {
-        
-        return instance.getMapInt32BytesMap().containsKey(key);
-      }
-
-      public Builder clearMapInt32Bytes() {
-        copyOnWrite();
-        instance.getMutableMapInt32BytesMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-       */
-
-      public Builder removeMapInt32Bytes(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapInt32BytesMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapInt32BytesMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, com.google.protobuf.ByteString> getMapInt32Bytes() {
-        return getMapInt32BytesMap();
-      }
-      /**
-       * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, com.google.protobuf.ByteString> getMapInt32BytesMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapInt32BytesMap());
-      }
-      /**
-       * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-       */
-      @java.lang.Override
-
-      public com.google.protobuf.ByteString getMapInt32BytesOrDefault(
-          int key,
-          com.google.protobuf.ByteString defaultValue) {
-        
-        java.util.Map<java.lang.Integer, com.google.protobuf.ByteString> map =
-            instance.getMapInt32BytesMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-       */
-      @java.lang.Override
-
-      public com.google.protobuf.ByteString getMapInt32BytesOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, com.google.protobuf.ByteString> map =
-            instance.getMapInt32BytesMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-       */
-      public Builder putMapInt32Bytes(
-          int key,
-          com.google.protobuf.ByteString value) {
-        
-        value.getClass();
-        copyOnWrite();
-        instance.getMutableMapInt32BytesMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-       */
-      public Builder putAllMapInt32Bytes(
-          java.util.Map<java.lang.Integer, com.google.protobuf.ByteString> values) {
-        copyOnWrite();
-        instance.getMutableMapInt32BytesMap().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapInt32EnumCount() {
-        return instance.getMapInt32EnumMap().size();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapInt32Enum(
-          int key) {
-        
-        return instance.getMapInt32EnumMap().containsKey(key);
-      }
-
-      public Builder clearMapInt32Enum() {
-        copyOnWrite();
-        instance.getMutableMapInt32EnumMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-       */
-
-      public Builder removeMapInt32Enum(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapInt32EnumMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapInt32EnumMap()} instead.
-       */
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite>
-      getMapInt32Enum() {
-        return getMapInt32EnumMap();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-       */
-      @java.lang.Override
-
-      public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite>
-      getMapInt32EnumMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapInt32EnumMap());
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-       */
-      @java.lang.Override
-
-      public protobuf_unittest.MapLiteUnittest.MapEnumLite getMapInt32EnumOrDefault(
-          int key,
-          protobuf_unittest.MapLiteUnittest.MapEnumLite defaultValue) {
-        
-        java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite> map =
-            instance.getMapInt32EnumMap();
-        return map.containsKey(key)
-               ? map.get(key)
-               : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-       */
-      @java.lang.Override
-
-      public protobuf_unittest.MapLiteUnittest.MapEnumLite getMapInt32EnumOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite> map =
-            instance.getMapInt32EnumMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-       */
-      public Builder putMapInt32Enum(
-          int key,
-          protobuf_unittest.MapLiteUnittest.MapEnumLite value) {
-        
-        value.getClass();
-        copyOnWrite();
-        instance.getMutableMapInt32EnumMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-       */
-      public Builder putAllMapInt32Enum(
-          java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite> values) {
-        copyOnWrite();
-        instance.getMutableMapInt32EnumMap().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapInt32ForeignMessageCount() {
-        return instance.getMapInt32ForeignMessageMap().size();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapInt32ForeignMessage(
-          int key) {
-        
-        return instance.getMapInt32ForeignMessageMap().containsKey(key);
-      }
-
-      public Builder clearMapInt32ForeignMessage() {
-        copyOnWrite();
-        instance.getMutableMapInt32ForeignMessageMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-       */
-
-      public Builder removeMapInt32ForeignMessage(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapInt32ForeignMessageMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapInt32ForeignMessageMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.ForeignMessageLite> getMapInt32ForeignMessage() {
-        return getMapInt32ForeignMessageMap();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.ForeignMessageLite> getMapInt32ForeignMessageMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapInt32ForeignMessageMap());
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-       */
-      @java.lang.Override
-
-      public com.google.protobuf.UnittestLite.ForeignMessageLite getMapInt32ForeignMessageOrDefault(
-          int key,
-          com.google.protobuf.UnittestLite.ForeignMessageLite defaultValue) {
-        
-        java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.ForeignMessageLite> map =
-            instance.getMapInt32ForeignMessageMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-       */
-      @java.lang.Override
-
-      public com.google.protobuf.UnittestLite.ForeignMessageLite getMapInt32ForeignMessageOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.ForeignMessageLite> map =
-            instance.getMapInt32ForeignMessageMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-       */
-      public Builder putMapInt32ForeignMessage(
-          int key,
-          com.google.protobuf.UnittestLite.ForeignMessageLite value) {
-        
-        value.getClass();
-        copyOnWrite();
-        instance.getMutableMapInt32ForeignMessageMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-       */
-      public Builder putAllMapInt32ForeignMessage(
-          java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.ForeignMessageLite> values) {
-        copyOnWrite();
-        instance.getMutableMapInt32ForeignMessageMap().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getTeboringCount() {
-        return instance.getTeboringMap().size();
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsTeboring(
-          int key) {
-        
-        return instance.getTeboringMap().containsKey(key);
-      }
-
-      public Builder clearTeboring() {
-        copyOnWrite();
-        instance.getMutableTeboringMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-       */
-
-      public Builder removeTeboring(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableTeboringMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getTeboringMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getTeboring() {
-        return getTeboringMap();
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getTeboringMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getTeboringMap());
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-       */
-      @java.lang.Override
-
-      public int getTeboringOrDefault(
-          int key,
-          int defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getTeboringMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-       */
-      @java.lang.Override
-
-      public int getTeboringOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getTeboringMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-       */
-      public Builder putTeboring(
-          int key,
-          int value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableTeboringMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-       */
-      public Builder putAllTeboring(
-          java.util.Map<java.lang.Integer, java.lang.Integer> values) {
-        copyOnWrite();
-        instance.getMutableTeboringMap().putAll(values);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestMapLite)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.MapLiteUnittest.TestMapLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "mapInt32Int32_",
-              MapInt32Int32DefaultEntryHolder.defaultEntry,
-              "mapInt64Int64_",
-              MapInt64Int64DefaultEntryHolder.defaultEntry,
-              "mapUint32Uint32_",
-              MapUint32Uint32DefaultEntryHolder.defaultEntry,
-              "mapUint64Uint64_",
-              MapUint64Uint64DefaultEntryHolder.defaultEntry,
-              "mapSint32Sint32_",
-              MapSint32Sint32DefaultEntryHolder.defaultEntry,
-              "mapSint64Sint64_",
-              MapSint64Sint64DefaultEntryHolder.defaultEntry,
-              "mapFixed32Fixed32_",
-              MapFixed32Fixed32DefaultEntryHolder.defaultEntry,
-              "mapFixed64Fixed64_",
-              MapFixed64Fixed64DefaultEntryHolder.defaultEntry,
-              "mapSfixed32Sfixed32_",
-              MapSfixed32Sfixed32DefaultEntryHolder.defaultEntry,
-              "mapSfixed64Sfixed64_",
-              MapSfixed64Sfixed64DefaultEntryHolder.defaultEntry,
-              "mapInt32Float_",
-              MapInt32FloatDefaultEntryHolder.defaultEntry,
-              "mapInt32Double_",
-              MapInt32DoubleDefaultEntryHolder.defaultEntry,
-              "mapBoolBool_",
-              MapBoolBoolDefaultEntryHolder.defaultEntry,
-              "mapStringString_",
-              MapStringStringDefaultEntryHolder.defaultEntry,
-              "mapInt32Bytes_",
-              MapInt32BytesDefaultEntryHolder.defaultEntry,
-              "mapInt32Enum_",
-              MapInt32EnumDefaultEntryHolder.defaultEntry,
-              protobuf_unittest.MapLiteUnittest.MapEnumLite.internalGetVerifier(),
-              "mapInt32ForeignMessage_",
-              MapInt32ForeignMessageDefaultEntryHolder.defaultEntry,
-              "teboring_",
-              TeboringDefaultEntryHolder.defaultEntry,
-            };
-            java.lang.String info =
-                "\u0001\u0012\u0000\u0000\u0001\u0012\u0012\u0012\u0000\u0000\u00012\u00022\u0003" +
-                "2\u00042\u00052\u00062\u00072\b2\t2\n2\u000b2\f2\r2\u000e2\u000f2\u0010\u0832\u0011" +
-                "2\u00122";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.MapLiteUnittest.TestMapLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.MapLiteUnittest.TestMapLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.MapLiteUnittest.TestMapLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestMapLite)
-    private static final protobuf_unittest.MapLiteUnittest.TestMapLite DEFAULT_INSTANCE;
-    static {
-      TestMapLite defaultInstance = new TestMapLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestMapLite.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.MapLiteUnittest.TestMapLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestMapLite> PARSER;
-
-    public static com.google.protobuf.Parser<TestMapLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestArenaMapLiteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestArenaMapLite)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    int getMapInt32Int32Count();
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    boolean containsMapInt32Int32(
-        int key);
-    /**
-     * Use {@link #getMapInt32Int32Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapInt32Int32();
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapInt32Int32Map();
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-
-    int getMapInt32Int32OrDefault(
-        int key,
-        int defaultValue);
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-
-    int getMapInt32Int32OrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    int getMapInt64Int64Count();
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    boolean containsMapInt64Int64(
-        long key);
-    /**
-     * Use {@link #getMapInt64Int64Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapInt64Int64();
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapInt64Int64Map();
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-
-    long getMapInt64Int64OrDefault(
-        long key,
-        long defaultValue);
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-
-    long getMapInt64Int64OrThrow(
-        long key);
-
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    int getMapUint32Uint32Count();
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    boolean containsMapUint32Uint32(
-        int key);
-    /**
-     * Use {@link #getMapUint32Uint32Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapUint32Uint32();
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapUint32Uint32Map();
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-
-    int getMapUint32Uint32OrDefault(
-        int key,
-        int defaultValue);
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-
-    int getMapUint32Uint32OrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    int getMapUint64Uint64Count();
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    boolean containsMapUint64Uint64(
-        long key);
-    /**
-     * Use {@link #getMapUint64Uint64Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapUint64Uint64();
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapUint64Uint64Map();
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-
-    long getMapUint64Uint64OrDefault(
-        long key,
-        long defaultValue);
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-
-    long getMapUint64Uint64OrThrow(
-        long key);
-
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    int getMapSint32Sint32Count();
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    boolean containsMapSint32Sint32(
-        int key);
-    /**
-     * Use {@link #getMapSint32Sint32Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapSint32Sint32();
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapSint32Sint32Map();
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-
-    int getMapSint32Sint32OrDefault(
-        int key,
-        int defaultValue);
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-
-    int getMapSint32Sint32OrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    int getMapSint64Sint64Count();
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    boolean containsMapSint64Sint64(
-        long key);
-    /**
-     * Use {@link #getMapSint64Sint64Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapSint64Sint64();
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapSint64Sint64Map();
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-
-    long getMapSint64Sint64OrDefault(
-        long key,
-        long defaultValue);
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-
-    long getMapSint64Sint64OrThrow(
-        long key);
-
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    int getMapFixed32Fixed32Count();
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    boolean containsMapFixed32Fixed32(
-        int key);
-    /**
-     * Use {@link #getMapFixed32Fixed32Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapFixed32Fixed32();
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapFixed32Fixed32Map();
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-
-    int getMapFixed32Fixed32OrDefault(
-        int key,
-        int defaultValue);
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-
-    int getMapFixed32Fixed32OrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    int getMapFixed64Fixed64Count();
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    boolean containsMapFixed64Fixed64(
-        long key);
-    /**
-     * Use {@link #getMapFixed64Fixed64Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapFixed64Fixed64();
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapFixed64Fixed64Map();
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-
-    long getMapFixed64Fixed64OrDefault(
-        long key,
-        long defaultValue);
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-
-    long getMapFixed64Fixed64OrThrow(
-        long key);
-
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    int getMapSfixed32Sfixed32Count();
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    boolean containsMapSfixed32Sfixed32(
-        int key);
-    /**
-     * Use {@link #getMapSfixed32Sfixed32Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapSfixed32Sfixed32();
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMapSfixed32Sfixed32Map();
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-
-    int getMapSfixed32Sfixed32OrDefault(
-        int key,
-        int defaultValue);
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-
-    int getMapSfixed32Sfixed32OrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    int getMapSfixed64Sfixed64Count();
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    boolean containsMapSfixed64Sfixed64(
-        long key);
-    /**
-     * Use {@link #getMapSfixed64Sfixed64Map()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapSfixed64Sfixed64();
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    java.util.Map<java.lang.Long, java.lang.Long>
-    getMapSfixed64Sfixed64Map();
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-
-    long getMapSfixed64Sfixed64OrDefault(
-        long key,
-        long defaultValue);
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-
-    long getMapSfixed64Sfixed64OrThrow(
-        long key);
-
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    int getMapInt32FloatCount();
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    boolean containsMapInt32Float(
-        int key);
-    /**
-     * Use {@link #getMapInt32FloatMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Float>
-    getMapInt32Float();
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Float>
-    getMapInt32FloatMap();
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-
-    float getMapInt32FloatOrDefault(
-        int key,
-        float defaultValue);
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-
-    float getMapInt32FloatOrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    int getMapInt32DoubleCount();
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    boolean containsMapInt32Double(
-        int key);
-    /**
-     * Use {@link #getMapInt32DoubleMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, java.lang.Double>
-    getMapInt32Double();
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    java.util.Map<java.lang.Integer, java.lang.Double>
-    getMapInt32DoubleMap();
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-
-    double getMapInt32DoubleOrDefault(
-        int key,
-        double defaultValue);
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-
-    double getMapInt32DoubleOrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    int getMapBoolBoolCount();
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    boolean containsMapBoolBool(
-        boolean key);
-    /**
-     * Use {@link #getMapBoolBoolMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Boolean, java.lang.Boolean>
-    getMapBoolBool();
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    java.util.Map<java.lang.Boolean, java.lang.Boolean>
-    getMapBoolBoolMap();
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-
-    boolean getMapBoolBoolOrDefault(
-        boolean key,
-        boolean defaultValue);
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-
-    boolean getMapBoolBoolOrThrow(
-        boolean key);
-
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    int getMapStringStringCount();
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    boolean containsMapStringString(
-        java.lang.String key);
-    /**
-     * Use {@link #getMapStringStringMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.String, java.lang.String>
-    getMapStringString();
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    java.util.Map<java.lang.String, java.lang.String>
-    getMapStringStringMap();
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-
-    java.lang.String getMapStringStringOrDefault(
-        java.lang.String key,
-        java.lang.String defaultValue);
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-
-    java.lang.String getMapStringStringOrThrow(
-        java.lang.String key);
-
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    int getMapInt32BytesCount();
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    boolean containsMapInt32Bytes(
-        int key);
-    /**
-     * Use {@link #getMapInt32BytesMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, com.google.protobuf.ByteString>
-    getMapInt32Bytes();
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    java.util.Map<java.lang.Integer, com.google.protobuf.ByteString>
-    getMapInt32BytesMap();
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-
-    com.google.protobuf.ByteString getMapInt32BytesOrDefault(
-        int key,
-        com.google.protobuf.ByteString defaultValue);
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-
-    com.google.protobuf.ByteString getMapInt32BytesOrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    int getMapInt32EnumCount();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    boolean containsMapInt32Enum(
-        int key);
-    /**
-     * Use {@link #getMapInt32EnumMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite>
-    getMapInt32Enum();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite>
-    getMapInt32EnumMap();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    protobuf_unittest.MapLiteUnittest.MapEnumLite getMapInt32EnumOrDefault(
-        int key,
-        protobuf_unittest.MapLiteUnittest.MapEnumLite defaultValue);
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    protobuf_unittest.MapLiteUnittest.MapEnumLite getMapInt32EnumOrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    int getMapInt32ForeignMessageCount();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    boolean containsMapInt32ForeignMessage(
-        int key);
-    /**
-     * Use {@link #getMapInt32ForeignMessageMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite>
-    getMapInt32ForeignMessage();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite>
-    getMapInt32ForeignMessageMap();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-     */
-
-    protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite getMapInt32ForeignMessageOrDefault(
-        int key,
-        protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite defaultValue);
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-     */
-
-    protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite getMapInt32ForeignMessageOrThrow(
-        int key);
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestArenaMapLite}
-   */
-  public  static final class TestArenaMapLite extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestArenaMapLite, TestArenaMapLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestArenaMapLite)
-      TestArenaMapLiteOrBuilder {
-    private TestArenaMapLite() {
-    }
-    public static final int MAP_INT32_INT32_FIELD_NUMBER = 1;
-    private static final class MapInt32Int32DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> mapInt32Int32_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMapInt32Int32() {
-      return mapInt32Int32_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableMapInt32Int32() {
-      if (!mapInt32Int32_.isMutable()) {
-        mapInt32Int32_ = mapInt32Int32_.mutableCopy();
-      }
-      return mapInt32Int32_;
-    }
-    @java.lang.Override
-
-    public int getMapInt32Int32Count() {
-      return internalGetMapInt32Int32().size();
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapInt32Int32(
-        int key) {
-      
-      return internalGetMapInt32Int32().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapInt32Int32Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapInt32Int32() {
-      return getMapInt32Int32Map();
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapInt32Int32Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapInt32Int32());
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    @java.lang.Override
-
-    public int getMapInt32Int32OrDefault(
-        int key,
-        int defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapInt32Int32();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    @java.lang.Override
-
-    public int getMapInt32Int32OrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapInt32Int32();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMutableMapInt32Int32Map() {
-      return internalGetMutableMapInt32Int32();
-    }
-
-    public static final int MAP_INT64_INT64_FIELD_NUMBER = 2;
-    private static final class MapInt64Int64DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Long, java.lang.Long> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Long, java.lang.Long>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT64,
-                  0L,
-                  com.google.protobuf.WireFormat.FieldType.INT64,
-                  0L);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Long, java.lang.Long> mapInt64Int64_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMapInt64Int64() {
-      return mapInt64Int64_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMutableMapInt64Int64() {
-      if (!mapInt64Int64_.isMutable()) {
-        mapInt64Int64_ = mapInt64Int64_.mutableCopy();
-      }
-      return mapInt64Int64_;
-    }
-    @java.lang.Override
-
-    public int getMapInt64Int64Count() {
-      return internalGetMapInt64Int64().size();
-    }
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapInt64Int64(
-        long key) {
-      
-      return internalGetMapInt64Int64().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapInt64Int64Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapInt64Int64() {
-      return getMapInt64Int64Map();
-    }
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapInt64Int64Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapInt64Int64());
-    }
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    @java.lang.Override
-
-    public long getMapInt64Int64OrDefault(
-        long key,
-        long defaultValue) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapInt64Int64();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    @java.lang.Override
-
-    public long getMapInt64Int64OrThrow(
-        long key) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapInt64Int64();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    private java.util.Map<java.lang.Long, java.lang.Long>
-    getMutableMapInt64Int64Map() {
-      return internalGetMutableMapInt64Int64();
-    }
-
-    public static final int MAP_UINT32_UINT32_FIELD_NUMBER = 3;
-    private static final class MapUint32Uint32DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.UINT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.UINT32,
-                  0);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> mapUint32Uint32_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMapUint32Uint32() {
-      return mapUint32Uint32_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableMapUint32Uint32() {
-      if (!mapUint32Uint32_.isMutable()) {
-        mapUint32Uint32_ = mapUint32Uint32_.mutableCopy();
-      }
-      return mapUint32Uint32_;
-    }
-    @java.lang.Override
-
-    public int getMapUint32Uint32Count() {
-      return internalGetMapUint32Uint32().size();
-    }
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapUint32Uint32(
-        int key) {
-      
-      return internalGetMapUint32Uint32().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapUint32Uint32Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapUint32Uint32() {
-      return getMapUint32Uint32Map();
-    }
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapUint32Uint32Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapUint32Uint32());
-    }
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    @java.lang.Override
-
-    public int getMapUint32Uint32OrDefault(
-        int key,
-        int defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapUint32Uint32();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    @java.lang.Override
-
-    public int getMapUint32Uint32OrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapUint32Uint32();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMutableMapUint32Uint32Map() {
-      return internalGetMutableMapUint32Uint32();
-    }
-
-    public static final int MAP_UINT64_UINT64_FIELD_NUMBER = 4;
-    private static final class MapUint64Uint64DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Long, java.lang.Long> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Long, java.lang.Long>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.UINT64,
-                  0L,
-                  com.google.protobuf.WireFormat.FieldType.UINT64,
-                  0L);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Long, java.lang.Long> mapUint64Uint64_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMapUint64Uint64() {
-      return mapUint64Uint64_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMutableMapUint64Uint64() {
-      if (!mapUint64Uint64_.isMutable()) {
-        mapUint64Uint64_ = mapUint64Uint64_.mutableCopy();
-      }
-      return mapUint64Uint64_;
-    }
-    @java.lang.Override
-
-    public int getMapUint64Uint64Count() {
-      return internalGetMapUint64Uint64().size();
-    }
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapUint64Uint64(
-        long key) {
-      
-      return internalGetMapUint64Uint64().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapUint64Uint64Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapUint64Uint64() {
-      return getMapUint64Uint64Map();
-    }
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapUint64Uint64Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapUint64Uint64());
-    }
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    @java.lang.Override
-
-    public long getMapUint64Uint64OrDefault(
-        long key,
-        long defaultValue) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapUint64Uint64();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    @java.lang.Override
-
-    public long getMapUint64Uint64OrThrow(
-        long key) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapUint64Uint64();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    private java.util.Map<java.lang.Long, java.lang.Long>
-    getMutableMapUint64Uint64Map() {
-      return internalGetMutableMapUint64Uint64();
-    }
-
-    public static final int MAP_SINT32_SINT32_FIELD_NUMBER = 5;
-    private static final class MapSint32Sint32DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.SINT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.SINT32,
-                  0);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> mapSint32Sint32_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMapSint32Sint32() {
-      return mapSint32Sint32_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableMapSint32Sint32() {
-      if (!mapSint32Sint32_.isMutable()) {
-        mapSint32Sint32_ = mapSint32Sint32_.mutableCopy();
-      }
-      return mapSint32Sint32_;
-    }
-    @java.lang.Override
-
-    public int getMapSint32Sint32Count() {
-      return internalGetMapSint32Sint32().size();
-    }
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapSint32Sint32(
-        int key) {
-      
-      return internalGetMapSint32Sint32().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapSint32Sint32Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapSint32Sint32() {
-      return getMapSint32Sint32Map();
-    }
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapSint32Sint32Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapSint32Sint32());
-    }
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    @java.lang.Override
-
-    public int getMapSint32Sint32OrDefault(
-        int key,
-        int defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapSint32Sint32();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    @java.lang.Override
-
-    public int getMapSint32Sint32OrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapSint32Sint32();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMutableMapSint32Sint32Map() {
-      return internalGetMutableMapSint32Sint32();
-    }
-
-    public static final int MAP_SINT64_SINT64_FIELD_NUMBER = 6;
-    private static final class MapSint64Sint64DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Long, java.lang.Long> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Long, java.lang.Long>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.SINT64,
-                  0L,
-                  com.google.protobuf.WireFormat.FieldType.SINT64,
-                  0L);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Long, java.lang.Long> mapSint64Sint64_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMapSint64Sint64() {
-      return mapSint64Sint64_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMutableMapSint64Sint64() {
-      if (!mapSint64Sint64_.isMutable()) {
-        mapSint64Sint64_ = mapSint64Sint64_.mutableCopy();
-      }
-      return mapSint64Sint64_;
-    }
-    @java.lang.Override
-
-    public int getMapSint64Sint64Count() {
-      return internalGetMapSint64Sint64().size();
-    }
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapSint64Sint64(
-        long key) {
-      
-      return internalGetMapSint64Sint64().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapSint64Sint64Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapSint64Sint64() {
-      return getMapSint64Sint64Map();
-    }
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapSint64Sint64Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapSint64Sint64());
-    }
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    @java.lang.Override
-
-    public long getMapSint64Sint64OrDefault(
-        long key,
-        long defaultValue) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapSint64Sint64();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    @java.lang.Override
-
-    public long getMapSint64Sint64OrThrow(
-        long key) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapSint64Sint64();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    private java.util.Map<java.lang.Long, java.lang.Long>
-    getMutableMapSint64Sint64Map() {
-      return internalGetMutableMapSint64Sint64();
-    }
-
-    public static final int MAP_FIXED32_FIXED32_FIELD_NUMBER = 7;
-    private static final class MapFixed32Fixed32DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.FIXED32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.FIXED32,
-                  0);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> mapFixed32Fixed32_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMapFixed32Fixed32() {
-      return mapFixed32Fixed32_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableMapFixed32Fixed32() {
-      if (!mapFixed32Fixed32_.isMutable()) {
-        mapFixed32Fixed32_ = mapFixed32Fixed32_.mutableCopy();
-      }
-      return mapFixed32Fixed32_;
-    }
-    @java.lang.Override
-
-    public int getMapFixed32Fixed32Count() {
-      return internalGetMapFixed32Fixed32().size();
-    }
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapFixed32Fixed32(
-        int key) {
-      
-      return internalGetMapFixed32Fixed32().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapFixed32Fixed32Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapFixed32Fixed32() {
-      return getMapFixed32Fixed32Map();
-    }
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapFixed32Fixed32Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapFixed32Fixed32());
-    }
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    @java.lang.Override
-
-    public int getMapFixed32Fixed32OrDefault(
-        int key,
-        int defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapFixed32Fixed32();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    @java.lang.Override
-
-    public int getMapFixed32Fixed32OrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapFixed32Fixed32();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMutableMapFixed32Fixed32Map() {
-      return internalGetMutableMapFixed32Fixed32();
-    }
-
-    public static final int MAP_FIXED64_FIXED64_FIELD_NUMBER = 8;
-    private static final class MapFixed64Fixed64DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Long, java.lang.Long> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Long, java.lang.Long>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.FIXED64,
-                  0L,
-                  com.google.protobuf.WireFormat.FieldType.FIXED64,
-                  0L);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Long, java.lang.Long> mapFixed64Fixed64_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMapFixed64Fixed64() {
-      return mapFixed64Fixed64_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMutableMapFixed64Fixed64() {
-      if (!mapFixed64Fixed64_.isMutable()) {
-        mapFixed64Fixed64_ = mapFixed64Fixed64_.mutableCopy();
-      }
-      return mapFixed64Fixed64_;
-    }
-    @java.lang.Override
-
-    public int getMapFixed64Fixed64Count() {
-      return internalGetMapFixed64Fixed64().size();
-    }
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapFixed64Fixed64(
-        long key) {
-      
-      return internalGetMapFixed64Fixed64().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapFixed64Fixed64Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapFixed64Fixed64() {
-      return getMapFixed64Fixed64Map();
-    }
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapFixed64Fixed64Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapFixed64Fixed64());
-    }
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    @java.lang.Override
-
-    public long getMapFixed64Fixed64OrDefault(
-        long key,
-        long defaultValue) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapFixed64Fixed64();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    @java.lang.Override
-
-    public long getMapFixed64Fixed64OrThrow(
-        long key) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapFixed64Fixed64();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    private java.util.Map<java.lang.Long, java.lang.Long>
-    getMutableMapFixed64Fixed64Map() {
-      return internalGetMutableMapFixed64Fixed64();
-    }
-
-    public static final int MAP_SFIXED32_SFIXED32_FIELD_NUMBER = 9;
-    private static final class MapSfixed32Sfixed32DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.SFIXED32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.SFIXED32,
-                  0);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> mapSfixed32Sfixed32_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMapSfixed32Sfixed32() {
-      return mapSfixed32Sfixed32_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableMapSfixed32Sfixed32() {
-      if (!mapSfixed32Sfixed32_.isMutable()) {
-        mapSfixed32Sfixed32_ = mapSfixed32Sfixed32_.mutableCopy();
-      }
-      return mapSfixed32Sfixed32_;
-    }
-    @java.lang.Override
-
-    public int getMapSfixed32Sfixed32Count() {
-      return internalGetMapSfixed32Sfixed32().size();
-    }
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapSfixed32Sfixed32(
-        int key) {
-      
-      return internalGetMapSfixed32Sfixed32().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapSfixed32Sfixed32Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapSfixed32Sfixed32() {
-      return getMapSfixed32Sfixed32Map();
-    }
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Integer> getMapSfixed32Sfixed32Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapSfixed32Sfixed32());
-    }
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    @java.lang.Override
-
-    public int getMapSfixed32Sfixed32OrDefault(
-        int key,
-        int defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapSfixed32Sfixed32();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    @java.lang.Override
-
-    public int getMapSfixed32Sfixed32OrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapSfixed32Sfixed32();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Integer>
-    getMutableMapSfixed32Sfixed32Map() {
-      return internalGetMutableMapSfixed32Sfixed32();
-    }
-
-    public static final int MAP_SFIXED64_SFIXED64_FIELD_NUMBER = 10;
-    private static final class MapSfixed64Sfixed64DefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Long, java.lang.Long> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Long, java.lang.Long>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.SFIXED64,
-                  0L,
-                  com.google.protobuf.WireFormat.FieldType.SFIXED64,
-                  0L);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Long, java.lang.Long> mapSfixed64Sfixed64_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMapSfixed64Sfixed64() {
-      return mapSfixed64Sfixed64_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Long, java.lang.Long>
-    internalGetMutableMapSfixed64Sfixed64() {
-      if (!mapSfixed64Sfixed64_.isMutable()) {
-        mapSfixed64Sfixed64_ = mapSfixed64Sfixed64_.mutableCopy();
-      }
-      return mapSfixed64Sfixed64_;
-    }
-    @java.lang.Override
-
-    public int getMapSfixed64Sfixed64Count() {
-      return internalGetMapSfixed64Sfixed64().size();
-    }
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapSfixed64Sfixed64(
-        long key) {
-      
-      return internalGetMapSfixed64Sfixed64().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapSfixed64Sfixed64Map()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapSfixed64Sfixed64() {
-      return getMapSfixed64Sfixed64Map();
-    }
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Long, java.lang.Long> getMapSfixed64Sfixed64Map() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapSfixed64Sfixed64());
-    }
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    @java.lang.Override
-
-    public long getMapSfixed64Sfixed64OrDefault(
-        long key,
-        long defaultValue) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapSfixed64Sfixed64();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    @java.lang.Override
-
-    public long getMapSfixed64Sfixed64OrThrow(
-        long key) {
-      
-      java.util.Map<java.lang.Long, java.lang.Long> map =
-          internalGetMapSfixed64Sfixed64();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    private java.util.Map<java.lang.Long, java.lang.Long>
-    getMutableMapSfixed64Sfixed64Map() {
-      return internalGetMutableMapSfixed64Sfixed64();
-    }
-
-    public static final int MAP_INT32_FLOAT_FIELD_NUMBER = 11;
-    private static final class MapInt32FloatDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Float> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Float>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.FLOAT,
-                  0F);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Float> mapInt32Float_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Float>
-    internalGetMapInt32Float() {
-      return mapInt32Float_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Float>
-    internalGetMutableMapInt32Float() {
-      if (!mapInt32Float_.isMutable()) {
-        mapInt32Float_ = mapInt32Float_.mutableCopy();
-      }
-      return mapInt32Float_;
-    }
-    @java.lang.Override
-
-    public int getMapInt32FloatCount() {
-      return internalGetMapInt32Float().size();
-    }
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapInt32Float(
-        int key) {
-      
-      return internalGetMapInt32Float().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapInt32FloatMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Float> getMapInt32Float() {
-      return getMapInt32FloatMap();
-    }
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Float> getMapInt32FloatMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapInt32Float());
-    }
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    @java.lang.Override
-
-    public float getMapInt32FloatOrDefault(
-        int key,
-        float defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Float> map =
-          internalGetMapInt32Float();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    @java.lang.Override
-
-    public float getMapInt32FloatOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Float> map =
-          internalGetMapInt32Float();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Float>
-    getMutableMapInt32FloatMap() {
-      return internalGetMutableMapInt32Float();
-    }
-
-    public static final int MAP_INT32_DOUBLE_FIELD_NUMBER = 12;
-    private static final class MapInt32DoubleDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Double> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Double>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.DOUBLE,
-                  0D);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Double> mapInt32Double_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Double>
-    internalGetMapInt32Double() {
-      return mapInt32Double_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Double>
-    internalGetMutableMapInt32Double() {
-      if (!mapInt32Double_.isMutable()) {
-        mapInt32Double_ = mapInt32Double_.mutableCopy();
-      }
-      return mapInt32Double_;
-    }
-    @java.lang.Override
-
-    public int getMapInt32DoubleCount() {
-      return internalGetMapInt32Double().size();
-    }
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapInt32Double(
-        int key) {
-      
-      return internalGetMapInt32Double().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapInt32DoubleMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, java.lang.Double> getMapInt32Double() {
-      return getMapInt32DoubleMap();
-    }
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, java.lang.Double> getMapInt32DoubleMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapInt32Double());
-    }
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    @java.lang.Override
-
-    public double getMapInt32DoubleOrDefault(
-        int key,
-        double defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Double> map =
-          internalGetMapInt32Double();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    @java.lang.Override
-
-    public double getMapInt32DoubleOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Double> map =
-          internalGetMapInt32Double();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    private java.util.Map<java.lang.Integer, java.lang.Double>
-    getMutableMapInt32DoubleMap() {
-      return internalGetMutableMapInt32Double();
-    }
-
-    public static final int MAP_BOOL_BOOL_FIELD_NUMBER = 13;
-    private static final class MapBoolBoolDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Boolean, java.lang.Boolean> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Boolean, java.lang.Boolean>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.BOOL,
-                  false,
-                  com.google.protobuf.WireFormat.FieldType.BOOL,
-                  false);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Boolean, java.lang.Boolean> mapBoolBool_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Boolean, java.lang.Boolean>
-    internalGetMapBoolBool() {
-      return mapBoolBool_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Boolean, java.lang.Boolean>
-    internalGetMutableMapBoolBool() {
-      if (!mapBoolBool_.isMutable()) {
-        mapBoolBool_ = mapBoolBool_.mutableCopy();
-      }
-      return mapBoolBool_;
-    }
-    @java.lang.Override
-
-    public int getMapBoolBoolCount() {
-      return internalGetMapBoolBool().size();
-    }
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapBoolBool(
-        boolean key) {
-      
-      return internalGetMapBoolBool().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapBoolBoolMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Boolean, java.lang.Boolean> getMapBoolBool() {
-      return getMapBoolBoolMap();
-    }
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Boolean, java.lang.Boolean> getMapBoolBoolMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapBoolBool());
-    }
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    @java.lang.Override
-
-    public boolean getMapBoolBoolOrDefault(
-        boolean key,
-        boolean defaultValue) {
-      
-      java.util.Map<java.lang.Boolean, java.lang.Boolean> map =
-          internalGetMapBoolBool();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    @java.lang.Override
-
-    public boolean getMapBoolBoolOrThrow(
-        boolean key) {
-      
-      java.util.Map<java.lang.Boolean, java.lang.Boolean> map =
-          internalGetMapBoolBool();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    private java.util.Map<java.lang.Boolean, java.lang.Boolean>
-    getMutableMapBoolBoolMap() {
-      return internalGetMutableMapBoolBool();
-    }
-
-    public static final int MAP_STRING_STRING_FIELD_NUMBER = 14;
-    private static final class MapStringStringDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.String, java.lang.String> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.String, java.lang.String>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.STRING,
-                  "",
-                  com.google.protobuf.WireFormat.FieldType.STRING,
-                  "");
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.String, java.lang.String> mapStringString_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.String, java.lang.String>
-    internalGetMapStringString() {
-      return mapStringString_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.String, java.lang.String>
-    internalGetMutableMapStringString() {
-      if (!mapStringString_.isMutable()) {
-        mapStringString_ = mapStringString_.mutableCopy();
-      }
-      return mapStringString_;
-    }
-    @java.lang.Override
-
-    public int getMapStringStringCount() {
-      return internalGetMapStringString().size();
-    }
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapStringString(
-        java.lang.String key) {
-      key.getClass();
-      return internalGetMapStringString().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapStringStringMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.String, java.lang.String> getMapStringString() {
-      return getMapStringStringMap();
-    }
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.String, java.lang.String> getMapStringStringMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapStringString());
-    }
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    @java.lang.Override
-
-    public java.lang.String getMapStringStringOrDefault(
-        java.lang.String key,
-        java.lang.String defaultValue) {
-      key.getClass();
-      java.util.Map<java.lang.String, java.lang.String> map =
-          internalGetMapStringString();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    @java.lang.Override
-
-    public java.lang.String getMapStringStringOrThrow(
-        java.lang.String key) {
-      key.getClass();
-      java.util.Map<java.lang.String, java.lang.String> map =
-          internalGetMapStringString();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    private java.util.Map<java.lang.String, java.lang.String>
-    getMutableMapStringStringMap() {
-      return internalGetMutableMapStringString();
-    }
-
-    public static final int MAP_INT32_BYTES_FIELD_NUMBER = 15;
-    private static final class MapInt32BytesDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, com.google.protobuf.ByteString> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, com.google.protobuf.ByteString>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.BYTES,
-                  com.google.protobuf.ByteString.EMPTY);
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, com.google.protobuf.ByteString> mapInt32Bytes_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, com.google.protobuf.ByteString>
-    internalGetMapInt32Bytes() {
-      return mapInt32Bytes_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, com.google.protobuf.ByteString>
-    internalGetMutableMapInt32Bytes() {
-      if (!mapInt32Bytes_.isMutable()) {
-        mapInt32Bytes_ = mapInt32Bytes_.mutableCopy();
-      }
-      return mapInt32Bytes_;
-    }
-    @java.lang.Override
-
-    public int getMapInt32BytesCount() {
-      return internalGetMapInt32Bytes().size();
-    }
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapInt32Bytes(
-        int key) {
-      
-      return internalGetMapInt32Bytes().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapInt32BytesMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, com.google.protobuf.ByteString> getMapInt32Bytes() {
-      return getMapInt32BytesMap();
-    }
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, com.google.protobuf.ByteString> getMapInt32BytesMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapInt32Bytes());
-    }
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    @java.lang.Override
-
-    public com.google.protobuf.ByteString getMapInt32BytesOrDefault(
-        int key,
-        com.google.protobuf.ByteString defaultValue) {
-      
-      java.util.Map<java.lang.Integer, com.google.protobuf.ByteString> map =
-          internalGetMapInt32Bytes();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    @java.lang.Override
-
-    public com.google.protobuf.ByteString getMapInt32BytesOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, com.google.protobuf.ByteString> map =
-          internalGetMapInt32Bytes();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    private java.util.Map<java.lang.Integer, com.google.protobuf.ByteString>
-    getMutableMapInt32BytesMap() {
-      return internalGetMutableMapInt32Bytes();
-    }
-
-    public static final int MAP_INT32_ENUM_FIELD_NUMBER = 16;
-    private static final class MapInt32EnumDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.ENUM,
-                  protobuf_unittest.MapLiteUnittest.MapEnumLite.MAP_ENUM_FOO_LITE.getNumber());
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> mapInt32Enum_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMapInt32Enum() {
-      return mapInt32Enum_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableMapInt32Enum() {
-      if (!mapInt32Enum_.isMutable()) {
-        mapInt32Enum_ = mapInt32Enum_.mutableCopy();
-      }
-      return mapInt32Enum_;
-    }
-    @java.lang.Override
-
-    public int getMapInt32EnumCount() {
-      return internalGetMapInt32Enum().size();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapInt32Enum(
-        int key) {
-      
-      return internalGetMapInt32Enum().containsKey(key);
-    }
-    private static final
-    com.google.protobuf.Internal.MapAdapter.Converter<
-        java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite> mapInt32EnumValueConverter =
-            com.google.protobuf.Internal.MapAdapter.newEnumConverter(
-                protobuf_unittest.MapLiteUnittest.MapEnumLite.internalGetValueMap(),
-                protobuf_unittest.MapLiteUnittest.MapEnumLite.MAP_ENUM_FOO_LITE);
-    /**
-     * Use {@link #getMapInt32EnumMap()} instead.
-     */
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite>
-    getMapInt32Enum() {
-      return getMapInt32EnumMap();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite>
-    getMapInt32EnumMap() {
-      return java.util.Collections.unmodifiableMap(
-          new com.google.protobuf.Internal.MapAdapter<
-            java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite, java.lang.Integer>(
-                internalGetMapInt32Enum(),
-                mapInt32EnumValueConverter));
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    @java.lang.Override
-
-    public protobuf_unittest.MapLiteUnittest.MapEnumLite getMapInt32EnumOrDefault(
-        int key,
-        protobuf_unittest.MapLiteUnittest.MapEnumLite defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapInt32Enum();
-      return map.containsKey(key)
-             ? mapInt32EnumValueConverter.doForward(map.get(key))
-             : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    @java.lang.Override
-
-    public protobuf_unittest.MapLiteUnittest.MapEnumLite getMapInt32EnumOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetMapInt32Enum();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return mapInt32EnumValueConverter.doForward(map.get(key));
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    private java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite>
-    getMutableMapInt32EnumMap() {
-      return new com.google.protobuf.Internal.MapAdapter<
-          java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite, java.lang.Integer>(
-              internalGetMutableMapInt32Enum(),
-              mapInt32EnumValueConverter);
-    }
-
-    public static final int MAP_INT32_FOREIGN_MESSAGE_FIELD_NUMBER = 17;
-    private static final class MapInt32ForeignMessageDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.MESSAGE,
-                  protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite.getDefaultInstance());
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite> mapInt32ForeignMessage_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite>
-    internalGetMapInt32ForeignMessage() {
-      return mapInt32ForeignMessage_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite>
-    internalGetMutableMapInt32ForeignMessage() {
-      if (!mapInt32ForeignMessage_.isMutable()) {
-        mapInt32ForeignMessage_ = mapInt32ForeignMessage_.mutableCopy();
-      }
-      return mapInt32ForeignMessage_;
-    }
-    @java.lang.Override
-
-    public int getMapInt32ForeignMessageCount() {
-      return internalGetMapInt32ForeignMessage().size();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapInt32ForeignMessage(
-        int key) {
-      
-      return internalGetMapInt32ForeignMessage().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapInt32ForeignMessageMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite> getMapInt32ForeignMessage() {
-      return getMapInt32ForeignMessageMap();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite> getMapInt32ForeignMessageMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapInt32ForeignMessage());
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    @java.lang.Override
-
-    public protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite getMapInt32ForeignMessageOrDefault(
-        int key,
-        protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite defaultValue) {
-      
-      java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite> map =
-          internalGetMapInt32ForeignMessage();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    @java.lang.Override
-
-    public protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite getMapInt32ForeignMessageOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite> map =
-          internalGetMapInt32ForeignMessage();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    private java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite>
-    getMutableMapInt32ForeignMessageMap() {
-      return internalGetMutableMapInt32ForeignMessage();
-    }
-
-    public static protobuf_unittest.MapLiteUnittest.TestArenaMapLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestArenaMapLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestArenaMapLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestArenaMapLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestArenaMapLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestArenaMapLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestArenaMapLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestArenaMapLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestArenaMapLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestArenaMapLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestArenaMapLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestArenaMapLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.MapLiteUnittest.TestArenaMapLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestArenaMapLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.MapLiteUnittest.TestArenaMapLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestArenaMapLite)
-        protobuf_unittest.MapLiteUnittest.TestArenaMapLiteOrBuilder {
-      // Construct using protobuf_unittest.MapLiteUnittest.TestArenaMapLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      @java.lang.Override
-
-      public int getMapInt32Int32Count() {
-        return instance.getMapInt32Int32Map().size();
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapInt32Int32(
-          int key) {
-        
-        return instance.getMapInt32Int32Map().containsKey(key);
-      }
-
-      public Builder clearMapInt32Int32() {
-        copyOnWrite();
-        instance.getMutableMapInt32Int32Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-       */
-
-      public Builder removeMapInt32Int32(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapInt32Int32Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapInt32Int32Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapInt32Int32() {
-        return getMapInt32Int32Map();
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapInt32Int32Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapInt32Int32Map());
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-       */
-      @java.lang.Override
-
-      public int getMapInt32Int32OrDefault(
-          int key,
-          int defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapInt32Int32Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-       */
-      @java.lang.Override
-
-      public int getMapInt32Int32OrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapInt32Int32Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-       */
-      public Builder putMapInt32Int32(
-          int key,
-          int value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapInt32Int32Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-       */
-      public Builder putAllMapInt32Int32(
-          java.util.Map<java.lang.Integer, java.lang.Integer> values) {
-        copyOnWrite();
-        instance.getMutableMapInt32Int32Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapInt64Int64Count() {
-        return instance.getMapInt64Int64Map().size();
-      }
-      /**
-       * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapInt64Int64(
-          long key) {
-        
-        return instance.getMapInt64Int64Map().containsKey(key);
-      }
-
-      public Builder clearMapInt64Int64() {
-        copyOnWrite();
-        instance.getMutableMapInt64Int64Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-       */
-
-      public Builder removeMapInt64Int64(
-          long key) {
-        
-        copyOnWrite();
-        instance.getMutableMapInt64Int64Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapInt64Int64Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapInt64Int64() {
-        return getMapInt64Int64Map();
-      }
-      /**
-       * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapInt64Int64Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapInt64Int64Map());
-      }
-      /**
-       * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-       */
-      @java.lang.Override
-
-      public long getMapInt64Int64OrDefault(
-          long key,
-          long defaultValue) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapInt64Int64Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-       */
-      @java.lang.Override
-
-      public long getMapInt64Int64OrThrow(
-          long key) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapInt64Int64Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-       */
-      public Builder putMapInt64Int64(
-          long key,
-          long value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapInt64Int64Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-       */
-      public Builder putAllMapInt64Int64(
-          java.util.Map<java.lang.Long, java.lang.Long> values) {
-        copyOnWrite();
-        instance.getMutableMapInt64Int64Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapUint32Uint32Count() {
-        return instance.getMapUint32Uint32Map().size();
-      }
-      /**
-       * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapUint32Uint32(
-          int key) {
-        
-        return instance.getMapUint32Uint32Map().containsKey(key);
-      }
-
-      public Builder clearMapUint32Uint32() {
-        copyOnWrite();
-        instance.getMutableMapUint32Uint32Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-       */
-
-      public Builder removeMapUint32Uint32(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapUint32Uint32Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapUint32Uint32Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapUint32Uint32() {
-        return getMapUint32Uint32Map();
-      }
-      /**
-       * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapUint32Uint32Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapUint32Uint32Map());
-      }
-      /**
-       * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-       */
-      @java.lang.Override
-
-      public int getMapUint32Uint32OrDefault(
-          int key,
-          int defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapUint32Uint32Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-       */
-      @java.lang.Override
-
-      public int getMapUint32Uint32OrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapUint32Uint32Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-       */
-      public Builder putMapUint32Uint32(
-          int key,
-          int value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapUint32Uint32Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-       */
-      public Builder putAllMapUint32Uint32(
-          java.util.Map<java.lang.Integer, java.lang.Integer> values) {
-        copyOnWrite();
-        instance.getMutableMapUint32Uint32Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapUint64Uint64Count() {
-        return instance.getMapUint64Uint64Map().size();
-      }
-      /**
-       * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapUint64Uint64(
-          long key) {
-        
-        return instance.getMapUint64Uint64Map().containsKey(key);
-      }
-
-      public Builder clearMapUint64Uint64() {
-        copyOnWrite();
-        instance.getMutableMapUint64Uint64Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-       */
-
-      public Builder removeMapUint64Uint64(
-          long key) {
-        
-        copyOnWrite();
-        instance.getMutableMapUint64Uint64Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapUint64Uint64Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapUint64Uint64() {
-        return getMapUint64Uint64Map();
-      }
-      /**
-       * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapUint64Uint64Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapUint64Uint64Map());
-      }
-      /**
-       * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-       */
-      @java.lang.Override
-
-      public long getMapUint64Uint64OrDefault(
-          long key,
-          long defaultValue) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapUint64Uint64Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-       */
-      @java.lang.Override
-
-      public long getMapUint64Uint64OrThrow(
-          long key) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapUint64Uint64Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-       */
-      public Builder putMapUint64Uint64(
-          long key,
-          long value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapUint64Uint64Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-       */
-      public Builder putAllMapUint64Uint64(
-          java.util.Map<java.lang.Long, java.lang.Long> values) {
-        copyOnWrite();
-        instance.getMutableMapUint64Uint64Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapSint32Sint32Count() {
-        return instance.getMapSint32Sint32Map().size();
-      }
-      /**
-       * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapSint32Sint32(
-          int key) {
-        
-        return instance.getMapSint32Sint32Map().containsKey(key);
-      }
-
-      public Builder clearMapSint32Sint32() {
-        copyOnWrite();
-        instance.getMutableMapSint32Sint32Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-       */
-
-      public Builder removeMapSint32Sint32(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapSint32Sint32Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapSint32Sint32Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapSint32Sint32() {
-        return getMapSint32Sint32Map();
-      }
-      /**
-       * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapSint32Sint32Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapSint32Sint32Map());
-      }
-      /**
-       * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-       */
-      @java.lang.Override
-
-      public int getMapSint32Sint32OrDefault(
-          int key,
-          int defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapSint32Sint32Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-       */
-      @java.lang.Override
-
-      public int getMapSint32Sint32OrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapSint32Sint32Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-       */
-      public Builder putMapSint32Sint32(
-          int key,
-          int value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapSint32Sint32Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-       */
-      public Builder putAllMapSint32Sint32(
-          java.util.Map<java.lang.Integer, java.lang.Integer> values) {
-        copyOnWrite();
-        instance.getMutableMapSint32Sint32Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapSint64Sint64Count() {
-        return instance.getMapSint64Sint64Map().size();
-      }
-      /**
-       * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapSint64Sint64(
-          long key) {
-        
-        return instance.getMapSint64Sint64Map().containsKey(key);
-      }
-
-      public Builder clearMapSint64Sint64() {
-        copyOnWrite();
-        instance.getMutableMapSint64Sint64Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-       */
-
-      public Builder removeMapSint64Sint64(
-          long key) {
-        
-        copyOnWrite();
-        instance.getMutableMapSint64Sint64Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapSint64Sint64Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapSint64Sint64() {
-        return getMapSint64Sint64Map();
-      }
-      /**
-       * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapSint64Sint64Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapSint64Sint64Map());
-      }
-      /**
-       * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-       */
-      @java.lang.Override
-
-      public long getMapSint64Sint64OrDefault(
-          long key,
-          long defaultValue) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapSint64Sint64Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-       */
-      @java.lang.Override
-
-      public long getMapSint64Sint64OrThrow(
-          long key) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapSint64Sint64Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-       */
-      public Builder putMapSint64Sint64(
-          long key,
-          long value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapSint64Sint64Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-       */
-      public Builder putAllMapSint64Sint64(
-          java.util.Map<java.lang.Long, java.lang.Long> values) {
-        copyOnWrite();
-        instance.getMutableMapSint64Sint64Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapFixed32Fixed32Count() {
-        return instance.getMapFixed32Fixed32Map().size();
-      }
-      /**
-       * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapFixed32Fixed32(
-          int key) {
-        
-        return instance.getMapFixed32Fixed32Map().containsKey(key);
-      }
-
-      public Builder clearMapFixed32Fixed32() {
-        copyOnWrite();
-        instance.getMutableMapFixed32Fixed32Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-       */
-
-      public Builder removeMapFixed32Fixed32(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapFixed32Fixed32Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapFixed32Fixed32Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapFixed32Fixed32() {
-        return getMapFixed32Fixed32Map();
-      }
-      /**
-       * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapFixed32Fixed32Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapFixed32Fixed32Map());
-      }
-      /**
-       * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-       */
-      @java.lang.Override
-
-      public int getMapFixed32Fixed32OrDefault(
-          int key,
-          int defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapFixed32Fixed32Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-       */
-      @java.lang.Override
-
-      public int getMapFixed32Fixed32OrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapFixed32Fixed32Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-       */
-      public Builder putMapFixed32Fixed32(
-          int key,
-          int value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapFixed32Fixed32Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-       */
-      public Builder putAllMapFixed32Fixed32(
-          java.util.Map<java.lang.Integer, java.lang.Integer> values) {
-        copyOnWrite();
-        instance.getMutableMapFixed32Fixed32Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapFixed64Fixed64Count() {
-        return instance.getMapFixed64Fixed64Map().size();
-      }
-      /**
-       * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapFixed64Fixed64(
-          long key) {
-        
-        return instance.getMapFixed64Fixed64Map().containsKey(key);
-      }
-
-      public Builder clearMapFixed64Fixed64() {
-        copyOnWrite();
-        instance.getMutableMapFixed64Fixed64Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-       */
-
-      public Builder removeMapFixed64Fixed64(
-          long key) {
-        
-        copyOnWrite();
-        instance.getMutableMapFixed64Fixed64Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapFixed64Fixed64Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapFixed64Fixed64() {
-        return getMapFixed64Fixed64Map();
-      }
-      /**
-       * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapFixed64Fixed64Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapFixed64Fixed64Map());
-      }
-      /**
-       * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-       */
-      @java.lang.Override
-
-      public long getMapFixed64Fixed64OrDefault(
-          long key,
-          long defaultValue) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapFixed64Fixed64Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-       */
-      @java.lang.Override
-
-      public long getMapFixed64Fixed64OrThrow(
-          long key) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapFixed64Fixed64Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-       */
-      public Builder putMapFixed64Fixed64(
-          long key,
-          long value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapFixed64Fixed64Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-       */
-      public Builder putAllMapFixed64Fixed64(
-          java.util.Map<java.lang.Long, java.lang.Long> values) {
-        copyOnWrite();
-        instance.getMutableMapFixed64Fixed64Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapSfixed32Sfixed32Count() {
-        return instance.getMapSfixed32Sfixed32Map().size();
-      }
-      /**
-       * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapSfixed32Sfixed32(
-          int key) {
-        
-        return instance.getMapSfixed32Sfixed32Map().containsKey(key);
-      }
-
-      public Builder clearMapSfixed32Sfixed32() {
-        copyOnWrite();
-        instance.getMutableMapSfixed32Sfixed32Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-       */
-
-      public Builder removeMapSfixed32Sfixed32(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapSfixed32Sfixed32Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapSfixed32Sfixed32Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapSfixed32Sfixed32() {
-        return getMapSfixed32Sfixed32Map();
-      }
-      /**
-       * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Integer> getMapSfixed32Sfixed32Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapSfixed32Sfixed32Map());
-      }
-      /**
-       * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-       */
-      @java.lang.Override
-
-      public int getMapSfixed32Sfixed32OrDefault(
-          int key,
-          int defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapSfixed32Sfixed32Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-       */
-      @java.lang.Override
-
-      public int getMapSfixed32Sfixed32OrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Integer> map =
-            instance.getMapSfixed32Sfixed32Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-       */
-      public Builder putMapSfixed32Sfixed32(
-          int key,
-          int value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapSfixed32Sfixed32Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-       */
-      public Builder putAllMapSfixed32Sfixed32(
-          java.util.Map<java.lang.Integer, java.lang.Integer> values) {
-        copyOnWrite();
-        instance.getMutableMapSfixed32Sfixed32Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapSfixed64Sfixed64Count() {
-        return instance.getMapSfixed64Sfixed64Map().size();
-      }
-      /**
-       * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapSfixed64Sfixed64(
-          long key) {
-        
-        return instance.getMapSfixed64Sfixed64Map().containsKey(key);
-      }
-
-      public Builder clearMapSfixed64Sfixed64() {
-        copyOnWrite();
-        instance.getMutableMapSfixed64Sfixed64Map().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-       */
-
-      public Builder removeMapSfixed64Sfixed64(
-          long key) {
-        
-        copyOnWrite();
-        instance.getMutableMapSfixed64Sfixed64Map().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapSfixed64Sfixed64Map()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapSfixed64Sfixed64() {
-        return getMapSfixed64Sfixed64Map();
-      }
-      /**
-       * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Long, java.lang.Long> getMapSfixed64Sfixed64Map() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapSfixed64Sfixed64Map());
-      }
-      /**
-       * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-       */
-      @java.lang.Override
-
-      public long getMapSfixed64Sfixed64OrDefault(
-          long key,
-          long defaultValue) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapSfixed64Sfixed64Map();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-       */
-      @java.lang.Override
-
-      public long getMapSfixed64Sfixed64OrThrow(
-          long key) {
-        
-        java.util.Map<java.lang.Long, java.lang.Long> map =
-            instance.getMapSfixed64Sfixed64Map();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-       */
-      public Builder putMapSfixed64Sfixed64(
-          long key,
-          long value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapSfixed64Sfixed64Map().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-       */
-      public Builder putAllMapSfixed64Sfixed64(
-          java.util.Map<java.lang.Long, java.lang.Long> values) {
-        copyOnWrite();
-        instance.getMutableMapSfixed64Sfixed64Map().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapInt32FloatCount() {
-        return instance.getMapInt32FloatMap().size();
-      }
-      /**
-       * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapInt32Float(
-          int key) {
-        
-        return instance.getMapInt32FloatMap().containsKey(key);
-      }
-
-      public Builder clearMapInt32Float() {
-        copyOnWrite();
-        instance.getMutableMapInt32FloatMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-       */
-
-      public Builder removeMapInt32Float(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapInt32FloatMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapInt32FloatMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Float> getMapInt32Float() {
-        return getMapInt32FloatMap();
-      }
-      /**
-       * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Float> getMapInt32FloatMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapInt32FloatMap());
-      }
-      /**
-       * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-       */
-      @java.lang.Override
-
-      public float getMapInt32FloatOrDefault(
-          int key,
-          float defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Float> map =
-            instance.getMapInt32FloatMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-       */
-      @java.lang.Override
-
-      public float getMapInt32FloatOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Float> map =
-            instance.getMapInt32FloatMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-       */
-      public Builder putMapInt32Float(
-          int key,
-          float value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapInt32FloatMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-       */
-      public Builder putAllMapInt32Float(
-          java.util.Map<java.lang.Integer, java.lang.Float> values) {
-        copyOnWrite();
-        instance.getMutableMapInt32FloatMap().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapInt32DoubleCount() {
-        return instance.getMapInt32DoubleMap().size();
-      }
-      /**
-       * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapInt32Double(
-          int key) {
-        
-        return instance.getMapInt32DoubleMap().containsKey(key);
-      }
-
-      public Builder clearMapInt32Double() {
-        copyOnWrite();
-        instance.getMutableMapInt32DoubleMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-       */
-
-      public Builder removeMapInt32Double(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapInt32DoubleMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapInt32DoubleMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, java.lang.Double> getMapInt32Double() {
-        return getMapInt32DoubleMap();
-      }
-      /**
-       * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, java.lang.Double> getMapInt32DoubleMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapInt32DoubleMap());
-      }
-      /**
-       * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-       */
-      @java.lang.Override
-
-      public double getMapInt32DoubleOrDefault(
-          int key,
-          double defaultValue) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Double> map =
-            instance.getMapInt32DoubleMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-       */
-      @java.lang.Override
-
-      public double getMapInt32DoubleOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, java.lang.Double> map =
-            instance.getMapInt32DoubleMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-       */
-      public Builder putMapInt32Double(
-          int key,
-          double value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapInt32DoubleMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-       */
-      public Builder putAllMapInt32Double(
-          java.util.Map<java.lang.Integer, java.lang.Double> values) {
-        copyOnWrite();
-        instance.getMutableMapInt32DoubleMap().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapBoolBoolCount() {
-        return instance.getMapBoolBoolMap().size();
-      }
-      /**
-       * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapBoolBool(
-          boolean key) {
-        
-        return instance.getMapBoolBoolMap().containsKey(key);
-      }
-
-      public Builder clearMapBoolBool() {
-        copyOnWrite();
-        instance.getMutableMapBoolBoolMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-       */
-
-      public Builder removeMapBoolBool(
-          boolean key) {
-        
-        copyOnWrite();
-        instance.getMutableMapBoolBoolMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapBoolBoolMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Boolean, java.lang.Boolean> getMapBoolBool() {
-        return getMapBoolBoolMap();
-      }
-      /**
-       * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Boolean, java.lang.Boolean> getMapBoolBoolMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapBoolBoolMap());
-      }
-      /**
-       * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-       */
-      @java.lang.Override
-
-      public boolean getMapBoolBoolOrDefault(
-          boolean key,
-          boolean defaultValue) {
-        
-        java.util.Map<java.lang.Boolean, java.lang.Boolean> map =
-            instance.getMapBoolBoolMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-       */
-      @java.lang.Override
-
-      public boolean getMapBoolBoolOrThrow(
-          boolean key) {
-        
-        java.util.Map<java.lang.Boolean, java.lang.Boolean> map =
-            instance.getMapBoolBoolMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-       */
-      public Builder putMapBoolBool(
-          boolean key,
-          boolean value) {
-        
-        
-        copyOnWrite();
-        instance.getMutableMapBoolBoolMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-       */
-      public Builder putAllMapBoolBool(
-          java.util.Map<java.lang.Boolean, java.lang.Boolean> values) {
-        copyOnWrite();
-        instance.getMutableMapBoolBoolMap().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapStringStringCount() {
-        return instance.getMapStringStringMap().size();
-      }
-      /**
-       * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapStringString(
-          java.lang.String key) {
-        key.getClass();
-        return instance.getMapStringStringMap().containsKey(key);
-      }
-
-      public Builder clearMapStringString() {
-        copyOnWrite();
-        instance.getMutableMapStringStringMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-       */
-
-      public Builder removeMapStringString(
-          java.lang.String key) {
-        key.getClass();
-        copyOnWrite();
-        instance.getMutableMapStringStringMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapStringStringMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.String, java.lang.String> getMapStringString() {
-        return getMapStringStringMap();
-      }
-      /**
-       * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.String, java.lang.String> getMapStringStringMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapStringStringMap());
-      }
-      /**
-       * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-       */
-      @java.lang.Override
-
-      public java.lang.String getMapStringStringOrDefault(
-          java.lang.String key,
-          java.lang.String defaultValue) {
-        key.getClass();
-        java.util.Map<java.lang.String, java.lang.String> map =
-            instance.getMapStringStringMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-       */
-      @java.lang.Override
-
-      public java.lang.String getMapStringStringOrThrow(
-          java.lang.String key) {
-        key.getClass();
-        java.util.Map<java.lang.String, java.lang.String> map =
-            instance.getMapStringStringMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-       */
-      public Builder putMapStringString(
-          java.lang.String key,
-          java.lang.String value) {
-        key.getClass();
-        value.getClass();
-        copyOnWrite();
-        instance.getMutableMapStringStringMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-       */
-      public Builder putAllMapStringString(
-          java.util.Map<java.lang.String, java.lang.String> values) {
-        copyOnWrite();
-        instance.getMutableMapStringStringMap().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapInt32BytesCount() {
-        return instance.getMapInt32BytesMap().size();
-      }
-      /**
-       * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapInt32Bytes(
-          int key) {
-        
-        return instance.getMapInt32BytesMap().containsKey(key);
-      }
-
-      public Builder clearMapInt32Bytes() {
-        copyOnWrite();
-        instance.getMutableMapInt32BytesMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-       */
-
-      public Builder removeMapInt32Bytes(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapInt32BytesMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapInt32BytesMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, com.google.protobuf.ByteString> getMapInt32Bytes() {
-        return getMapInt32BytesMap();
-      }
-      /**
-       * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, com.google.protobuf.ByteString> getMapInt32BytesMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapInt32BytesMap());
-      }
-      /**
-       * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-       */
-      @java.lang.Override
-
-      public com.google.protobuf.ByteString getMapInt32BytesOrDefault(
-          int key,
-          com.google.protobuf.ByteString defaultValue) {
-        
-        java.util.Map<java.lang.Integer, com.google.protobuf.ByteString> map =
-            instance.getMapInt32BytesMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-       */
-      @java.lang.Override
-
-      public com.google.protobuf.ByteString getMapInt32BytesOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, com.google.protobuf.ByteString> map =
-            instance.getMapInt32BytesMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-       */
-      public Builder putMapInt32Bytes(
-          int key,
-          com.google.protobuf.ByteString value) {
-        
-        value.getClass();
-        copyOnWrite();
-        instance.getMutableMapInt32BytesMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-       */
-      public Builder putAllMapInt32Bytes(
-          java.util.Map<java.lang.Integer, com.google.protobuf.ByteString> values) {
-        copyOnWrite();
-        instance.getMutableMapInt32BytesMap().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapInt32EnumCount() {
-        return instance.getMapInt32EnumMap().size();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapInt32Enum(
-          int key) {
-        
-        return instance.getMapInt32EnumMap().containsKey(key);
-      }
-
-      public Builder clearMapInt32Enum() {
-        copyOnWrite();
-        instance.getMutableMapInt32EnumMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-       */
-
-      public Builder removeMapInt32Enum(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapInt32EnumMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapInt32EnumMap()} instead.
-       */
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite>
-      getMapInt32Enum() {
-        return getMapInt32EnumMap();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-       */
-      @java.lang.Override
-
-      public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite>
-      getMapInt32EnumMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapInt32EnumMap());
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-       */
-      @java.lang.Override
-
-      public protobuf_unittest.MapLiteUnittest.MapEnumLite getMapInt32EnumOrDefault(
-          int key,
-          protobuf_unittest.MapLiteUnittest.MapEnumLite defaultValue) {
-        
-        java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite> map =
-            instance.getMapInt32EnumMap();
-        return map.containsKey(key)
-               ? map.get(key)
-               : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-       */
-      @java.lang.Override
-
-      public protobuf_unittest.MapLiteUnittest.MapEnumLite getMapInt32EnumOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite> map =
-            instance.getMapInt32EnumMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-       */
-      public Builder putMapInt32Enum(
-          int key,
-          protobuf_unittest.MapLiteUnittest.MapEnumLite value) {
-        
-        value.getClass();
-        copyOnWrite();
-        instance.getMutableMapInt32EnumMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-       */
-      public Builder putAllMapInt32Enum(
-          java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.MapEnumLite> values) {
-        copyOnWrite();
-        instance.getMutableMapInt32EnumMap().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getMapInt32ForeignMessageCount() {
-        return instance.getMapInt32ForeignMessageMap().size();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapInt32ForeignMessage(
-          int key) {
-        
-        return instance.getMapInt32ForeignMessageMap().containsKey(key);
-      }
-
-      public Builder clearMapInt32ForeignMessage() {
-        copyOnWrite();
-        instance.getMutableMapInt32ForeignMessageMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-       */
-
-      public Builder removeMapInt32ForeignMessage(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapInt32ForeignMessageMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapInt32ForeignMessageMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite> getMapInt32ForeignMessage() {
-        return getMapInt32ForeignMessageMap();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite> getMapInt32ForeignMessageMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapInt32ForeignMessageMap());
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-       */
-      @java.lang.Override
-
-      public protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite getMapInt32ForeignMessageOrDefault(
-          int key,
-          protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite defaultValue) {
-        
-        java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite> map =
-            instance.getMapInt32ForeignMessageMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-       */
-      @java.lang.Override
-
-      public protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite getMapInt32ForeignMessageOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite> map =
-            instance.getMapInt32ForeignMessageMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-       */
-      public Builder putMapInt32ForeignMessage(
-          int key,
-          protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite value) {
-        
-        value.getClass();
-        copyOnWrite();
-        instance.getMutableMapInt32ForeignMessageMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-       */
-      public Builder putAllMapInt32ForeignMessage(
-          java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite> values) {
-        copyOnWrite();
-        instance.getMutableMapInt32ForeignMessageMap().putAll(values);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestArenaMapLite)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.MapLiteUnittest.TestArenaMapLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "mapInt32Int32_",
-              MapInt32Int32DefaultEntryHolder.defaultEntry,
-              "mapInt64Int64_",
-              MapInt64Int64DefaultEntryHolder.defaultEntry,
-              "mapUint32Uint32_",
-              MapUint32Uint32DefaultEntryHolder.defaultEntry,
-              "mapUint64Uint64_",
-              MapUint64Uint64DefaultEntryHolder.defaultEntry,
-              "mapSint32Sint32_",
-              MapSint32Sint32DefaultEntryHolder.defaultEntry,
-              "mapSint64Sint64_",
-              MapSint64Sint64DefaultEntryHolder.defaultEntry,
-              "mapFixed32Fixed32_",
-              MapFixed32Fixed32DefaultEntryHolder.defaultEntry,
-              "mapFixed64Fixed64_",
-              MapFixed64Fixed64DefaultEntryHolder.defaultEntry,
-              "mapSfixed32Sfixed32_",
-              MapSfixed32Sfixed32DefaultEntryHolder.defaultEntry,
-              "mapSfixed64Sfixed64_",
-              MapSfixed64Sfixed64DefaultEntryHolder.defaultEntry,
-              "mapInt32Float_",
-              MapInt32FloatDefaultEntryHolder.defaultEntry,
-              "mapInt32Double_",
-              MapInt32DoubleDefaultEntryHolder.defaultEntry,
-              "mapBoolBool_",
-              MapBoolBoolDefaultEntryHolder.defaultEntry,
-              "mapStringString_",
-              MapStringStringDefaultEntryHolder.defaultEntry,
-              "mapInt32Bytes_",
-              MapInt32BytesDefaultEntryHolder.defaultEntry,
-              "mapInt32Enum_",
-              MapInt32EnumDefaultEntryHolder.defaultEntry,
-              protobuf_unittest.MapLiteUnittest.MapEnumLite.internalGetVerifier(),
-              "mapInt32ForeignMessage_",
-              MapInt32ForeignMessageDefaultEntryHolder.defaultEntry,
-            };
-            java.lang.String info =
-                "\u0001\u0011\u0000\u0000\u0001\u0011\u0011\u0011\u0000\u0000\u00012\u00022\u0003" +
-                "2\u00042\u00052\u00062\u00072\b2\t2\n2\u000b2\f2\r2\u000e2\u000f2\u0010\u0832\u0011" +
-                "2";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.MapLiteUnittest.TestArenaMapLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.MapLiteUnittest.TestArenaMapLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.MapLiteUnittest.TestArenaMapLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMapLite)
-    private static final protobuf_unittest.MapLiteUnittest.TestArenaMapLite DEFAULT_INSTANCE;
-    static {
-      TestArenaMapLite defaultInstance = new TestArenaMapLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestArenaMapLite.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.MapLiteUnittest.TestArenaMapLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestArenaMapLite> PARSER;
-
-    public static com.google.protobuf.Parser<TestArenaMapLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestRequiredMessageMapLiteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestRequiredMessageMapLite)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-     */
-    int getMapFieldCount();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-     */
-    boolean containsMapField(
-        int key);
-    /**
-     * Use {@link #getMapFieldMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.TestRequiredLite>
-    getMapField();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-     */
-    java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.TestRequiredLite>
-    getMapFieldMap();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-     */
-
-    protobuf_unittest.MapLiteUnittest.TestRequiredLite getMapFieldOrDefault(
-        int key,
-        protobuf_unittest.MapLiteUnittest.TestRequiredLite defaultValue);
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-     */
-
-    protobuf_unittest.MapLiteUnittest.TestRequiredLite getMapFieldOrThrow(
-        int key);
-  }
-  /**
-   * <pre>
-   * Test embedded message with required fields
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestRequiredMessageMapLite}
-   */
-  public  static final class TestRequiredMessageMapLite extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestRequiredMessageMapLite, TestRequiredMessageMapLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestRequiredMessageMapLite)
-      TestRequiredMessageMapLiteOrBuilder {
-    private TestRequiredMessageMapLite() {
-    }
-    public static final int MAP_FIELD_FIELD_NUMBER = 1;
-    private static final class MapFieldDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, protobuf_unittest.MapLiteUnittest.TestRequiredLite> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, protobuf_unittest.MapLiteUnittest.TestRequiredLite>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.MESSAGE,
-                  protobuf_unittest.MapLiteUnittest.TestRequiredLite.getDefaultInstance());
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, protobuf_unittest.MapLiteUnittest.TestRequiredLite> mapField_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, protobuf_unittest.MapLiteUnittest.TestRequiredLite>
-    internalGetMapField() {
-      return mapField_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, protobuf_unittest.MapLiteUnittest.TestRequiredLite>
-    internalGetMutableMapField() {
-      if (!mapField_.isMutable()) {
-        mapField_ = mapField_.mutableCopy();
-      }
-      return mapField_;
-    }
-    @java.lang.Override
-
-    public int getMapFieldCount() {
-      return internalGetMapField().size();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapField(
-        int key) {
-      
-      return internalGetMapField().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapFieldMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.TestRequiredLite> getMapField() {
-      return getMapFieldMap();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.TestRequiredLite> getMapFieldMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapField());
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-     */
-    @java.lang.Override
-
-    public protobuf_unittest.MapLiteUnittest.TestRequiredLite getMapFieldOrDefault(
-        int key,
-        protobuf_unittest.MapLiteUnittest.TestRequiredLite defaultValue) {
-      
-      java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.TestRequiredLite> map =
-          internalGetMapField();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-     */
-    @java.lang.Override
-
-    public protobuf_unittest.MapLiteUnittest.TestRequiredLite getMapFieldOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.TestRequiredLite> map =
-          internalGetMapField();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-     */
-    private java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.TestRequiredLite>
-    getMutableMapFieldMap() {
-      return internalGetMutableMapField();
-    }
-
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Test embedded message with required fields
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestRequiredMessageMapLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestRequiredMessageMapLite)
-        protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLiteOrBuilder {
-      // Construct using protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      @java.lang.Override
-
-      public int getMapFieldCount() {
-        return instance.getMapFieldMap().size();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapField(
-          int key) {
-        
-        return instance.getMapFieldMap().containsKey(key);
-      }
-
-      public Builder clearMapField() {
-        copyOnWrite();
-        instance.getMutableMapFieldMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-       */
-
-      public Builder removeMapField(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapFieldMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapFieldMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.TestRequiredLite> getMapField() {
-        return getMapFieldMap();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.TestRequiredLite> getMapFieldMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapFieldMap());
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-       */
-      @java.lang.Override
-
-      public protobuf_unittest.MapLiteUnittest.TestRequiredLite getMapFieldOrDefault(
-          int key,
-          protobuf_unittest.MapLiteUnittest.TestRequiredLite defaultValue) {
-        
-        java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.TestRequiredLite> map =
-            instance.getMapFieldMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-       */
-      @java.lang.Override
-
-      public protobuf_unittest.MapLiteUnittest.TestRequiredLite getMapFieldOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.TestRequiredLite> map =
-            instance.getMapFieldMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-       */
-      public Builder putMapField(
-          int key,
-          protobuf_unittest.MapLiteUnittest.TestRequiredLite value) {
-        
-        value.getClass();
-        copyOnWrite();
-        instance.getMutableMapFieldMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-       */
-      public Builder putAllMapField(
-          java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.TestRequiredLite> values) {
-        copyOnWrite();
-        instance.getMutableMapFieldMap().putAll(values);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestRequiredMessageMapLite)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "mapField_",
-              MapFieldDefaultEntryHolder.defaultEntry,
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0000\u0001\u0001\u0001\u0001\u0000\u0001\u0001\u0432";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestRequiredMessageMapLite)
-    private static final protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite DEFAULT_INSTANCE;
-    static {
-      TestRequiredMessageMapLite defaultInstance = new TestRequiredMessageMapLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestRequiredMessageMapLite.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestRequiredMessageMapLite> PARSER;
-
-    public static com.google.protobuf.Parser<TestRequiredMessageMapLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestEnumMapLiteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestEnumMapLite)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-     */
-    int getKnownMapFieldCount();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-     */
-    boolean containsKnownMapField(
-        int key);
-    /**
-     * Use {@link #getKnownMapFieldMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite>
-    getKnownMapField();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-     */
-    java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite>
-    getKnownMapFieldMap();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-     */
-    protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite getKnownMapFieldOrDefault(
-        int key,
-        protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite defaultValue);
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-     */
-    protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite getKnownMapFieldOrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-     */
-    int getUnknownMapFieldCount();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-     */
-    boolean containsUnknownMapField(
-        int key);
-    /**
-     * Use {@link #getUnknownMapFieldMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite>
-    getUnknownMapField();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-     */
-    java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite>
-    getUnknownMapFieldMap();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-     */
-    protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite getUnknownMapFieldOrDefault(
-        int key,
-        protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite defaultValue);
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-     */
-    protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite getUnknownMapFieldOrThrow(
-        int key);
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestEnumMapLite}
-   */
-  public  static final class TestEnumMapLite extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestEnumMapLite, TestEnumMapLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestEnumMapLite)
-      TestEnumMapLiteOrBuilder {
-    private TestEnumMapLite() {
-    }
-    public static final int KNOWN_MAP_FIELD_FIELD_NUMBER = 101;
-    private static final class KnownMapFieldDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.ENUM,
-                  protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite.PROTO2_MAP_ENUM_FOO_LITE.getNumber());
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> knownMapField_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetKnownMapField() {
-      return knownMapField_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableKnownMapField() {
-      if (!knownMapField_.isMutable()) {
-        knownMapField_ = knownMapField_.mutableCopy();
-      }
-      return knownMapField_;
-    }
-    @java.lang.Override
-
-    public int getKnownMapFieldCount() {
-      return internalGetKnownMapField().size();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsKnownMapField(
-        int key) {
-      
-      return internalGetKnownMapField().containsKey(key);
-    }
-    private static final
-    com.google.protobuf.Internal.MapAdapter.Converter<
-        java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite> knownMapFieldValueConverter =
-            com.google.protobuf.Internal.MapAdapter.newEnumConverter(
-                protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite.internalGetValueMap(),
-                protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite.PROTO2_MAP_ENUM_FOO_LITE);
-    /**
-     * Use {@link #getKnownMapFieldMap()} instead.
-     */
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite>
-    getKnownMapField() {
-      return getKnownMapFieldMap();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite>
-    getKnownMapFieldMap() {
-      return java.util.Collections.unmodifiableMap(
-          new com.google.protobuf.Internal.MapAdapter<
-            java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite, java.lang.Integer>(
-                internalGetKnownMapField(),
-                knownMapFieldValueConverter));
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-     */
-    @java.lang.Override
-
-    public protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite getKnownMapFieldOrDefault(
-        int key,
-        protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetKnownMapField();
-      return map.containsKey(key)
-             ? knownMapFieldValueConverter.doForward(map.get(key))
-             : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-     */
-    @java.lang.Override
-
-    public protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite getKnownMapFieldOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetKnownMapField();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return knownMapFieldValueConverter.doForward(map.get(key));
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-     */
-    private java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite>
-    getMutableKnownMapFieldMap() {
-      return new com.google.protobuf.Internal.MapAdapter<
-          java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite, java.lang.Integer>(
-              internalGetMutableKnownMapField(),
-              knownMapFieldValueConverter);
-    }
-
-    public static final int UNKNOWN_MAP_FIELD_FIELD_NUMBER = 102;
-    private static final class UnknownMapFieldDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.ENUM,
-                  protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite.PROTO2_MAP_ENUM_FOO_LITE.getNumber());
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> unknownMapField_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetUnknownMapField() {
-      return unknownMapField_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableUnknownMapField() {
-      if (!unknownMapField_.isMutable()) {
-        unknownMapField_ = unknownMapField_.mutableCopy();
-      }
-      return unknownMapField_;
-    }
-    @java.lang.Override
-
-    public int getUnknownMapFieldCount() {
-      return internalGetUnknownMapField().size();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsUnknownMapField(
-        int key) {
-      
-      return internalGetUnknownMapField().containsKey(key);
-    }
-    private static final
-    com.google.protobuf.Internal.MapAdapter.Converter<
-        java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite> unknownMapFieldValueConverter =
-            com.google.protobuf.Internal.MapAdapter.newEnumConverter(
-                protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite.internalGetValueMap(),
-                protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite.PROTO2_MAP_ENUM_FOO_LITE);
-    /**
-     * Use {@link #getUnknownMapFieldMap()} instead.
-     */
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite>
-    getUnknownMapField() {
-      return getUnknownMapFieldMap();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite>
-    getUnknownMapFieldMap() {
-      return java.util.Collections.unmodifiableMap(
-          new com.google.protobuf.Internal.MapAdapter<
-            java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite, java.lang.Integer>(
-                internalGetUnknownMapField(),
-                unknownMapFieldValueConverter));
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-     */
-    @java.lang.Override
-
-    public protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite getUnknownMapFieldOrDefault(
-        int key,
-        protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetUnknownMapField();
-      return map.containsKey(key)
-             ? unknownMapFieldValueConverter.doForward(map.get(key))
-             : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-     */
-    @java.lang.Override
-
-    public protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite getUnknownMapFieldOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetUnknownMapField();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return unknownMapFieldValueConverter.doForward(map.get(key));
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-     */
-    private java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite>
-    getMutableUnknownMapFieldMap() {
-      return new com.google.protobuf.Internal.MapAdapter<
-          java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite, java.lang.Integer>(
-              internalGetMutableUnknownMapField(),
-              unknownMapFieldValueConverter);
-    }
-
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.MapLiteUnittest.TestEnumMapLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestEnumMapLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.MapLiteUnittest.TestEnumMapLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestEnumMapLite)
-        protobuf_unittest.MapLiteUnittest.TestEnumMapLiteOrBuilder {
-      // Construct using protobuf_unittest.MapLiteUnittest.TestEnumMapLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      @java.lang.Override
-
-      public int getKnownMapFieldCount() {
-        return instance.getKnownMapFieldMap().size();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsKnownMapField(
-          int key) {
-        
-        return instance.getKnownMapFieldMap().containsKey(key);
-      }
-
-      public Builder clearKnownMapField() {
-        copyOnWrite();
-        instance.getMutableKnownMapFieldMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-       */
-
-      public Builder removeKnownMapField(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableKnownMapFieldMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getKnownMapFieldMap()} instead.
-       */
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite>
-      getKnownMapField() {
-        return getKnownMapFieldMap();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-       */
-      @java.lang.Override
-
-      public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite>
-      getKnownMapFieldMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getKnownMapFieldMap());
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-       */
-      @java.lang.Override
-
-      public protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite getKnownMapFieldOrDefault(
-          int key,
-          protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite defaultValue) {
-        
-        java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite> map =
-            instance.getKnownMapFieldMap();
-        return map.containsKey(key)
-               ? map.get(key)
-               : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-       */
-      @java.lang.Override
-
-      public protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite getKnownMapFieldOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite> map =
-            instance.getKnownMapFieldMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-       */
-      public Builder putKnownMapField(
-          int key,
-          protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite value) {
-        
-        value.getClass();
-        copyOnWrite();
-        instance.getMutableKnownMapFieldMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-       */
-      public Builder putAllKnownMapField(
-          java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite> values) {
-        copyOnWrite();
-        instance.getMutableKnownMapFieldMap().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getUnknownMapFieldCount() {
-        return instance.getUnknownMapFieldMap().size();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsUnknownMapField(
-          int key) {
-        
-        return instance.getUnknownMapFieldMap().containsKey(key);
-      }
-
-      public Builder clearUnknownMapField() {
-        copyOnWrite();
-        instance.getMutableUnknownMapFieldMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-       */
-
-      public Builder removeUnknownMapField(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableUnknownMapFieldMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getUnknownMapFieldMap()} instead.
-       */
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite>
-      getUnknownMapField() {
-        return getUnknownMapFieldMap();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-       */
-      @java.lang.Override
-
-      public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite>
-      getUnknownMapFieldMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getUnknownMapFieldMap());
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-       */
-      @java.lang.Override
-
-      public protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite getUnknownMapFieldOrDefault(
-          int key,
-          protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite defaultValue) {
-        
-        java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite> map =
-            instance.getUnknownMapFieldMap();
-        return map.containsKey(key)
-               ? map.get(key)
-               : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-       */
-      @java.lang.Override
-
-      public protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite getUnknownMapFieldOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite> map =
-            instance.getUnknownMapFieldMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-       */
-      public Builder putUnknownMapField(
-          int key,
-          protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite value) {
-        
-        value.getClass();
-        copyOnWrite();
-        instance.getMutableUnknownMapFieldMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-       */
-      public Builder putAllUnknownMapField(
-          java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite> values) {
-        copyOnWrite();
-        instance.getMutableUnknownMapFieldMap().putAll(values);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestEnumMapLite)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.MapLiteUnittest.TestEnumMapLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "knownMapField_",
-              KnownMapFieldDefaultEntryHolder.defaultEntry,
-              protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite.internalGetVerifier(),
-              "unknownMapField_",
-              UnknownMapFieldDefaultEntryHolder.defaultEntry,
-              protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite.internalGetVerifier(),
-            };
-            java.lang.String info =
-                "\u0001\u0002\u0000\u0000ef\u0002\u0002\u0000\u0000e\u0832f\u0832";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.MapLiteUnittest.TestEnumMapLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.MapLiteUnittest.TestEnumMapLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.MapLiteUnittest.TestEnumMapLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestEnumMapLite)
-    private static final protobuf_unittest.MapLiteUnittest.TestEnumMapLite DEFAULT_INSTANCE;
-    static {
-      TestEnumMapLite defaultInstance = new TestEnumMapLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestEnumMapLite.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestEnumMapLite> PARSER;
-
-    public static com.google.protobuf.Parser<TestEnumMapLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestEnumMapPlusExtraLiteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestEnumMapPlusExtraLite)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-     */
-    int getKnownMapFieldCount();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-     */
-    boolean containsKnownMapField(
-        int key);
-    /**
-     * Use {@link #getKnownMapFieldMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite>
-    getKnownMapField();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-     */
-    java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite>
-    getKnownMapFieldMap();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-     */
-    protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite getKnownMapFieldOrDefault(
-        int key,
-        protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite defaultValue);
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-     */
-    protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite getKnownMapFieldOrThrow(
-        int key);
-
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-     */
-    int getUnknownMapFieldCount();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-     */
-    boolean containsUnknownMapField(
-        int key);
-    /**
-     * Use {@link #getUnknownMapFieldMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite>
-    getUnknownMapField();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-     */
-    java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite>
-    getUnknownMapFieldMap();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-     */
-    protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite getUnknownMapFieldOrDefault(
-        int key,
-        protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite defaultValue);
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-     */
-    protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite getUnknownMapFieldOrThrow(
-        int key);
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestEnumMapPlusExtraLite}
-   */
-  public  static final class TestEnumMapPlusExtraLite extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestEnumMapPlusExtraLite, TestEnumMapPlusExtraLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestEnumMapPlusExtraLite)
-      TestEnumMapPlusExtraLiteOrBuilder {
-    private TestEnumMapPlusExtraLite() {
-    }
-    public static final int KNOWN_MAP_FIELD_FIELD_NUMBER = 101;
-    private static final class KnownMapFieldDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.ENUM,
-                  protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite.E_PROTO2_MAP_ENUM_FOO_LITE.getNumber());
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> knownMapField_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetKnownMapField() {
-      return knownMapField_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableKnownMapField() {
-      if (!knownMapField_.isMutable()) {
-        knownMapField_ = knownMapField_.mutableCopy();
-      }
-      return knownMapField_;
-    }
-    @java.lang.Override
-
-    public int getKnownMapFieldCount() {
-      return internalGetKnownMapField().size();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsKnownMapField(
-        int key) {
-      
-      return internalGetKnownMapField().containsKey(key);
-    }
-    private static final
-    com.google.protobuf.Internal.MapAdapter.Converter<
-        java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite> knownMapFieldValueConverter =
-            com.google.protobuf.Internal.MapAdapter.newEnumConverter(
-                protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite.internalGetValueMap(),
-                protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite.E_PROTO2_MAP_ENUM_FOO_LITE);
-    /**
-     * Use {@link #getKnownMapFieldMap()} instead.
-     */
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite>
-    getKnownMapField() {
-      return getKnownMapFieldMap();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite>
-    getKnownMapFieldMap() {
-      return java.util.Collections.unmodifiableMap(
-          new com.google.protobuf.Internal.MapAdapter<
-            java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite, java.lang.Integer>(
-                internalGetKnownMapField(),
-                knownMapFieldValueConverter));
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-     */
-    @java.lang.Override
-
-    public protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite getKnownMapFieldOrDefault(
-        int key,
-        protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetKnownMapField();
-      return map.containsKey(key)
-             ? knownMapFieldValueConverter.doForward(map.get(key))
-             : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-     */
-    @java.lang.Override
-
-    public protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite getKnownMapFieldOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetKnownMapField();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return knownMapFieldValueConverter.doForward(map.get(key));
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-     */
-    private java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite>
-    getMutableKnownMapFieldMap() {
-      return new com.google.protobuf.Internal.MapAdapter<
-          java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite, java.lang.Integer>(
-              internalGetMutableKnownMapField(),
-              knownMapFieldValueConverter);
-    }
-
-    public static final int UNKNOWN_MAP_FIELD_FIELD_NUMBER = 102;
-    private static final class UnknownMapFieldDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, java.lang.Integer> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, java.lang.Integer>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.ENUM,
-                  protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite.E_PROTO2_MAP_ENUM_FOO_LITE.getNumber());
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, java.lang.Integer> unknownMapField_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetUnknownMapField() {
-      return unknownMapField_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, java.lang.Integer>
-    internalGetMutableUnknownMapField() {
-      if (!unknownMapField_.isMutable()) {
-        unknownMapField_ = unknownMapField_.mutableCopy();
-      }
-      return unknownMapField_;
-    }
-    @java.lang.Override
-
-    public int getUnknownMapFieldCount() {
-      return internalGetUnknownMapField().size();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsUnknownMapField(
-        int key) {
-      
-      return internalGetUnknownMapField().containsKey(key);
-    }
-    private static final
-    com.google.protobuf.Internal.MapAdapter.Converter<
-        java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite> unknownMapFieldValueConverter =
-            com.google.protobuf.Internal.MapAdapter.newEnumConverter(
-                protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite.internalGetValueMap(),
-                protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite.E_PROTO2_MAP_ENUM_FOO_LITE);
-    /**
-     * Use {@link #getUnknownMapFieldMap()} instead.
-     */
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite>
-    getUnknownMapField() {
-      return getUnknownMapFieldMap();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite>
-    getUnknownMapFieldMap() {
-      return java.util.Collections.unmodifiableMap(
-          new com.google.protobuf.Internal.MapAdapter<
-            java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite, java.lang.Integer>(
-                internalGetUnknownMapField(),
-                unknownMapFieldValueConverter));
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-     */
-    @java.lang.Override
-
-    public protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite getUnknownMapFieldOrDefault(
-        int key,
-        protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite defaultValue) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetUnknownMapField();
-      return map.containsKey(key)
-             ? unknownMapFieldValueConverter.doForward(map.get(key))
-             : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-     */
-    @java.lang.Override
-
-    public protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite getUnknownMapFieldOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, java.lang.Integer> map =
-          internalGetUnknownMapField();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return unknownMapFieldValueConverter.doForward(map.get(key));
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-     */
-    private java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite>
-    getMutableUnknownMapFieldMap() {
-      return new com.google.protobuf.Internal.MapAdapter<
-          java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite, java.lang.Integer>(
-              internalGetMutableUnknownMapField(),
-              unknownMapFieldValueConverter);
-    }
-
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestEnumMapPlusExtraLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestEnumMapPlusExtraLite)
-        protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLiteOrBuilder {
-      // Construct using protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      @java.lang.Override
-
-      public int getKnownMapFieldCount() {
-        return instance.getKnownMapFieldMap().size();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsKnownMapField(
-          int key) {
-        
-        return instance.getKnownMapFieldMap().containsKey(key);
-      }
-
-      public Builder clearKnownMapField() {
-        copyOnWrite();
-        instance.getMutableKnownMapFieldMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-       */
-
-      public Builder removeKnownMapField(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableKnownMapFieldMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getKnownMapFieldMap()} instead.
-       */
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite>
-      getKnownMapField() {
-        return getKnownMapFieldMap();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-       */
-      @java.lang.Override
-
-      public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite>
-      getKnownMapFieldMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getKnownMapFieldMap());
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-       */
-      @java.lang.Override
-
-      public protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite getKnownMapFieldOrDefault(
-          int key,
-          protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite defaultValue) {
-        
-        java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite> map =
-            instance.getKnownMapFieldMap();
-        return map.containsKey(key)
-               ? map.get(key)
-               : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-       */
-      @java.lang.Override
-
-      public protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite getKnownMapFieldOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite> map =
-            instance.getKnownMapFieldMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-       */
-      public Builder putKnownMapField(
-          int key,
-          protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite value) {
-        
-        value.getClass();
-        copyOnWrite();
-        instance.getMutableKnownMapFieldMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-       */
-      public Builder putAllKnownMapField(
-          java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite> values) {
-        copyOnWrite();
-        instance.getMutableKnownMapFieldMap().putAll(values);
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getUnknownMapFieldCount() {
-        return instance.getUnknownMapFieldMap().size();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsUnknownMapField(
-          int key) {
-        
-        return instance.getUnknownMapFieldMap().containsKey(key);
-      }
-
-      public Builder clearUnknownMapField() {
-        copyOnWrite();
-        instance.getMutableUnknownMapFieldMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-       */
-
-      public Builder removeUnknownMapField(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableUnknownMapFieldMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getUnknownMapFieldMap()} instead.
-       */
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite>
-      getUnknownMapField() {
-        return getUnknownMapFieldMap();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-       */
-      @java.lang.Override
-
-      public java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite>
-      getUnknownMapFieldMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getUnknownMapFieldMap());
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-       */
-      @java.lang.Override
-
-      public protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite getUnknownMapFieldOrDefault(
-          int key,
-          protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite defaultValue) {
-        
-        java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite> map =
-            instance.getUnknownMapFieldMap();
-        return map.containsKey(key)
-               ? map.get(key)
-               : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-       */
-      @java.lang.Override
-
-      public protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite getUnknownMapFieldOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite> map =
-            instance.getUnknownMapFieldMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-       */
-      public Builder putUnknownMapField(
-          int key,
-          protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite value) {
-        
-        value.getClass();
-        copyOnWrite();
-        instance.getMutableUnknownMapFieldMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-       */
-      public Builder putAllUnknownMapField(
-          java.util.Map<java.lang.Integer, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite> values) {
-        copyOnWrite();
-        instance.getMutableUnknownMapFieldMap().putAll(values);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestEnumMapPlusExtraLite)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "knownMapField_",
-              KnownMapFieldDefaultEntryHolder.defaultEntry,
-              protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite.internalGetVerifier(),
-              "unknownMapField_",
-              UnknownMapFieldDefaultEntryHolder.defaultEntry,
-              protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite.internalGetVerifier(),
-            };
-            java.lang.String info =
-                "\u0001\u0002\u0000\u0000ef\u0002\u0002\u0000\u0000e\u0832f\u0832";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestEnumMapPlusExtraLite)
-    private static final protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite DEFAULT_INSTANCE;
-    static {
-      TestEnumMapPlusExtraLite defaultInstance = new TestEnumMapPlusExtraLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestEnumMapPlusExtraLite.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestEnumMapPlusExtraLite> PARSER;
-
-    public static com.google.protobuf.Parser<TestEnumMapPlusExtraLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestMessageMapLiteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestMessageMapLite)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-     */
-    int getMapInt32MessageCount();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-     */
-    boolean containsMapInt32Message(
-        int key);
-    /**
-     * Use {@link #getMapInt32MessageMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite>
-    getMapInt32Message();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-     */
-    java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite>
-    getMapInt32MessageMap();
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-     */
-
-    com.google.protobuf.UnittestLite.TestAllTypesLite getMapInt32MessageOrDefault(
-        int key,
-        com.google.protobuf.UnittestLite.TestAllTypesLite defaultValue);
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-     */
-
-    com.google.protobuf.UnittestLite.TestAllTypesLite getMapInt32MessageOrThrow(
-        int key);
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestMessageMapLite}
-   */
-  public  static final class TestMessageMapLite extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestMessageMapLite, TestMessageMapLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestMessageMapLite)
-      TestMessageMapLiteOrBuilder {
-    private TestMessageMapLite() {
-    }
-    public static final int MAP_INT32_MESSAGE_FIELD_NUMBER = 1;
-    private static final class MapInt32MessageDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.INT32,
-                  0,
-                  com.google.protobuf.WireFormat.FieldType.MESSAGE,
-                  com.google.protobuf.UnittestLite.TestAllTypesLite.getDefaultInstance());
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite> mapInt32Message_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite>
-    internalGetMapInt32Message() {
-      return mapInt32Message_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite>
-    internalGetMutableMapInt32Message() {
-      if (!mapInt32Message_.isMutable()) {
-        mapInt32Message_ = mapInt32Message_.mutableCopy();
-      }
-      return mapInt32Message_;
-    }
-    @java.lang.Override
-
-    public int getMapInt32MessageCount() {
-      return internalGetMapInt32Message().size();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsMapInt32Message(
-        int key) {
-      
-      return internalGetMapInt32Message().containsKey(key);
-    }
-    /**
-     * Use {@link #getMapInt32MessageMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite> getMapInt32Message() {
-      return getMapInt32MessageMap();
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite> getMapInt32MessageMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetMapInt32Message());
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-     */
-    @java.lang.Override
-
-    public com.google.protobuf.UnittestLite.TestAllTypesLite getMapInt32MessageOrDefault(
-        int key,
-        com.google.protobuf.UnittestLite.TestAllTypesLite defaultValue) {
-      
-      java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite> map =
-          internalGetMapInt32Message();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-     */
-    @java.lang.Override
-
-    public com.google.protobuf.UnittestLite.TestAllTypesLite getMapInt32MessageOrThrow(
-        int key) {
-      
-      java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite> map =
-          internalGetMapInt32Message();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-     */
-    private java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite>
-    getMutableMapInt32MessageMap() {
-      return internalGetMutableMapInt32Message();
-    }
-
-    public static protobuf_unittest.MapLiteUnittest.TestMessageMapLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMessageMapLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMessageMapLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMessageMapLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMessageMapLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMessageMapLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMessageMapLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMessageMapLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMessageMapLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMessageMapLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMessageMapLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestMessageMapLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.MapLiteUnittest.TestMessageMapLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestMessageMapLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.MapLiteUnittest.TestMessageMapLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestMessageMapLite)
-        protobuf_unittest.MapLiteUnittest.TestMessageMapLiteOrBuilder {
-      // Construct using protobuf_unittest.MapLiteUnittest.TestMessageMapLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      @java.lang.Override
-
-      public int getMapInt32MessageCount() {
-        return instance.getMapInt32MessageMap().size();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsMapInt32Message(
-          int key) {
-        
-        return instance.getMapInt32MessageMap().containsKey(key);
-      }
-
-      public Builder clearMapInt32Message() {
-        copyOnWrite();
-        instance.getMutableMapInt32MessageMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-       */
-
-      public Builder removeMapInt32Message(
-          int key) {
-        
-        copyOnWrite();
-        instance.getMutableMapInt32MessageMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getMapInt32MessageMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite> getMapInt32Message() {
-        return getMapInt32MessageMap();
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite> getMapInt32MessageMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getMapInt32MessageMap());
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-       */
-      @java.lang.Override
-
-      public com.google.protobuf.UnittestLite.TestAllTypesLite getMapInt32MessageOrDefault(
-          int key,
-          com.google.protobuf.UnittestLite.TestAllTypesLite defaultValue) {
-        
-        java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite> map =
-            instance.getMapInt32MessageMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-       */
-      @java.lang.Override
-
-      public com.google.protobuf.UnittestLite.TestAllTypesLite getMapInt32MessageOrThrow(
-          int key) {
-        
-        java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite> map =
-            instance.getMapInt32MessageMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-       */
-      public Builder putMapInt32Message(
-          int key,
-          com.google.protobuf.UnittestLite.TestAllTypesLite value) {
-        
-        value.getClass();
-        copyOnWrite();
-        instance.getMutableMapInt32MessageMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-       */
-      public Builder putAllMapInt32Message(
-          java.util.Map<java.lang.Integer, com.google.protobuf.UnittestLite.TestAllTypesLite> values) {
-        copyOnWrite();
-        instance.getMutableMapInt32MessageMap().putAll(values);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestMessageMapLite)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.MapLiteUnittest.TestMessageMapLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "mapInt32Message_",
-              MapInt32MessageDefaultEntryHolder.defaultEntry,
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u00012";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.MapLiteUnittest.TestMessageMapLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.MapLiteUnittest.TestMessageMapLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.MapLiteUnittest.TestMessageMapLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestMessageMapLite)
-    private static final protobuf_unittest.MapLiteUnittest.TestMessageMapLite DEFAULT_INSTANCE;
-    static {
-      TestMessageMapLite defaultInstance = new TestMessageMapLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestMessageMapLite.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.MapLiteUnittest.TestMessageMapLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestMessageMapLite> PARSER;
-
-    public static com.google.protobuf.Parser<TestMessageMapLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestRequiredLiteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestRequiredLite)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>required int32 a = 1;</code>
-     * @return Whether the a field is set.
-     */
-    boolean hasA();
-    /**
-     * <code>required int32 a = 1;</code>
-     * @return The a.
-     */
-    int getA();
-
-    /**
-     * <code>required int32 b = 2;</code>
-     * @return Whether the b field is set.
-     */
-    boolean hasB();
-    /**
-     * <code>required int32 b = 2;</code>
-     * @return The b.
-     */
-    int getB();
-
-    /**
-     * <code>required int32 c = 3;</code>
-     * @return Whether the c field is set.
-     */
-    boolean hasC();
-    /**
-     * <code>required int32 c = 3;</code>
-     * @return The c.
-     */
-    int getC();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestRequiredLite}
-   */
-  public  static final class TestRequiredLite extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestRequiredLite, TestRequiredLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestRequiredLite)
-      TestRequiredLiteOrBuilder {
-    private TestRequiredLite() {
-    }
-    private int bitField0_;
-    public static final int A_FIELD_NUMBER = 1;
-    private int a_;
-    /**
-     * <code>required int32 a = 1;</code>
-     * @return Whether the a field is set.
-     */
-    @java.lang.Override
-    public boolean hasA() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>required int32 a = 1;</code>
-     * @return The a.
-     */
-    @java.lang.Override
-    public int getA() {
-      return a_;
-    }
-    /**
-     * <code>required int32 a = 1;</code>
-     * @param value The a to set.
-     */
-    private void setA(int value) {
-      bitField0_ |= 0x00000001;
-      a_ = value;
-    }
-    /**
-     * <code>required int32 a = 1;</code>
-     */
-    private void clearA() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      a_ = 0;
-    }
-
-    public static final int B_FIELD_NUMBER = 2;
-    private int b_;
-    /**
-     * <code>required int32 b = 2;</code>
-     * @return Whether the b field is set.
-     */
-    @java.lang.Override
-    public boolean hasB() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>required int32 b = 2;</code>
-     * @return The b.
-     */
-    @java.lang.Override
-    public int getB() {
-      return b_;
-    }
-    /**
-     * <code>required int32 b = 2;</code>
-     * @param value The b to set.
-     */
-    private void setB(int value) {
-      bitField0_ |= 0x00000002;
-      b_ = value;
-    }
-    /**
-     * <code>required int32 b = 2;</code>
-     */
-    private void clearB() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      b_ = 0;
-    }
-
-    public static final int C_FIELD_NUMBER = 3;
-    private int c_;
-    /**
-     * <code>required int32 c = 3;</code>
-     * @return Whether the c field is set.
-     */
-    @java.lang.Override
-    public boolean hasC() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>required int32 c = 3;</code>
-     * @return The c.
-     */
-    @java.lang.Override
-    public int getC() {
-      return c_;
-    }
-    /**
-     * <code>required int32 c = 3;</code>
-     * @param value The c to set.
-     */
-    private void setC(int value) {
-      bitField0_ |= 0x00000004;
-      c_ = value;
-    }
-    /**
-     * <code>required int32 c = 3;</code>
-     */
-    private void clearC() {
-      bitField0_ = (bitField0_ & ~0x00000004);
-      c_ = 0;
-    }
-
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.MapLiteUnittest.TestRequiredLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestRequiredLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.MapLiteUnittest.TestRequiredLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestRequiredLite)
-        protobuf_unittest.MapLiteUnittest.TestRequiredLiteOrBuilder {
-      // Construct using protobuf_unittest.MapLiteUnittest.TestRequiredLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>required int32 a = 1;</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return instance.hasA();
-      }
-      /**
-       * <code>required int32 a = 1;</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public int getA() {
-        return instance.getA();
-      }
-      /**
-       * <code>required int32 a = 1;</code>
-       * @param value The a to set.
-       * @return This builder for chaining.
-       */
-      public Builder setA(int value) {
-        copyOnWrite();
-        instance.setA(value);
-        return this;
-      }
-      /**
-       * <code>required int32 a = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearA() {
-        copyOnWrite();
-        instance.clearA();
-        return this;
-      }
-
-      /**
-       * <code>required int32 b = 2;</code>
-       * @return Whether the b field is set.
-       */
-      @java.lang.Override
-      public boolean hasB() {
-        return instance.hasB();
-      }
-      /**
-       * <code>required int32 b = 2;</code>
-       * @return The b.
-       */
-      @java.lang.Override
-      public int getB() {
-        return instance.getB();
-      }
-      /**
-       * <code>required int32 b = 2;</code>
-       * @param value The b to set.
-       * @return This builder for chaining.
-       */
-      public Builder setB(int value) {
-        copyOnWrite();
-        instance.setB(value);
-        return this;
-      }
-      /**
-       * <code>required int32 b = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearB() {
-        copyOnWrite();
-        instance.clearB();
-        return this;
-      }
-
-      /**
-       * <code>required int32 c = 3;</code>
-       * @return Whether the c field is set.
-       */
-      @java.lang.Override
-      public boolean hasC() {
-        return instance.hasC();
-      }
-      /**
-       * <code>required int32 c = 3;</code>
-       * @return The c.
-       */
-      @java.lang.Override
-      public int getC() {
-        return instance.getC();
-      }
-      /**
-       * <code>required int32 c = 3;</code>
-       * @param value The c to set.
-       * @return This builder for chaining.
-       */
-      public Builder setC(int value) {
-        copyOnWrite();
-        instance.setC(value);
-        return this;
-      }
-      /**
-       * <code>required int32 c = 3;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearC() {
-        copyOnWrite();
-        instance.clearC();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestRequiredLite)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.MapLiteUnittest.TestRequiredLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "a_",
-              "b_",
-              "c_",
-            };
-            java.lang.String info =
-                "\u0001\u0003\u0000\u0001\u0001\u0003\u0003\u0000\u0000\u0003\u0001\u1504\u0000\u0002" +
-                "\u1504\u0001\u0003\u1504\u0002";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.MapLiteUnittest.TestRequiredLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.MapLiteUnittest.TestRequiredLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.MapLiteUnittest.TestRequiredLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestRequiredLite)
-    private static final protobuf_unittest.MapLiteUnittest.TestRequiredLite DEFAULT_INSTANCE;
-    static {
-      TestRequiredLite defaultInstance = new TestRequiredLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestRequiredLite.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.MapLiteUnittest.TestRequiredLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestRequiredLite> PARSER;
-
-    public static com.google.protobuf.Parser<TestRequiredLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface ForeignMessageArenaLiteOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.ForeignMessageArenaLite)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional int32 c = 1;</code>
-     * @return Whether the c field is set.
-     */
-    boolean hasC();
-    /**
-     * <code>optional int32 c = 1;</code>
-     * @return The c.
-     */
-    int getC();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.ForeignMessageArenaLite}
-   */
-  public  static final class ForeignMessageArenaLite extends
-      com.google.protobuf.GeneratedMessageLite<
-          ForeignMessageArenaLite, ForeignMessageArenaLite.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.ForeignMessageArenaLite)
-      ForeignMessageArenaLiteOrBuilder {
-    private ForeignMessageArenaLite() {
-    }
-    private int bitField0_;
-    public static final int C_FIELD_NUMBER = 1;
-    private int c_;
-    /**
-     * <code>optional int32 c = 1;</code>
-     * @return Whether the c field is set.
-     */
-    @java.lang.Override
-    public boolean hasC() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 c = 1;</code>
-     * @return The c.
-     */
-    @java.lang.Override
-    public int getC() {
-      return c_;
-    }
-    /**
-     * <code>optional int32 c = 1;</code>
-     * @param value The c to set.
-     */
-    private void setC(int value) {
-      bitField0_ |= 0x00000001;
-      c_ = value;
-    }
-    /**
-     * <code>optional int32 c = 1;</code>
-     */
-    private void clearC() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      c_ = 0;
-    }
-
-    public static protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.ForeignMessageArenaLite}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.ForeignMessageArenaLite)
-        protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLiteOrBuilder {
-      // Construct using protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int32 c = 1;</code>
-       * @return Whether the c field is set.
-       */
-      @java.lang.Override
-      public boolean hasC() {
-        return instance.hasC();
-      }
-      /**
-       * <code>optional int32 c = 1;</code>
-       * @return The c.
-       */
-      @java.lang.Override
-      public int getC() {
-        return instance.getC();
-      }
-      /**
-       * <code>optional int32 c = 1;</code>
-       * @param value The c to set.
-       * @return This builder for chaining.
-       */
-      public Builder setC(int value) {
-        copyOnWrite();
-        instance.setC(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 c = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearC() {
-        copyOnWrite();
-        instance.clearC();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.ForeignMessageArenaLite)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "c_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1004\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.ForeignMessageArenaLite)
-    private static final protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite DEFAULT_INSTANCE;
-    static {
-      ForeignMessageArenaLite defaultInstance = new ForeignMessageArenaLite();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        ForeignMessageArenaLite.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<ForeignMessageArenaLite> PARSER;
-
-    public static com.google.protobuf.Parser<ForeignMessageArenaLite> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/MapLiteUnittestKt.kt b/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/MapLiteUnittestKt.kt
deleted file mode 100644
index e69de29..0000000
--- a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/MapLiteUnittestKt.kt
+++ /dev/null
diff --git a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestArenaMapLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestArenaMapLiteKt.kt
deleted file mode 100644
index ce04652..0000000
--- a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestArenaMapLiteKt.kt
+++ /dev/null
@@ -1,1047 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/map_lite_unittest.proto
-
-package protobuf_unittest;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testArenaMapLite(block: protobuf_unittest.TestArenaMapLiteKt.Dsl.() -> Unit): protobuf_unittest.MapLiteUnittest.TestArenaMapLite =
-  protobuf_unittest.TestArenaMapLiteKt.Dsl._create(protobuf_unittest.MapLiteUnittest.TestArenaMapLite.newBuilder()).apply { block() }._build()
-object TestArenaMapLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: protobuf_unittest.MapLiteUnittest.TestArenaMapLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: protobuf_unittest.MapLiteUnittest.TestArenaMapLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): protobuf_unittest.MapLiteUnittest.TestArenaMapLite = _builder.build()
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapInt32Int32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-     val mapInt32Int32: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapInt32Int32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapInt32Int32Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapInt32Int32Map()
-      )
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    @JvmName("putMapInt32Int32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapInt32Int32Proxy>
-      .put(key: kotlin.Int, value: kotlin.Int) {
-         _builder.putMapInt32Int32(key, value)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapInt32Int32")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapInt32Int32Proxy>
-      .set(key: kotlin.Int, value: kotlin.Int) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapInt32Int32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapInt32Int32Proxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapInt32Int32(key)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapInt32Int32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapInt32Int32Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Int>) {
-         _builder.putAllMapInt32Int32(map)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapInt32Int32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapInt32Int32Proxy>
-      .clear() {
-         _builder.clearMapInt32Int32()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapInt64Int64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-     val mapInt64Int64: com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapInt64Int64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapInt64Int64Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapInt64Int64Map()
-      )
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    @JvmName("putMapInt64Int64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapInt64Int64Proxy>
-      .put(key: kotlin.Long, value: kotlin.Long) {
-         _builder.putMapInt64Int64(key, value)
-       }
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapInt64Int64")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapInt64Int64Proxy>
-      .set(key: kotlin.Long, value: kotlin.Long) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapInt64Int64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapInt64Int64Proxy>
-      .remove(key: kotlin.Long) {
-         _builder.removeMapInt64Int64(key)
-       }
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapInt64Int64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapInt64Int64Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Long, kotlin.Long>) {
-         _builder.putAllMapInt64Int64(map)
-       }
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapInt64Int64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapInt64Int64Proxy>
-      .clear() {
-         _builder.clearMapInt64Int64()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapUint32Uint32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-     val mapUint32Uint32: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapUint32Uint32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapUint32Uint32Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapUint32Uint32Map()
-      )
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    @JvmName("putMapUint32Uint32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapUint32Uint32Proxy>
-      .put(key: kotlin.Int, value: kotlin.Int) {
-         _builder.putMapUint32Uint32(key, value)
-       }
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapUint32Uint32")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapUint32Uint32Proxy>
-      .set(key: kotlin.Int, value: kotlin.Int) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapUint32Uint32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapUint32Uint32Proxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapUint32Uint32(key)
-       }
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapUint32Uint32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapUint32Uint32Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Int>) {
-         _builder.putAllMapUint32Uint32(map)
-       }
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapUint32Uint32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapUint32Uint32Proxy>
-      .clear() {
-         _builder.clearMapUint32Uint32()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapUint64Uint64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-     val mapUint64Uint64: com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapUint64Uint64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapUint64Uint64Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapUint64Uint64Map()
-      )
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    @JvmName("putMapUint64Uint64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapUint64Uint64Proxy>
-      .put(key: kotlin.Long, value: kotlin.Long) {
-         _builder.putMapUint64Uint64(key, value)
-       }
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapUint64Uint64")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapUint64Uint64Proxy>
-      .set(key: kotlin.Long, value: kotlin.Long) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapUint64Uint64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapUint64Uint64Proxy>
-      .remove(key: kotlin.Long) {
-         _builder.removeMapUint64Uint64(key)
-       }
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapUint64Uint64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapUint64Uint64Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Long, kotlin.Long>) {
-         _builder.putAllMapUint64Uint64(map)
-       }
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapUint64Uint64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapUint64Uint64Proxy>
-      .clear() {
-         _builder.clearMapUint64Uint64()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapSint32Sint32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-     val mapSint32Sint32: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSint32Sint32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapSint32Sint32Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapSint32Sint32Map()
-      )
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    @JvmName("putMapSint32Sint32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSint32Sint32Proxy>
-      .put(key: kotlin.Int, value: kotlin.Int) {
-         _builder.putMapSint32Sint32(key, value)
-       }
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapSint32Sint32")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSint32Sint32Proxy>
-      .set(key: kotlin.Int, value: kotlin.Int) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapSint32Sint32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSint32Sint32Proxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapSint32Sint32(key)
-       }
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapSint32Sint32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSint32Sint32Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Int>) {
-         _builder.putAllMapSint32Sint32(map)
-       }
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapSint32Sint32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSint32Sint32Proxy>
-      .clear() {
-         _builder.clearMapSint32Sint32()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapSint64Sint64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-     val mapSint64Sint64: com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSint64Sint64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapSint64Sint64Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapSint64Sint64Map()
-      )
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    @JvmName("putMapSint64Sint64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSint64Sint64Proxy>
-      .put(key: kotlin.Long, value: kotlin.Long) {
-         _builder.putMapSint64Sint64(key, value)
-       }
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapSint64Sint64")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSint64Sint64Proxy>
-      .set(key: kotlin.Long, value: kotlin.Long) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapSint64Sint64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSint64Sint64Proxy>
-      .remove(key: kotlin.Long) {
-         _builder.removeMapSint64Sint64(key)
-       }
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapSint64Sint64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSint64Sint64Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Long, kotlin.Long>) {
-         _builder.putAllMapSint64Sint64(map)
-       }
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapSint64Sint64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSint64Sint64Proxy>
-      .clear() {
-         _builder.clearMapSint64Sint64()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapFixed32Fixed32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-     val mapFixed32Fixed32: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapFixed32Fixed32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapFixed32Fixed32Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapFixed32Fixed32Map()
-      )
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    @JvmName("putMapFixed32Fixed32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapFixed32Fixed32Proxy>
-      .put(key: kotlin.Int, value: kotlin.Int) {
-         _builder.putMapFixed32Fixed32(key, value)
-       }
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapFixed32Fixed32")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapFixed32Fixed32Proxy>
-      .set(key: kotlin.Int, value: kotlin.Int) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapFixed32Fixed32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapFixed32Fixed32Proxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapFixed32Fixed32(key)
-       }
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapFixed32Fixed32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapFixed32Fixed32Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Int>) {
-         _builder.putAllMapFixed32Fixed32(map)
-       }
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapFixed32Fixed32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapFixed32Fixed32Proxy>
-      .clear() {
-         _builder.clearMapFixed32Fixed32()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapFixed64Fixed64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-     val mapFixed64Fixed64: com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapFixed64Fixed64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapFixed64Fixed64Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapFixed64Fixed64Map()
-      )
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    @JvmName("putMapFixed64Fixed64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapFixed64Fixed64Proxy>
-      .put(key: kotlin.Long, value: kotlin.Long) {
-         _builder.putMapFixed64Fixed64(key, value)
-       }
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapFixed64Fixed64")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapFixed64Fixed64Proxy>
-      .set(key: kotlin.Long, value: kotlin.Long) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapFixed64Fixed64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapFixed64Fixed64Proxy>
-      .remove(key: kotlin.Long) {
-         _builder.removeMapFixed64Fixed64(key)
-       }
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapFixed64Fixed64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapFixed64Fixed64Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Long, kotlin.Long>) {
-         _builder.putAllMapFixed64Fixed64(map)
-       }
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapFixed64Fixed64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapFixed64Fixed64Proxy>
-      .clear() {
-         _builder.clearMapFixed64Fixed64()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapSfixed32Sfixed32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-     val mapSfixed32Sfixed32: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSfixed32Sfixed32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapSfixed32Sfixed32Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapSfixed32Sfixed32Map()
-      )
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    @JvmName("putMapSfixed32Sfixed32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSfixed32Sfixed32Proxy>
-      .put(key: kotlin.Int, value: kotlin.Int) {
-         _builder.putMapSfixed32Sfixed32(key, value)
-       }
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapSfixed32Sfixed32")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSfixed32Sfixed32Proxy>
-      .set(key: kotlin.Int, value: kotlin.Int) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapSfixed32Sfixed32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSfixed32Sfixed32Proxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapSfixed32Sfixed32(key)
-       }
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapSfixed32Sfixed32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSfixed32Sfixed32Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Int>) {
-         _builder.putAllMapSfixed32Sfixed32(map)
-       }
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapSfixed32Sfixed32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSfixed32Sfixed32Proxy>
-      .clear() {
-         _builder.clearMapSfixed32Sfixed32()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapSfixed64Sfixed64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-     val mapSfixed64Sfixed64: com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSfixed64Sfixed64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapSfixed64Sfixed64Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapSfixed64Sfixed64Map()
-      )
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    @JvmName("putMapSfixed64Sfixed64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSfixed64Sfixed64Proxy>
-      .put(key: kotlin.Long, value: kotlin.Long) {
-         _builder.putMapSfixed64Sfixed64(key, value)
-       }
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapSfixed64Sfixed64")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSfixed64Sfixed64Proxy>
-      .set(key: kotlin.Long, value: kotlin.Long) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapSfixed64Sfixed64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSfixed64Sfixed64Proxy>
-      .remove(key: kotlin.Long) {
-         _builder.removeMapSfixed64Sfixed64(key)
-       }
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapSfixed64Sfixed64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSfixed64Sfixed64Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Long, kotlin.Long>) {
-         _builder.putAllMapSfixed64Sfixed64(map)
-       }
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapSfixed64Sfixed64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSfixed64Sfixed64Proxy>
-      .clear() {
-         _builder.clearMapSfixed64Sfixed64()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapInt32FloatProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-     val mapInt32Float: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Float, MapInt32FloatProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapInt32FloatMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapInt32FloatMap()
-      )
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    @JvmName("putMapInt32Float")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Float, MapInt32FloatProxy>
-      .put(key: kotlin.Int, value: kotlin.Float) {
-         _builder.putMapInt32Float(key, value)
-       }
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapInt32Float")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Float, MapInt32FloatProxy>
-      .set(key: kotlin.Int, value: kotlin.Float) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapInt32Float")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Float, MapInt32FloatProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapInt32Float(key)
-       }
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapInt32Float")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Float, MapInt32FloatProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Float>) {
-         _builder.putAllMapInt32Float(map)
-       }
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapInt32Float")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Float, MapInt32FloatProxy>
-      .clear() {
-         _builder.clearMapInt32Float()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapInt32DoubleProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-     val mapInt32Double: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Double, MapInt32DoubleProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapInt32DoubleMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapInt32DoubleMap()
-      )
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    @JvmName("putMapInt32Double")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Double, MapInt32DoubleProxy>
-      .put(key: kotlin.Int, value: kotlin.Double) {
-         _builder.putMapInt32Double(key, value)
-       }
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapInt32Double")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Double, MapInt32DoubleProxy>
-      .set(key: kotlin.Int, value: kotlin.Double) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapInt32Double")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Double, MapInt32DoubleProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapInt32Double(key)
-       }
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapInt32Double")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Double, MapInt32DoubleProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Double>) {
-         _builder.putAllMapInt32Double(map)
-       }
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapInt32Double")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Double, MapInt32DoubleProxy>
-      .clear() {
-         _builder.clearMapInt32Double()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapBoolBoolProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-     val mapBoolBool: com.google.protobuf.kotlin.DslMap<kotlin.Boolean, kotlin.Boolean, MapBoolBoolProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapBoolBoolMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapBoolBoolMap()
-      )
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    @JvmName("putMapBoolBool")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Boolean, kotlin.Boolean, MapBoolBoolProxy>
-      .put(key: kotlin.Boolean, value: kotlin.Boolean) {
-         _builder.putMapBoolBool(key, value)
-       }
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapBoolBool")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Boolean, kotlin.Boolean, MapBoolBoolProxy>
-      .set(key: kotlin.Boolean, value: kotlin.Boolean) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapBoolBool")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Boolean, kotlin.Boolean, MapBoolBoolProxy>
-      .remove(key: kotlin.Boolean) {
-         _builder.removeMapBoolBool(key)
-       }
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapBoolBool")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Boolean, kotlin.Boolean, MapBoolBoolProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Boolean, kotlin.Boolean>) {
-         _builder.putAllMapBoolBool(map)
-       }
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapBoolBool")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Boolean, kotlin.Boolean, MapBoolBoolProxy>
-      .clear() {
-         _builder.clearMapBoolBool()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapStringStringProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-     val mapStringString: com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, MapStringStringProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapStringStringMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapStringStringMap()
-      )
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    @JvmName("putMapStringString")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, MapStringStringProxy>
-      .put(key: kotlin.String, value: kotlin.String) {
-         _builder.putMapStringString(key, value)
-       }
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapStringString")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, MapStringStringProxy>
-      .set(key: kotlin.String, value: kotlin.String) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapStringString")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, MapStringStringProxy>
-      .remove(key: kotlin.String) {
-         _builder.removeMapStringString(key)
-       }
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapStringString")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, MapStringStringProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.String, kotlin.String>) {
-         _builder.putAllMapStringString(map)
-       }
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapStringString")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, MapStringStringProxy>
-      .clear() {
-         _builder.clearMapStringString()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapInt32BytesProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-     val mapInt32Bytes: com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.ByteString, MapInt32BytesProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapInt32BytesMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapInt32BytesMap()
-      )
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    @JvmName("putMapInt32Bytes")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.ByteString, MapInt32BytesProxy>
-      .put(key: kotlin.Int, value: com.google.protobuf.ByteString) {
-         _builder.putMapInt32Bytes(key, value)
-       }
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapInt32Bytes")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.ByteString, MapInt32BytesProxy>
-      .set(key: kotlin.Int, value: com.google.protobuf.ByteString) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapInt32Bytes")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.ByteString, MapInt32BytesProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapInt32Bytes(key)
-       }
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapInt32Bytes")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.ByteString, MapInt32BytesProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, com.google.protobuf.ByteString>) {
-         _builder.putAllMapInt32Bytes(map)
-       }
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapInt32Bytes")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.ByteString, MapInt32BytesProxy>
-      .clear() {
-         _builder.clearMapInt32Bytes()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapInt32EnumProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-     val mapInt32Enum: com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.MapEnumLite, MapInt32EnumProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapInt32EnumMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapInt32EnumMap()
-      )
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    @JvmName("putMapInt32Enum")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.MapEnumLite, MapInt32EnumProxy>
-      .put(key: kotlin.Int, value: protobuf_unittest.MapLiteUnittest.MapEnumLite) {
-         _builder.putMapInt32Enum(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapInt32Enum")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.MapEnumLite, MapInt32EnumProxy>
-      .set(key: kotlin.Int, value: protobuf_unittest.MapLiteUnittest.MapEnumLite) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapInt32Enum")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.MapEnumLite, MapInt32EnumProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapInt32Enum(key)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapInt32Enum")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.MapEnumLite, MapInt32EnumProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, protobuf_unittest.MapLiteUnittest.MapEnumLite>) {
-         _builder.putAllMapInt32Enum(map)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapInt32Enum")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.MapEnumLite, MapInt32EnumProxy>
-      .clear() {
-         _builder.clearMapInt32Enum()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapInt32ForeignMessageProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-     */
-     val mapInt32ForeignMessage: com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite, MapInt32ForeignMessageProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapInt32ForeignMessageMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapInt32ForeignMessageMap()
-      )
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    @JvmName("putMapInt32ForeignMessage")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite, MapInt32ForeignMessageProxy>
-      .put(key: kotlin.Int, value: protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite) {
-         _builder.putMapInt32ForeignMessage(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapInt32ForeignMessage")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite, MapInt32ForeignMessageProxy>
-      .set(key: kotlin.Int, value: protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapInt32ForeignMessage")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite, MapInt32ForeignMessageProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapInt32ForeignMessage(key)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapInt32ForeignMessage")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite, MapInt32ForeignMessageProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite>) {
-         _builder.putAllMapInt32ForeignMessage(map)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageArenaLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapInt32ForeignMessage")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.ForeignMessageArenaLite, MapInt32ForeignMessageProxy>
-      .clear() {
-         _builder.clearMapInt32ForeignMessage()
-       }
-  }
-}
-inline fun protobuf_unittest.MapLiteUnittest.TestArenaMapLite.copy(block: protobuf_unittest.TestArenaMapLiteKt.Dsl.() -> Unit): protobuf_unittest.MapLiteUnittest.TestArenaMapLite =
-  protobuf_unittest.TestArenaMapLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestEnumMapLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestEnumMapLiteKt.kt
deleted file mode 100644
index f654171..0000000
--- a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestEnumMapLiteKt.kt
+++ /dev/null
@@ -1,147 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/map_lite_unittest.proto
-
-package protobuf_unittest;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testEnumMapLite(block: protobuf_unittest.TestEnumMapLiteKt.Dsl.() -> Unit): protobuf_unittest.MapLiteUnittest.TestEnumMapLite =
-  protobuf_unittest.TestEnumMapLiteKt.Dsl._create(protobuf_unittest.MapLiteUnittest.TestEnumMapLite.newBuilder()).apply { block() }._build()
-object TestEnumMapLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: protobuf_unittest.MapLiteUnittest.TestEnumMapLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: protobuf_unittest.MapLiteUnittest.TestEnumMapLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): protobuf_unittest.MapLiteUnittest.TestEnumMapLite = _builder.build()
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class KnownMapFieldProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-     */
-     val knownMapField: com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite, KnownMapFieldProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getKnownMapFieldMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getKnownMapFieldMap()
-      )
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-     */
-    @JvmName("putKnownMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite, KnownMapFieldProxy>
-      .put(key: kotlin.Int, value: protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite) {
-         _builder.putKnownMapField(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setKnownMapField")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite, KnownMapFieldProxy>
-      .set(key: kotlin.Int, value: protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeKnownMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite, KnownMapFieldProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeKnownMapField(key)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllKnownMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite, KnownMapFieldProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite>) {
-         _builder.putAllKnownMapField(map)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; known_map_field = 101;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearKnownMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite, KnownMapFieldProxy>
-      .clear() {
-         _builder.clearKnownMapField()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class UnknownMapFieldProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-     */
-     val unknownMapField: com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite, UnknownMapFieldProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getUnknownMapFieldMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getUnknownMapFieldMap()
-      )
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-     */
-    @JvmName("putUnknownMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite, UnknownMapFieldProxy>
-      .put(key: kotlin.Int, value: protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite) {
-         _builder.putUnknownMapField(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setUnknownMapField")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite, UnknownMapFieldProxy>
-      .set(key: kotlin.Int, value: protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeUnknownMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite, UnknownMapFieldProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeUnknownMapField(key)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllUnknownMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite, UnknownMapFieldProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite>) {
-         _builder.putAllUnknownMapField(map)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumLite&gt; unknown_map_field = 102;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearUnknownMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumLite, UnknownMapFieldProxy>
-      .clear() {
-         _builder.clearUnknownMapField()
-       }
-  }
-}
-inline fun protobuf_unittest.MapLiteUnittest.TestEnumMapLite.copy(block: protobuf_unittest.TestEnumMapLiteKt.Dsl.() -> Unit): protobuf_unittest.MapLiteUnittest.TestEnumMapLite =
-  protobuf_unittest.TestEnumMapLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestEnumMapPlusExtraLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestEnumMapPlusExtraLiteKt.kt
deleted file mode 100644
index fbcad09..0000000
--- a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestEnumMapPlusExtraLiteKt.kt
+++ /dev/null
@@ -1,147 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/map_lite_unittest.proto
-
-package protobuf_unittest;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testEnumMapPlusExtraLite(block: protobuf_unittest.TestEnumMapPlusExtraLiteKt.Dsl.() -> Unit): protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite =
-  protobuf_unittest.TestEnumMapPlusExtraLiteKt.Dsl._create(protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite.newBuilder()).apply { block() }._build()
-object TestEnumMapPlusExtraLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite = _builder.build()
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class KnownMapFieldProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-     */
-     val knownMapField: com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite, KnownMapFieldProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getKnownMapFieldMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getKnownMapFieldMap()
-      )
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-     */
-    @JvmName("putKnownMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite, KnownMapFieldProxy>
-      .put(key: kotlin.Int, value: protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite) {
-         _builder.putKnownMapField(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setKnownMapField")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite, KnownMapFieldProxy>
-      .set(key: kotlin.Int, value: protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeKnownMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite, KnownMapFieldProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeKnownMapField(key)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllKnownMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite, KnownMapFieldProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite>) {
-         _builder.putAllKnownMapField(map)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; known_map_field = 101;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearKnownMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite, KnownMapFieldProxy>
-      .clear() {
-         _builder.clearKnownMapField()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class UnknownMapFieldProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-     */
-     val unknownMapField: com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite, UnknownMapFieldProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getUnknownMapFieldMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getUnknownMapFieldMap()
-      )
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-     */
-    @JvmName("putUnknownMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite, UnknownMapFieldProxy>
-      .put(key: kotlin.Int, value: protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite) {
-         _builder.putUnknownMapField(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setUnknownMapField")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite, UnknownMapFieldProxy>
-      .set(key: kotlin.Int, value: protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeUnknownMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite, UnknownMapFieldProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeUnknownMapField(key)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllUnknownMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite, UnknownMapFieldProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite>) {
-         _builder.putAllUnknownMapField(map)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.Proto2MapEnumPlusExtraLite&gt; unknown_map_field = 102;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearUnknownMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.Proto2MapEnumPlusExtraLite, UnknownMapFieldProxy>
-      .clear() {
-         _builder.clearUnknownMapField()
-       }
-  }
-}
-inline fun protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite.copy(block: protobuf_unittest.TestEnumMapPlusExtraLiteKt.Dsl.() -> Unit): protobuf_unittest.MapLiteUnittest.TestEnumMapPlusExtraLite =
-  protobuf_unittest.TestEnumMapPlusExtraLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestMapLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestMapLiteKt.kt
deleted file mode 100644
index 7f0f09b..0000000
--- a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestMapLiteKt.kt
+++ /dev/null
@@ -1,1107 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/map_lite_unittest.proto
-
-package protobuf_unittest;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testMapLite(block: protobuf_unittest.TestMapLiteKt.Dsl.() -> Unit): protobuf_unittest.MapLiteUnittest.TestMapLite =
-  protobuf_unittest.TestMapLiteKt.Dsl._create(protobuf_unittest.MapLiteUnittest.TestMapLite.newBuilder()).apply { block() }._build()
-object TestMapLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: protobuf_unittest.MapLiteUnittest.TestMapLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: protobuf_unittest.MapLiteUnittest.TestMapLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): protobuf_unittest.MapLiteUnittest.TestMapLite = _builder.build()
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapInt32Int32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-     val mapInt32Int32: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapInt32Int32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapInt32Int32Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapInt32Int32Map()
-      )
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    @JvmName("putMapInt32Int32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapInt32Int32Proxy>
-      .put(key: kotlin.Int, value: kotlin.Int) {
-         _builder.putMapInt32Int32(key, value)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapInt32Int32")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapInt32Int32Proxy>
-      .set(key: kotlin.Int, value: kotlin.Int) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapInt32Int32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapInt32Int32Proxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapInt32Int32(key)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapInt32Int32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapInt32Int32Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Int>) {
-         _builder.putAllMapInt32Int32(map)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; map_int32_int32 = 1;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapInt32Int32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapInt32Int32Proxy>
-      .clear() {
-         _builder.clearMapInt32Int32()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapInt64Int64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-     val mapInt64Int64: com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapInt64Int64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapInt64Int64Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapInt64Int64Map()
-      )
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    @JvmName("putMapInt64Int64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapInt64Int64Proxy>
-      .put(key: kotlin.Long, value: kotlin.Long) {
-         _builder.putMapInt64Int64(key, value)
-       }
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapInt64Int64")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapInt64Int64Proxy>
-      .set(key: kotlin.Long, value: kotlin.Long) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapInt64Int64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapInt64Int64Proxy>
-      .remove(key: kotlin.Long) {
-         _builder.removeMapInt64Int64(key)
-       }
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapInt64Int64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapInt64Int64Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Long, kotlin.Long>) {
-         _builder.putAllMapInt64Int64(map)
-       }
-    /**
-     * <code>map&lt;int64, int64&gt; map_int64_int64 = 2;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapInt64Int64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapInt64Int64Proxy>
-      .clear() {
-         _builder.clearMapInt64Int64()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapUint32Uint32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-     val mapUint32Uint32: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapUint32Uint32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapUint32Uint32Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapUint32Uint32Map()
-      )
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    @JvmName("putMapUint32Uint32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapUint32Uint32Proxy>
-      .put(key: kotlin.Int, value: kotlin.Int) {
-         _builder.putMapUint32Uint32(key, value)
-       }
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapUint32Uint32")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapUint32Uint32Proxy>
-      .set(key: kotlin.Int, value: kotlin.Int) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapUint32Uint32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapUint32Uint32Proxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapUint32Uint32(key)
-       }
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapUint32Uint32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapUint32Uint32Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Int>) {
-         _builder.putAllMapUint32Uint32(map)
-       }
-    /**
-     * <code>map&lt;uint32, uint32&gt; map_uint32_uint32 = 3;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapUint32Uint32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapUint32Uint32Proxy>
-      .clear() {
-         _builder.clearMapUint32Uint32()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapUint64Uint64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-     val mapUint64Uint64: com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapUint64Uint64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapUint64Uint64Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapUint64Uint64Map()
-      )
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    @JvmName("putMapUint64Uint64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapUint64Uint64Proxy>
-      .put(key: kotlin.Long, value: kotlin.Long) {
-         _builder.putMapUint64Uint64(key, value)
-       }
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapUint64Uint64")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapUint64Uint64Proxy>
-      .set(key: kotlin.Long, value: kotlin.Long) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapUint64Uint64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapUint64Uint64Proxy>
-      .remove(key: kotlin.Long) {
-         _builder.removeMapUint64Uint64(key)
-       }
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapUint64Uint64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapUint64Uint64Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Long, kotlin.Long>) {
-         _builder.putAllMapUint64Uint64(map)
-       }
-    /**
-     * <code>map&lt;uint64, uint64&gt; map_uint64_uint64 = 4;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapUint64Uint64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapUint64Uint64Proxy>
-      .clear() {
-         _builder.clearMapUint64Uint64()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapSint32Sint32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-     val mapSint32Sint32: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSint32Sint32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapSint32Sint32Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapSint32Sint32Map()
-      )
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    @JvmName("putMapSint32Sint32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSint32Sint32Proxy>
-      .put(key: kotlin.Int, value: kotlin.Int) {
-         _builder.putMapSint32Sint32(key, value)
-       }
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapSint32Sint32")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSint32Sint32Proxy>
-      .set(key: kotlin.Int, value: kotlin.Int) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapSint32Sint32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSint32Sint32Proxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapSint32Sint32(key)
-       }
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapSint32Sint32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSint32Sint32Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Int>) {
-         _builder.putAllMapSint32Sint32(map)
-       }
-    /**
-     * <code>map&lt;sint32, sint32&gt; map_sint32_sint32 = 5;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapSint32Sint32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSint32Sint32Proxy>
-      .clear() {
-         _builder.clearMapSint32Sint32()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapSint64Sint64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-     val mapSint64Sint64: com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSint64Sint64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapSint64Sint64Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapSint64Sint64Map()
-      )
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    @JvmName("putMapSint64Sint64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSint64Sint64Proxy>
-      .put(key: kotlin.Long, value: kotlin.Long) {
-         _builder.putMapSint64Sint64(key, value)
-       }
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapSint64Sint64")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSint64Sint64Proxy>
-      .set(key: kotlin.Long, value: kotlin.Long) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapSint64Sint64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSint64Sint64Proxy>
-      .remove(key: kotlin.Long) {
-         _builder.removeMapSint64Sint64(key)
-       }
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapSint64Sint64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSint64Sint64Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Long, kotlin.Long>) {
-         _builder.putAllMapSint64Sint64(map)
-       }
-    /**
-     * <code>map&lt;sint64, sint64&gt; map_sint64_sint64 = 6;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapSint64Sint64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSint64Sint64Proxy>
-      .clear() {
-         _builder.clearMapSint64Sint64()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapFixed32Fixed32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-     val mapFixed32Fixed32: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapFixed32Fixed32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapFixed32Fixed32Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapFixed32Fixed32Map()
-      )
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    @JvmName("putMapFixed32Fixed32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapFixed32Fixed32Proxy>
-      .put(key: kotlin.Int, value: kotlin.Int) {
-         _builder.putMapFixed32Fixed32(key, value)
-       }
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapFixed32Fixed32")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapFixed32Fixed32Proxy>
-      .set(key: kotlin.Int, value: kotlin.Int) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapFixed32Fixed32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapFixed32Fixed32Proxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapFixed32Fixed32(key)
-       }
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapFixed32Fixed32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapFixed32Fixed32Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Int>) {
-         _builder.putAllMapFixed32Fixed32(map)
-       }
-    /**
-     * <code>map&lt;fixed32, fixed32&gt; map_fixed32_fixed32 = 7;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapFixed32Fixed32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapFixed32Fixed32Proxy>
-      .clear() {
-         _builder.clearMapFixed32Fixed32()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapFixed64Fixed64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-     val mapFixed64Fixed64: com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapFixed64Fixed64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapFixed64Fixed64Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapFixed64Fixed64Map()
-      )
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    @JvmName("putMapFixed64Fixed64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapFixed64Fixed64Proxy>
-      .put(key: kotlin.Long, value: kotlin.Long) {
-         _builder.putMapFixed64Fixed64(key, value)
-       }
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapFixed64Fixed64")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapFixed64Fixed64Proxy>
-      .set(key: kotlin.Long, value: kotlin.Long) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapFixed64Fixed64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapFixed64Fixed64Proxy>
-      .remove(key: kotlin.Long) {
-         _builder.removeMapFixed64Fixed64(key)
-       }
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapFixed64Fixed64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapFixed64Fixed64Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Long, kotlin.Long>) {
-         _builder.putAllMapFixed64Fixed64(map)
-       }
-    /**
-     * <code>map&lt;fixed64, fixed64&gt; map_fixed64_fixed64 = 8;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapFixed64Fixed64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapFixed64Fixed64Proxy>
-      .clear() {
-         _builder.clearMapFixed64Fixed64()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapSfixed32Sfixed32Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-     val mapSfixed32Sfixed32: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSfixed32Sfixed32Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapSfixed32Sfixed32Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapSfixed32Sfixed32Map()
-      )
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    @JvmName("putMapSfixed32Sfixed32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSfixed32Sfixed32Proxy>
-      .put(key: kotlin.Int, value: kotlin.Int) {
-         _builder.putMapSfixed32Sfixed32(key, value)
-       }
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapSfixed32Sfixed32")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSfixed32Sfixed32Proxy>
-      .set(key: kotlin.Int, value: kotlin.Int) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapSfixed32Sfixed32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSfixed32Sfixed32Proxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapSfixed32Sfixed32(key)
-       }
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapSfixed32Sfixed32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSfixed32Sfixed32Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Int>) {
-         _builder.putAllMapSfixed32Sfixed32(map)
-       }
-    /**
-     * <code>map&lt;sfixed32, sfixed32&gt; map_sfixed32_sfixed32 = 9;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapSfixed32Sfixed32")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, MapSfixed32Sfixed32Proxy>
-      .clear() {
-         _builder.clearMapSfixed32Sfixed32()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapSfixed64Sfixed64Proxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-     val mapSfixed64Sfixed64: com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSfixed64Sfixed64Proxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapSfixed64Sfixed64Map")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapSfixed64Sfixed64Map()
-      )
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    @JvmName("putMapSfixed64Sfixed64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSfixed64Sfixed64Proxy>
-      .put(key: kotlin.Long, value: kotlin.Long) {
-         _builder.putMapSfixed64Sfixed64(key, value)
-       }
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapSfixed64Sfixed64")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSfixed64Sfixed64Proxy>
-      .set(key: kotlin.Long, value: kotlin.Long) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapSfixed64Sfixed64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSfixed64Sfixed64Proxy>
-      .remove(key: kotlin.Long) {
-         _builder.removeMapSfixed64Sfixed64(key)
-       }
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapSfixed64Sfixed64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSfixed64Sfixed64Proxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Long, kotlin.Long>) {
-         _builder.putAllMapSfixed64Sfixed64(map)
-       }
-    /**
-     * <code>map&lt;sfixed64, sfixed64&gt; map_sfixed64_sfixed64 = 10;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapSfixed64Sfixed64")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Long, kotlin.Long, MapSfixed64Sfixed64Proxy>
-      .clear() {
-         _builder.clearMapSfixed64Sfixed64()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapInt32FloatProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-     val mapInt32Float: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Float, MapInt32FloatProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapInt32FloatMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapInt32FloatMap()
-      )
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    @JvmName("putMapInt32Float")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Float, MapInt32FloatProxy>
-      .put(key: kotlin.Int, value: kotlin.Float) {
-         _builder.putMapInt32Float(key, value)
-       }
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapInt32Float")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Float, MapInt32FloatProxy>
-      .set(key: kotlin.Int, value: kotlin.Float) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapInt32Float")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Float, MapInt32FloatProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapInt32Float(key)
-       }
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapInt32Float")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Float, MapInt32FloatProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Float>) {
-         _builder.putAllMapInt32Float(map)
-       }
-    /**
-     * <code>map&lt;int32, float&gt; map_int32_float = 11;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapInt32Float")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Float, MapInt32FloatProxy>
-      .clear() {
-         _builder.clearMapInt32Float()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapInt32DoubleProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-     val mapInt32Double: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Double, MapInt32DoubleProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapInt32DoubleMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapInt32DoubleMap()
-      )
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    @JvmName("putMapInt32Double")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Double, MapInt32DoubleProxy>
-      .put(key: kotlin.Int, value: kotlin.Double) {
-         _builder.putMapInt32Double(key, value)
-       }
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapInt32Double")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Double, MapInt32DoubleProxy>
-      .set(key: kotlin.Int, value: kotlin.Double) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapInt32Double")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Double, MapInt32DoubleProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapInt32Double(key)
-       }
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapInt32Double")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Double, MapInt32DoubleProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Double>) {
-         _builder.putAllMapInt32Double(map)
-       }
-    /**
-     * <code>map&lt;int32, double&gt; map_int32_double = 12;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapInt32Double")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Double, MapInt32DoubleProxy>
-      .clear() {
-         _builder.clearMapInt32Double()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapBoolBoolProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-     val mapBoolBool: com.google.protobuf.kotlin.DslMap<kotlin.Boolean, kotlin.Boolean, MapBoolBoolProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapBoolBoolMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapBoolBoolMap()
-      )
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    @JvmName("putMapBoolBool")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Boolean, kotlin.Boolean, MapBoolBoolProxy>
-      .put(key: kotlin.Boolean, value: kotlin.Boolean) {
-         _builder.putMapBoolBool(key, value)
-       }
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapBoolBool")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Boolean, kotlin.Boolean, MapBoolBoolProxy>
-      .set(key: kotlin.Boolean, value: kotlin.Boolean) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapBoolBool")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Boolean, kotlin.Boolean, MapBoolBoolProxy>
-      .remove(key: kotlin.Boolean) {
-         _builder.removeMapBoolBool(key)
-       }
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapBoolBool")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Boolean, kotlin.Boolean, MapBoolBoolProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Boolean, kotlin.Boolean>) {
-         _builder.putAllMapBoolBool(map)
-       }
-    /**
-     * <code>map&lt;bool, bool&gt; map_bool_bool = 13;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapBoolBool")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Boolean, kotlin.Boolean, MapBoolBoolProxy>
-      .clear() {
-         _builder.clearMapBoolBool()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapStringStringProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-     val mapStringString: com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, MapStringStringProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapStringStringMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapStringStringMap()
-      )
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    @JvmName("putMapStringString")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, MapStringStringProxy>
-      .put(key: kotlin.String, value: kotlin.String) {
-         _builder.putMapStringString(key, value)
-       }
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapStringString")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, MapStringStringProxy>
-      .set(key: kotlin.String, value: kotlin.String) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapStringString")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, MapStringStringProxy>
-      .remove(key: kotlin.String) {
-         _builder.removeMapStringString(key)
-       }
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapStringString")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, MapStringStringProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.String, kotlin.String>) {
-         _builder.putAllMapStringString(map)
-       }
-    /**
-     * <code>map&lt;string, string&gt; map_string_string = 14;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapStringString")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.String, kotlin.String, MapStringStringProxy>
-      .clear() {
-         _builder.clearMapStringString()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapInt32BytesProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-     val mapInt32Bytes: com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.ByteString, MapInt32BytesProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapInt32BytesMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapInt32BytesMap()
-      )
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    @JvmName("putMapInt32Bytes")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.ByteString, MapInt32BytesProxy>
-      .put(key: kotlin.Int, value: com.google.protobuf.ByteString) {
-         _builder.putMapInt32Bytes(key, value)
-       }
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapInt32Bytes")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.ByteString, MapInt32BytesProxy>
-      .set(key: kotlin.Int, value: com.google.protobuf.ByteString) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapInt32Bytes")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.ByteString, MapInt32BytesProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapInt32Bytes(key)
-       }
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapInt32Bytes")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.ByteString, MapInt32BytesProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, com.google.protobuf.ByteString>) {
-         _builder.putAllMapInt32Bytes(map)
-       }
-    /**
-     * <code>map&lt;int32, bytes&gt; map_int32_bytes = 15;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapInt32Bytes")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.ByteString, MapInt32BytesProxy>
-      .clear() {
-         _builder.clearMapInt32Bytes()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapInt32EnumProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-     val mapInt32Enum: com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.MapEnumLite, MapInt32EnumProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapInt32EnumMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapInt32EnumMap()
-      )
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    @JvmName("putMapInt32Enum")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.MapEnumLite, MapInt32EnumProxy>
-      .put(key: kotlin.Int, value: protobuf_unittest.MapLiteUnittest.MapEnumLite) {
-         _builder.putMapInt32Enum(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapInt32Enum")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.MapEnumLite, MapInt32EnumProxy>
-      .set(key: kotlin.Int, value: protobuf_unittest.MapLiteUnittest.MapEnumLite) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapInt32Enum")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.MapEnumLite, MapInt32EnumProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapInt32Enum(key)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapInt32Enum")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.MapEnumLite, MapInt32EnumProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, protobuf_unittest.MapLiteUnittest.MapEnumLite>) {
-         _builder.putAllMapInt32Enum(map)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.MapEnumLite&gt; map_int32_enum = 16;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapInt32Enum")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.MapEnumLite, MapInt32EnumProxy>
-      .clear() {
-         _builder.clearMapInt32Enum()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapInt32ForeignMessageProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-     */
-     val mapInt32ForeignMessage: com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.UnittestLite.ForeignMessageLite, MapInt32ForeignMessageProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapInt32ForeignMessageMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapInt32ForeignMessageMap()
-      )
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    @JvmName("putMapInt32ForeignMessage")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.UnittestLite.ForeignMessageLite, MapInt32ForeignMessageProxy>
-      .put(key: kotlin.Int, value: com.google.protobuf.UnittestLite.ForeignMessageLite) {
-         _builder.putMapInt32ForeignMessage(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapInt32ForeignMessage")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.UnittestLite.ForeignMessageLite, MapInt32ForeignMessageProxy>
-      .set(key: kotlin.Int, value: com.google.protobuf.UnittestLite.ForeignMessageLite) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapInt32ForeignMessage")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.UnittestLite.ForeignMessageLite, MapInt32ForeignMessageProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapInt32ForeignMessage(key)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapInt32ForeignMessage")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.UnittestLite.ForeignMessageLite, MapInt32ForeignMessageProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, com.google.protobuf.UnittestLite.ForeignMessageLite>) {
-         _builder.putAllMapInt32ForeignMessage(map)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.ForeignMessageLite&gt; map_int32_foreign_message = 17;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapInt32ForeignMessage")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.UnittestLite.ForeignMessageLite, MapInt32ForeignMessageProxy>
-      .clear() {
-         _builder.clearMapInt32ForeignMessage()
-       }
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class TeboringProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-     */
-     val teboring: com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, TeboringProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getTeboringMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getTeboringMap()
-      )
-    /**
-     * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-     */
-    @JvmName("putTeboring")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, TeboringProxy>
-      .put(key: kotlin.Int, value: kotlin.Int) {
-         _builder.putTeboring(key, value)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setTeboring")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, TeboringProxy>
-      .set(key: kotlin.Int, value: kotlin.Int) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeTeboring")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, TeboringProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeTeboring(key)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllTeboring")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, TeboringProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, kotlin.Int>) {
-         _builder.putAllTeboring(map)
-       }
-    /**
-     * <code>map&lt;int32, int32&gt; teboring = 18;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearTeboring")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, kotlin.Int, TeboringProxy>
-      .clear() {
-         _builder.clearTeboring()
-       }
-  }
-}
-inline fun protobuf_unittest.MapLiteUnittest.TestMapLite.copy(block: protobuf_unittest.TestMapLiteKt.Dsl.() -> Unit): protobuf_unittest.MapLiteUnittest.TestMapLite =
-  protobuf_unittest.TestMapLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestMessageMapLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestMessageMapLiteKt.kt
deleted file mode 100644
index c9e5a41..0000000
--- a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestMessageMapLiteKt.kt
+++ /dev/null
@@ -1,87 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/map_lite_unittest.proto
-
-package protobuf_unittest;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testMessageMapLite(block: protobuf_unittest.TestMessageMapLiteKt.Dsl.() -> Unit): protobuf_unittest.MapLiteUnittest.TestMessageMapLite =
-  protobuf_unittest.TestMessageMapLiteKt.Dsl._create(protobuf_unittest.MapLiteUnittest.TestMessageMapLite.newBuilder()).apply { block() }._build()
-object TestMessageMapLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: protobuf_unittest.MapLiteUnittest.TestMessageMapLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: protobuf_unittest.MapLiteUnittest.TestMessageMapLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): protobuf_unittest.MapLiteUnittest.TestMessageMapLite = _builder.build()
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapInt32MessageProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-     */
-     val mapInt32Message: com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.UnittestLite.TestAllTypesLite, MapInt32MessageProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapInt32MessageMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapInt32MessageMap()
-      )
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-     */
-    @JvmName("putMapInt32Message")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.UnittestLite.TestAllTypesLite, MapInt32MessageProxy>
-      .put(key: kotlin.Int, value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-         _builder.putMapInt32Message(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapInt32Message")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.UnittestLite.TestAllTypesLite, MapInt32MessageProxy>
-      .set(key: kotlin.Int, value: com.google.protobuf.UnittestLite.TestAllTypesLite) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapInt32Message")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.UnittestLite.TestAllTypesLite, MapInt32MessageProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapInt32Message(key)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapInt32Message")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.UnittestLite.TestAllTypesLite, MapInt32MessageProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, com.google.protobuf.UnittestLite.TestAllTypesLite>) {
-         _builder.putAllMapInt32Message(map)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestAllTypesLite&gt; map_int32_message = 1;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapInt32Message")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, com.google.protobuf.UnittestLite.TestAllTypesLite, MapInt32MessageProxy>
-      .clear() {
-         _builder.clearMapInt32Message()
-       }
-  }
-}
-inline fun protobuf_unittest.MapLiteUnittest.TestMessageMapLite.copy(block: protobuf_unittest.TestMessageMapLiteKt.Dsl.() -> Unit): protobuf_unittest.MapLiteUnittest.TestMessageMapLite =
-  protobuf_unittest.TestMessageMapLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestRequiredLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestRequiredLiteKt.kt
deleted file mode 100644
index 6f8dbfd..0000000
--- a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestRequiredLiteKt.kt
+++ /dev/null
@@ -1,99 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/map_lite_unittest.proto
-
-package protobuf_unittest;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testRequiredLite(block: protobuf_unittest.TestRequiredLiteKt.Dsl.() -> Unit): protobuf_unittest.MapLiteUnittest.TestRequiredLite =
-  protobuf_unittest.TestRequiredLiteKt.Dsl._create(protobuf_unittest.MapLiteUnittest.TestRequiredLite.newBuilder()).apply { block() }._build()
-object TestRequiredLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: protobuf_unittest.MapLiteUnittest.TestRequiredLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: protobuf_unittest.MapLiteUnittest.TestRequiredLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): protobuf_unittest.MapLiteUnittest.TestRequiredLite = _builder.build()
-
-    /**
-     * <code>required int32 a = 1;</code>
-     */
-    var a: kotlin.Int
-      @JvmName("getA")
-      get() = _builder.getA()
-      @JvmName("setA")
-      set(value) {
-        _builder.setA(value)
-      }
-    /**
-     * <code>required int32 a = 1;</code>
-     */
-    fun clearA() {
-      _builder.clearA()
-    }
-    /**
-     * <code>required int32 a = 1;</code>
-     * @return Whether the a field is set.
-     */
-    fun hasA(): kotlin.Boolean {
-      return _builder.hasA()
-    }
-
-    /**
-     * <code>required int32 b = 2;</code>
-     */
-    var b: kotlin.Int
-      @JvmName("getB")
-      get() = _builder.getB()
-      @JvmName("setB")
-      set(value) {
-        _builder.setB(value)
-      }
-    /**
-     * <code>required int32 b = 2;</code>
-     */
-    fun clearB() {
-      _builder.clearB()
-    }
-    /**
-     * <code>required int32 b = 2;</code>
-     * @return Whether the b field is set.
-     */
-    fun hasB(): kotlin.Boolean {
-      return _builder.hasB()
-    }
-
-    /**
-     * <code>required int32 c = 3;</code>
-     */
-    var c: kotlin.Int
-      @JvmName("getC")
-      get() = _builder.getC()
-      @JvmName("setC")
-      set(value) {
-        _builder.setC(value)
-      }
-    /**
-     * <code>required int32 c = 3;</code>
-     */
-    fun clearC() {
-      _builder.clearC()
-    }
-    /**
-     * <code>required int32 c = 3;</code>
-     * @return Whether the c field is set.
-     */
-    fun hasC(): kotlin.Boolean {
-      return _builder.hasC()
-    }
-  }
-}
-inline fun protobuf_unittest.MapLiteUnittest.TestRequiredLite.copy(block: protobuf_unittest.TestRequiredLiteKt.Dsl.() -> Unit): protobuf_unittest.MapLiteUnittest.TestRequiredLite =
-  protobuf_unittest.TestRequiredLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestRequiredMessageMapLiteKt.kt b/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestRequiredMessageMapLiteKt.kt
deleted file mode 100644
index dea0c47..0000000
--- a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/TestRequiredMessageMapLiteKt.kt
+++ /dev/null
@@ -1,87 +0,0 @@
-//Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/map_lite_unittest.proto
-
-package protobuf_unittest;
-
-@kotlin.jvm.JvmSynthetic
-inline fun testRequiredMessageMapLite(block: protobuf_unittest.TestRequiredMessageMapLiteKt.Dsl.() -> Unit): protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite =
-  protobuf_unittest.TestRequiredMessageMapLiteKt.Dsl._create(protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite.newBuilder()).apply { block() }._build()
-object TestRequiredMessageMapLiteKt {
-  @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-  @com.google.protobuf.kotlin.ProtoDslMarker
-  class Dsl private constructor(
-    @kotlin.jvm.JvmField private val _builder: protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite.Builder
-  ) {
-    companion object {
-      @kotlin.jvm.JvmSynthetic
-      @kotlin.PublishedApi
-      internal fun _create(builder: protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite.Builder): Dsl = Dsl(builder)
-    }
-
-    @kotlin.jvm.JvmSynthetic
-    @kotlin.PublishedApi
-    internal fun _build(): protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite = _builder.build()
-
-    /**
-     * An uninstantiable, behaviorless type to represent the field in
-     * generics.
-     */
-    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)
-    class MapFieldProxy private constructor() : com.google.protobuf.kotlin.DslProxy()
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-     */
-     val mapField: com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.TestRequiredLite, MapFieldProxy>
-      @kotlin.jvm.JvmSynthetic
-      @JvmName("getMapFieldMap")
-      get() = com.google.protobuf.kotlin.DslMap(
-        _builder.getMapFieldMap()
-      )
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-     */
-    @JvmName("putMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.TestRequiredLite, MapFieldProxy>
-      .put(key: kotlin.Int, value: protobuf_unittest.MapLiteUnittest.TestRequiredLite) {
-         _builder.putMapField(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("setMapField")
-    inline operator fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.TestRequiredLite, MapFieldProxy>
-      .set(key: kotlin.Int, value: protobuf_unittest.MapLiteUnittest.TestRequiredLite) {
-         put(key, value)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("removeMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.TestRequiredLite, MapFieldProxy>
-      .remove(key: kotlin.Int) {
-         _builder.removeMapField(key)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("putAllMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.TestRequiredLite, MapFieldProxy>
-      .putAll(map: kotlin.collections.Map<kotlin.Int, protobuf_unittest.MapLiteUnittest.TestRequiredLite>) {
-         _builder.putAllMapField(map)
-       }
-    /**
-     * <code>map&lt;int32, .protobuf_unittest.TestRequiredLite&gt; map_field = 1;</code>
-     */
-    @kotlin.jvm.JvmSynthetic
-    @JvmName("clearMapField")
-    fun com.google.protobuf.kotlin.DslMap<kotlin.Int, protobuf_unittest.MapLiteUnittest.TestRequiredLite, MapFieldProxy>
-      .clear() {
-         _builder.clearMapField()
-       }
-  }
-}
-inline fun protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite.copy(block: protobuf_unittest.TestRequiredMessageMapLiteKt.Dsl.() -> Unit): protobuf_unittest.MapLiteUnittest.TestRequiredMessageMapLite =
-  protobuf_unittest.TestRequiredMessageMapLiteKt.Dsl._create(this.toBuilder()).apply { block() }._build()
diff --git a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/UnittestProto.java b/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/UnittestProto.java
deleted file mode 100644
index 9fd117b..0000000
--- a/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/UnittestProto.java
+++ /dev/null
@@ -1,62726 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: google/protobuf/unittest.proto
-
-package protobuf_unittest;
-
-public final class UnittestProto {
-  private UnittestProto() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-    registry.add(protobuf_unittest.UnittestProto.optionalInt32Extension);
-    registry.add(protobuf_unittest.UnittestProto.optionalInt64Extension);
-    registry.add(protobuf_unittest.UnittestProto.optionalUint32Extension);
-    registry.add(protobuf_unittest.UnittestProto.optionalUint64Extension);
-    registry.add(protobuf_unittest.UnittestProto.optionalSint32Extension);
-    registry.add(protobuf_unittest.UnittestProto.optionalSint64Extension);
-    registry.add(protobuf_unittest.UnittestProto.optionalFixed32Extension);
-    registry.add(protobuf_unittest.UnittestProto.optionalFixed64Extension);
-    registry.add(protobuf_unittest.UnittestProto.optionalSfixed32Extension);
-    registry.add(protobuf_unittest.UnittestProto.optionalSfixed64Extension);
-    registry.add(protobuf_unittest.UnittestProto.optionalFloatExtension);
-    registry.add(protobuf_unittest.UnittestProto.optionalDoubleExtension);
-    registry.add(protobuf_unittest.UnittestProto.optionalBoolExtension);
-    registry.add(protobuf_unittest.UnittestProto.optionalStringExtension);
-    registry.add(protobuf_unittest.UnittestProto.optionalBytesExtension);
-    registry.add(protobuf_unittest.UnittestProto.optionalGroupExtension);
-    registry.add(protobuf_unittest.UnittestProto.optionalNestedMessageExtension);
-    registry.add(protobuf_unittest.UnittestProto.optionalForeignMessageExtension);
-    registry.add(protobuf_unittest.UnittestProto.optionalImportMessageExtension);
-    registry.add(protobuf_unittest.UnittestProto.optionalNestedEnumExtension);
-    registry.add(protobuf_unittest.UnittestProto.optionalForeignEnumExtension);
-    registry.add(protobuf_unittest.UnittestProto.optionalImportEnumExtension);
-    registry.add(protobuf_unittest.UnittestProto.optionalStringPieceExtension);
-    registry.add(protobuf_unittest.UnittestProto.optionalCordExtension);
-    registry.add(protobuf_unittest.UnittestProto.optionalPublicImportMessageExtension);
-    registry.add(protobuf_unittest.UnittestProto.optionalLazyMessageExtension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedInt32Extension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedInt64Extension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedUint32Extension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedUint64Extension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedSint32Extension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedSint64Extension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedFixed32Extension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedFixed64Extension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedSfixed32Extension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedSfixed64Extension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedFloatExtension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedDoubleExtension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedBoolExtension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedStringExtension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedBytesExtension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedGroupExtension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedNestedMessageExtension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedForeignMessageExtension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedImportMessageExtension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedNestedEnumExtension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedForeignEnumExtension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedImportEnumExtension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedStringPieceExtension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedCordExtension);
-    registry.add(protobuf_unittest.UnittestProto.repeatedLazyMessageExtension);
-    registry.add(protobuf_unittest.UnittestProto.defaultInt32Extension);
-    registry.add(protobuf_unittest.UnittestProto.defaultInt64Extension);
-    registry.add(protobuf_unittest.UnittestProto.defaultUint32Extension);
-    registry.add(protobuf_unittest.UnittestProto.defaultUint64Extension);
-    registry.add(protobuf_unittest.UnittestProto.defaultSint32Extension);
-    registry.add(protobuf_unittest.UnittestProto.defaultSint64Extension);
-    registry.add(protobuf_unittest.UnittestProto.defaultFixed32Extension);
-    registry.add(protobuf_unittest.UnittestProto.defaultFixed64Extension);
-    registry.add(protobuf_unittest.UnittestProto.defaultSfixed32Extension);
-    registry.add(protobuf_unittest.UnittestProto.defaultSfixed64Extension);
-    registry.add(protobuf_unittest.UnittestProto.defaultFloatExtension);
-    registry.add(protobuf_unittest.UnittestProto.defaultDoubleExtension);
-    registry.add(protobuf_unittest.UnittestProto.defaultBoolExtension);
-    registry.add(protobuf_unittest.UnittestProto.defaultStringExtension);
-    registry.add(protobuf_unittest.UnittestProto.defaultBytesExtension);
-    registry.add(protobuf_unittest.UnittestProto.defaultNestedEnumExtension);
-    registry.add(protobuf_unittest.UnittestProto.defaultForeignEnumExtension);
-    registry.add(protobuf_unittest.UnittestProto.defaultImportEnumExtension);
-    registry.add(protobuf_unittest.UnittestProto.defaultStringPieceExtension);
-    registry.add(protobuf_unittest.UnittestProto.defaultCordExtension);
-    registry.add(protobuf_unittest.UnittestProto.oneofUint32Extension);
-    registry.add(protobuf_unittest.UnittestProto.oneofNestedMessageExtension);
-    registry.add(protobuf_unittest.UnittestProto.oneofStringExtension);
-    registry.add(protobuf_unittest.UnittestProto.oneofBytesExtension);
-    registry.add(protobuf_unittest.UnittestProto.myExtensionString);
-    registry.add(protobuf_unittest.UnittestProto.myExtensionInt);
-    registry.add(protobuf_unittest.UnittestProto.packedInt32Extension);
-    registry.add(protobuf_unittest.UnittestProto.packedInt64Extension);
-    registry.add(protobuf_unittest.UnittestProto.packedUint32Extension);
-    registry.add(protobuf_unittest.UnittestProto.packedUint64Extension);
-    registry.add(protobuf_unittest.UnittestProto.packedSint32Extension);
-    registry.add(protobuf_unittest.UnittestProto.packedSint64Extension);
-    registry.add(protobuf_unittest.UnittestProto.packedFixed32Extension);
-    registry.add(protobuf_unittest.UnittestProto.packedFixed64Extension);
-    registry.add(protobuf_unittest.UnittestProto.packedSfixed32Extension);
-    registry.add(protobuf_unittest.UnittestProto.packedSfixed64Extension);
-    registry.add(protobuf_unittest.UnittestProto.packedFloatExtension);
-    registry.add(protobuf_unittest.UnittestProto.packedDoubleExtension);
-    registry.add(protobuf_unittest.UnittestProto.packedBoolExtension);
-    registry.add(protobuf_unittest.UnittestProto.packedEnumExtension);
-    registry.add(protobuf_unittest.UnittestProto.unpackedInt32Extension);
-    registry.add(protobuf_unittest.UnittestProto.unpackedInt64Extension);
-    registry.add(protobuf_unittest.UnittestProto.unpackedUint32Extension);
-    registry.add(protobuf_unittest.UnittestProto.unpackedUint64Extension);
-    registry.add(protobuf_unittest.UnittestProto.unpackedSint32Extension);
-    registry.add(protobuf_unittest.UnittestProto.unpackedSint64Extension);
-    registry.add(protobuf_unittest.UnittestProto.unpackedFixed32Extension);
-    registry.add(protobuf_unittest.UnittestProto.unpackedFixed64Extension);
-    registry.add(protobuf_unittest.UnittestProto.unpackedSfixed32Extension);
-    registry.add(protobuf_unittest.UnittestProto.unpackedSfixed64Extension);
-    registry.add(protobuf_unittest.UnittestProto.unpackedFloatExtension);
-    registry.add(protobuf_unittest.UnittestProto.unpackedDoubleExtension);
-    registry.add(protobuf_unittest.UnittestProto.unpackedBoolExtension);
-    registry.add(protobuf_unittest.UnittestProto.unpackedEnumExtension);
-    registry.add(protobuf_unittest.UnittestProto.testAllTypes);
-    registry.add(protobuf_unittest.UnittestProto.testExtensionInsideTableExtension);
-    registry.add(protobuf_unittest.UnittestProto.TestNestedExtension.test);
-    registry.add(protobuf_unittest.UnittestProto.TestNestedExtension.nestedStringExtension);
-    registry.add(protobuf_unittest.UnittestProto.TestNestedExtension.optionalGroupExtension);
-    registry.add(protobuf_unittest.UnittestProto.TestNestedExtension.optionalForeignEnumExtension);
-    registry.add(protobuf_unittest.UnittestProto.TestRequired.single);
-    registry.add(protobuf_unittest.UnittestProto.TestRequired.multi);
-    registry.add(protobuf_unittest.UnittestProto.TestExtensionOrderings1.testExtOrderings1);
-    registry.add(protobuf_unittest.UnittestProto.TestExtensionOrderings2.testExtOrderings2);
-    registry.add(protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3.testExtOrderings3);
-    registry.add(protobuf_unittest.UnittestProto.TestParsingMerge.optionalExt);
-    registry.add(protobuf_unittest.UnittestProto.TestParsingMerge.repeatedExt);
-    registry.add(protobuf_unittest.UnittestProto.TestExtensionRangeSerialize.barOne);
-    registry.add(protobuf_unittest.UnittestProto.TestExtensionRangeSerialize.barTwo);
-    registry.add(protobuf_unittest.UnittestProto.TestExtensionRangeSerialize.barThree);
-    registry.add(protobuf_unittest.UnittestProto.TestExtensionRangeSerialize.barFour);
-    registry.add(protobuf_unittest.UnittestProto.TestExtensionRangeSerialize.barFive);
-  }
-  /**
-   * Protobuf enum {@code protobuf_unittest.ForeignEnum}
-   */
-  public enum ForeignEnum
-      implements com.google.protobuf.Internal.EnumLite {
-    /**
-     * <code>FOREIGN_FOO = 4;</code>
-     */
-    FOREIGN_FOO(4),
-    /**
-     * <code>FOREIGN_BAR = 5;</code>
-     */
-    FOREIGN_BAR(5),
-    /**
-     * <code>FOREIGN_BAZ = 6;</code>
-     */
-    FOREIGN_BAZ(6),
-    ;
-
-    /**
-     * <code>FOREIGN_FOO = 4;</code>
-     */
-    public static final int FOREIGN_FOO_VALUE = 4;
-    /**
-     * <code>FOREIGN_BAR = 5;</code>
-     */
-    public static final int FOREIGN_BAR_VALUE = 5;
-    /**
-     * <code>FOREIGN_BAZ = 6;</code>
-     */
-    public static final int FOREIGN_BAZ_VALUE = 6;
-
-
-    @java.lang.Override
-    public final int getNumber() {
-      return value;
-    }
-
-    /**
-     * @param value The number of the enum to look for.
-     * @return The enum associated with the given number.
-     * @deprecated Use {@link #forNumber(int)} instead.
-     */
-    @java.lang.Deprecated
-    public static ForeignEnum valueOf(int value) {
-      return forNumber(value);
-    }
-
-    public static ForeignEnum forNumber(int value) {
-      switch (value) {
-        case 4: return FOREIGN_FOO;
-        case 5: return FOREIGN_BAR;
-        case 6: return FOREIGN_BAZ;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<ForeignEnum>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        ForeignEnum> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<ForeignEnum>() {
-            @java.lang.Override
-            public ForeignEnum findValueByNumber(int number) {
-              return ForeignEnum.forNumber(number);
-            }
-          };
-
-    public static com.google.protobuf.Internal.EnumVerifier 
-        internalGetVerifier() {
-      return ForeignEnumVerifier.INSTANCE;
-    }
-
-    private static final class ForeignEnumVerifier implements 
-         com.google.protobuf.Internal.EnumVerifier { 
-            static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new ForeignEnumVerifier();
-            @java.lang.Override
-            public boolean isInRange(int number) {
-              return ForeignEnum.forNumber(number) != null;
-            }
-          };
-
-    private final int value;
-
-    private ForeignEnum(int value) {
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:protobuf_unittest.ForeignEnum)
-  }
-
-  /**
-   * <pre>
-   * Test an enum that has multiple values with the same number.
-   * </pre>
-   *
-   * Protobuf enum {@code protobuf_unittest.TestEnumWithDupValue}
-   */
-  public enum TestEnumWithDupValue
-      implements com.google.protobuf.Internal.EnumLite {
-    /**
-     * <code>FOO1 = 1;</code>
-     */
-    FOO1(1),
-    /**
-     * <code>BAR1 = 2;</code>
-     */
-    BAR1(2),
-    /**
-     * <code>BAZ = 3;</code>
-     */
-    BAZ(3),
-    ;
-
-    /**
-     * <code>FOO2 = 1;</code>
-     */
-    public static final TestEnumWithDupValue FOO2 = FOO1;
-    /**
-     * <code>BAR2 = 2;</code>
-     */
-    public static final TestEnumWithDupValue BAR2 = BAR1;
-    /**
-     * <code>FOO1 = 1;</code>
-     */
-    public static final int FOO1_VALUE = 1;
-    /**
-     * <code>BAR1 = 2;</code>
-     */
-    public static final int BAR1_VALUE = 2;
-    /**
-     * <code>BAZ = 3;</code>
-     */
-    public static final int BAZ_VALUE = 3;
-    /**
-     * <code>FOO2 = 1;</code>
-     */
-    public static final int FOO2_VALUE = 1;
-    /**
-     * <code>BAR2 = 2;</code>
-     */
-    public static final int BAR2_VALUE = 2;
-
-
-    @java.lang.Override
-    public final int getNumber() {
-      return value;
-    }
-
-    /**
-     * @param value The number of the enum to look for.
-     * @return The enum associated with the given number.
-     * @deprecated Use {@link #forNumber(int)} instead.
-     */
-    @java.lang.Deprecated
-    public static TestEnumWithDupValue valueOf(int value) {
-      return forNumber(value);
-    }
-
-    public static TestEnumWithDupValue forNumber(int value) {
-      switch (value) {
-        case 1: return FOO1;
-        case 2: return BAR1;
-        case 3: return BAZ;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<TestEnumWithDupValue>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        TestEnumWithDupValue> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<TestEnumWithDupValue>() {
-            @java.lang.Override
-            public TestEnumWithDupValue findValueByNumber(int number) {
-              return TestEnumWithDupValue.forNumber(number);
-            }
-          };
-
-    public static com.google.protobuf.Internal.EnumVerifier 
-        internalGetVerifier() {
-      return TestEnumWithDupValueVerifier.INSTANCE;
-    }
-
-    private static final class TestEnumWithDupValueVerifier implements 
-         com.google.protobuf.Internal.EnumVerifier { 
-            static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new TestEnumWithDupValueVerifier();
-            @java.lang.Override
-            public boolean isInRange(int number) {
-              return TestEnumWithDupValue.forNumber(number) != null;
-            }
-          };
-
-    private final int value;
-
-    private TestEnumWithDupValue(int value) {
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:protobuf_unittest.TestEnumWithDupValue)
-  }
-
-  /**
-   * <pre>
-   * Test an enum with large, unordered values.
-   * </pre>
-   *
-   * Protobuf enum {@code protobuf_unittest.TestSparseEnum}
-   */
-  public enum TestSparseEnum
-      implements com.google.protobuf.Internal.EnumLite {
-    /**
-     * <code>SPARSE_A = 123;</code>
-     */
-    SPARSE_A(123),
-    /**
-     * <code>SPARSE_B = 62374;</code>
-     */
-    SPARSE_B(62374),
-    /**
-     * <code>SPARSE_C = 12589234;</code>
-     */
-    SPARSE_C(12589234),
-    /**
-     * <code>SPARSE_D = -15;</code>
-     */
-    SPARSE_D(-15),
-    /**
-     * <code>SPARSE_E = -53452;</code>
-     */
-    SPARSE_E(-53452),
-    /**
-     * <code>SPARSE_F = 0;</code>
-     */
-    SPARSE_F(0),
-    /**
-     * <code>SPARSE_G = 2;</code>
-     */
-    SPARSE_G(2),
-    ;
-
-    /**
-     * <code>SPARSE_A = 123;</code>
-     */
-    public static final int SPARSE_A_VALUE = 123;
-    /**
-     * <code>SPARSE_B = 62374;</code>
-     */
-    public static final int SPARSE_B_VALUE = 62374;
-    /**
-     * <code>SPARSE_C = 12589234;</code>
-     */
-    public static final int SPARSE_C_VALUE = 12589234;
-    /**
-     * <code>SPARSE_D = -15;</code>
-     */
-    public static final int SPARSE_D_VALUE = -15;
-    /**
-     * <code>SPARSE_E = -53452;</code>
-     */
-    public static final int SPARSE_E_VALUE = -53452;
-    /**
-     * <code>SPARSE_F = 0;</code>
-     */
-    public static final int SPARSE_F_VALUE = 0;
-    /**
-     * <code>SPARSE_G = 2;</code>
-     */
-    public static final int SPARSE_G_VALUE = 2;
-
-
-    @java.lang.Override
-    public final int getNumber() {
-      return value;
-    }
-
-    /**
-     * @param value The number of the enum to look for.
-     * @return The enum associated with the given number.
-     * @deprecated Use {@link #forNumber(int)} instead.
-     */
-    @java.lang.Deprecated
-    public static TestSparseEnum valueOf(int value) {
-      return forNumber(value);
-    }
-
-    public static TestSparseEnum forNumber(int value) {
-      switch (value) {
-        case 123: return SPARSE_A;
-        case 62374: return SPARSE_B;
-        case 12589234: return SPARSE_C;
-        case -15: return SPARSE_D;
-        case -53452: return SPARSE_E;
-        case 0: return SPARSE_F;
-        case 2: return SPARSE_G;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<TestSparseEnum>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        TestSparseEnum> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<TestSparseEnum>() {
-            @java.lang.Override
-            public TestSparseEnum findValueByNumber(int number) {
-              return TestSparseEnum.forNumber(number);
-            }
-          };
-
-    public static com.google.protobuf.Internal.EnumVerifier 
-        internalGetVerifier() {
-      return TestSparseEnumVerifier.INSTANCE;
-    }
-
-    private static final class TestSparseEnumVerifier implements 
-         com.google.protobuf.Internal.EnumVerifier { 
-            static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new TestSparseEnumVerifier();
-            @java.lang.Override
-            public boolean isInRange(int number) {
-              return TestSparseEnum.forNumber(number) != null;
-            }
-          };
-
-    private final int value;
-
-    private TestSparseEnum(int value) {
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:protobuf_unittest.TestSparseEnum)
-  }
-
-  /**
-   * Protobuf enum {@code protobuf_unittest.VeryLargeEnum}
-   */
-  public enum VeryLargeEnum
-      implements com.google.protobuf.Internal.EnumLite {
-    /**
-     * <code>ENUM_LABEL_DEFAULT = 0;</code>
-     */
-    ENUM_LABEL_DEFAULT(0),
-    /**
-     * <code>ENUM_LABEL_1 = 1;</code>
-     */
-    ENUM_LABEL_1(1),
-    /**
-     * <code>ENUM_LABEL_2 = 2;</code>
-     */
-    ENUM_LABEL_2(2),
-    /**
-     * <code>ENUM_LABEL_3 = 3;</code>
-     */
-    ENUM_LABEL_3(3),
-    /**
-     * <code>ENUM_LABEL_4 = 4;</code>
-     */
-    ENUM_LABEL_4(4),
-    /**
-     * <code>ENUM_LABEL_5 = 5;</code>
-     */
-    ENUM_LABEL_5(5),
-    /**
-     * <code>ENUM_LABEL_6 = 6;</code>
-     */
-    ENUM_LABEL_6(6),
-    /**
-     * <code>ENUM_LABEL_7 = 7;</code>
-     */
-    ENUM_LABEL_7(7),
-    /**
-     * <code>ENUM_LABEL_8 = 8;</code>
-     */
-    ENUM_LABEL_8(8),
-    /**
-     * <code>ENUM_LABEL_9 = 9;</code>
-     */
-    ENUM_LABEL_9(9),
-    /**
-     * <code>ENUM_LABEL_10 = 10;</code>
-     */
-    ENUM_LABEL_10(10),
-    /**
-     * <code>ENUM_LABEL_11 = 11;</code>
-     */
-    ENUM_LABEL_11(11),
-    /**
-     * <code>ENUM_LABEL_12 = 12;</code>
-     */
-    ENUM_LABEL_12(12),
-    /**
-     * <code>ENUM_LABEL_13 = 13;</code>
-     */
-    ENUM_LABEL_13(13),
-    /**
-     * <code>ENUM_LABEL_14 = 14;</code>
-     */
-    ENUM_LABEL_14(14),
-    /**
-     * <code>ENUM_LABEL_15 = 15;</code>
-     */
-    ENUM_LABEL_15(15),
-    /**
-     * <code>ENUM_LABEL_16 = 16;</code>
-     */
-    ENUM_LABEL_16(16),
-    /**
-     * <code>ENUM_LABEL_17 = 17;</code>
-     */
-    ENUM_LABEL_17(17),
-    /**
-     * <code>ENUM_LABEL_18 = 18;</code>
-     */
-    ENUM_LABEL_18(18),
-    /**
-     * <code>ENUM_LABEL_19 = 19;</code>
-     */
-    ENUM_LABEL_19(19),
-    /**
-     * <code>ENUM_LABEL_20 = 20;</code>
-     */
-    ENUM_LABEL_20(20),
-    /**
-     * <code>ENUM_LABEL_21 = 21;</code>
-     */
-    ENUM_LABEL_21(21),
-    /**
-     * <code>ENUM_LABEL_22 = 22;</code>
-     */
-    ENUM_LABEL_22(22),
-    /**
-     * <code>ENUM_LABEL_23 = 23;</code>
-     */
-    ENUM_LABEL_23(23),
-    /**
-     * <code>ENUM_LABEL_24 = 24;</code>
-     */
-    ENUM_LABEL_24(24),
-    /**
-     * <code>ENUM_LABEL_25 = 25;</code>
-     */
-    ENUM_LABEL_25(25),
-    /**
-     * <code>ENUM_LABEL_26 = 26;</code>
-     */
-    ENUM_LABEL_26(26),
-    /**
-     * <code>ENUM_LABEL_27 = 27;</code>
-     */
-    ENUM_LABEL_27(27),
-    /**
-     * <code>ENUM_LABEL_28 = 28;</code>
-     */
-    ENUM_LABEL_28(28),
-    /**
-     * <code>ENUM_LABEL_29 = 29;</code>
-     */
-    ENUM_LABEL_29(29),
-    /**
-     * <code>ENUM_LABEL_30 = 30;</code>
-     */
-    ENUM_LABEL_30(30),
-    /**
-     * <code>ENUM_LABEL_31 = 31;</code>
-     */
-    ENUM_LABEL_31(31),
-    /**
-     * <code>ENUM_LABEL_32 = 32;</code>
-     */
-    ENUM_LABEL_32(32),
-    /**
-     * <code>ENUM_LABEL_33 = 33;</code>
-     */
-    ENUM_LABEL_33(33),
-    /**
-     * <code>ENUM_LABEL_34 = 34;</code>
-     */
-    ENUM_LABEL_34(34),
-    /**
-     * <code>ENUM_LABEL_35 = 35;</code>
-     */
-    ENUM_LABEL_35(35),
-    /**
-     * <code>ENUM_LABEL_36 = 36;</code>
-     */
-    ENUM_LABEL_36(36),
-    /**
-     * <code>ENUM_LABEL_37 = 37;</code>
-     */
-    ENUM_LABEL_37(37),
-    /**
-     * <code>ENUM_LABEL_38 = 38;</code>
-     */
-    ENUM_LABEL_38(38),
-    /**
-     * <code>ENUM_LABEL_39 = 39;</code>
-     */
-    ENUM_LABEL_39(39),
-    /**
-     * <code>ENUM_LABEL_40 = 40;</code>
-     */
-    ENUM_LABEL_40(40),
-    /**
-     * <code>ENUM_LABEL_41 = 41;</code>
-     */
-    ENUM_LABEL_41(41),
-    /**
-     * <code>ENUM_LABEL_42 = 42;</code>
-     */
-    ENUM_LABEL_42(42),
-    /**
-     * <code>ENUM_LABEL_43 = 43;</code>
-     */
-    ENUM_LABEL_43(43),
-    /**
-     * <code>ENUM_LABEL_44 = 44;</code>
-     */
-    ENUM_LABEL_44(44),
-    /**
-     * <code>ENUM_LABEL_45 = 45;</code>
-     */
-    ENUM_LABEL_45(45),
-    /**
-     * <code>ENUM_LABEL_46 = 46;</code>
-     */
-    ENUM_LABEL_46(46),
-    /**
-     * <code>ENUM_LABEL_47 = 47;</code>
-     */
-    ENUM_LABEL_47(47),
-    /**
-     * <code>ENUM_LABEL_48 = 48;</code>
-     */
-    ENUM_LABEL_48(48),
-    /**
-     * <code>ENUM_LABEL_49 = 49;</code>
-     */
-    ENUM_LABEL_49(49),
-    /**
-     * <code>ENUM_LABEL_50 = 50;</code>
-     */
-    ENUM_LABEL_50(50),
-    /**
-     * <code>ENUM_LABEL_51 = 51;</code>
-     */
-    ENUM_LABEL_51(51),
-    /**
-     * <code>ENUM_LABEL_52 = 52;</code>
-     */
-    ENUM_LABEL_52(52),
-    /**
-     * <code>ENUM_LABEL_53 = 53;</code>
-     */
-    ENUM_LABEL_53(53),
-    /**
-     * <code>ENUM_LABEL_54 = 54;</code>
-     */
-    ENUM_LABEL_54(54),
-    /**
-     * <code>ENUM_LABEL_55 = 55;</code>
-     */
-    ENUM_LABEL_55(55),
-    /**
-     * <code>ENUM_LABEL_56 = 56;</code>
-     */
-    ENUM_LABEL_56(56),
-    /**
-     * <code>ENUM_LABEL_57 = 57;</code>
-     */
-    ENUM_LABEL_57(57),
-    /**
-     * <code>ENUM_LABEL_58 = 58;</code>
-     */
-    ENUM_LABEL_58(58),
-    /**
-     * <code>ENUM_LABEL_59 = 59;</code>
-     */
-    ENUM_LABEL_59(59),
-    /**
-     * <code>ENUM_LABEL_60 = 60;</code>
-     */
-    ENUM_LABEL_60(60),
-    /**
-     * <code>ENUM_LABEL_61 = 61;</code>
-     */
-    ENUM_LABEL_61(61),
-    /**
-     * <code>ENUM_LABEL_62 = 62;</code>
-     */
-    ENUM_LABEL_62(62),
-    /**
-     * <code>ENUM_LABEL_63 = 63;</code>
-     */
-    ENUM_LABEL_63(63),
-    /**
-     * <code>ENUM_LABEL_64 = 64;</code>
-     */
-    ENUM_LABEL_64(64),
-    /**
-     * <code>ENUM_LABEL_65 = 65;</code>
-     */
-    ENUM_LABEL_65(65),
-    /**
-     * <code>ENUM_LABEL_66 = 66;</code>
-     */
-    ENUM_LABEL_66(66),
-    /**
-     * <code>ENUM_LABEL_67 = 67;</code>
-     */
-    ENUM_LABEL_67(67),
-    /**
-     * <code>ENUM_LABEL_68 = 68;</code>
-     */
-    ENUM_LABEL_68(68),
-    /**
-     * <code>ENUM_LABEL_69 = 69;</code>
-     */
-    ENUM_LABEL_69(69),
-    /**
-     * <code>ENUM_LABEL_70 = 70;</code>
-     */
-    ENUM_LABEL_70(70),
-    /**
-     * <code>ENUM_LABEL_71 = 71;</code>
-     */
-    ENUM_LABEL_71(71),
-    /**
-     * <code>ENUM_LABEL_72 = 72;</code>
-     */
-    ENUM_LABEL_72(72),
-    /**
-     * <code>ENUM_LABEL_73 = 73;</code>
-     */
-    ENUM_LABEL_73(73),
-    /**
-     * <code>ENUM_LABEL_74 = 74;</code>
-     */
-    ENUM_LABEL_74(74),
-    /**
-     * <code>ENUM_LABEL_75 = 75;</code>
-     */
-    ENUM_LABEL_75(75),
-    /**
-     * <code>ENUM_LABEL_76 = 76;</code>
-     */
-    ENUM_LABEL_76(76),
-    /**
-     * <code>ENUM_LABEL_77 = 77;</code>
-     */
-    ENUM_LABEL_77(77),
-    /**
-     * <code>ENUM_LABEL_78 = 78;</code>
-     */
-    ENUM_LABEL_78(78),
-    /**
-     * <code>ENUM_LABEL_79 = 79;</code>
-     */
-    ENUM_LABEL_79(79),
-    /**
-     * <code>ENUM_LABEL_80 = 80;</code>
-     */
-    ENUM_LABEL_80(80),
-    /**
-     * <code>ENUM_LABEL_81 = 81;</code>
-     */
-    ENUM_LABEL_81(81),
-    /**
-     * <code>ENUM_LABEL_82 = 82;</code>
-     */
-    ENUM_LABEL_82(82),
-    /**
-     * <code>ENUM_LABEL_83 = 83;</code>
-     */
-    ENUM_LABEL_83(83),
-    /**
-     * <code>ENUM_LABEL_84 = 84;</code>
-     */
-    ENUM_LABEL_84(84),
-    /**
-     * <code>ENUM_LABEL_85 = 85;</code>
-     */
-    ENUM_LABEL_85(85),
-    /**
-     * <code>ENUM_LABEL_86 = 86;</code>
-     */
-    ENUM_LABEL_86(86),
-    /**
-     * <code>ENUM_LABEL_87 = 87;</code>
-     */
-    ENUM_LABEL_87(87),
-    /**
-     * <code>ENUM_LABEL_88 = 88;</code>
-     */
-    ENUM_LABEL_88(88),
-    /**
-     * <code>ENUM_LABEL_89 = 89;</code>
-     */
-    ENUM_LABEL_89(89),
-    /**
-     * <code>ENUM_LABEL_90 = 90;</code>
-     */
-    ENUM_LABEL_90(90),
-    /**
-     * <code>ENUM_LABEL_91 = 91;</code>
-     */
-    ENUM_LABEL_91(91),
-    /**
-     * <code>ENUM_LABEL_92 = 92;</code>
-     */
-    ENUM_LABEL_92(92),
-    /**
-     * <code>ENUM_LABEL_93 = 93;</code>
-     */
-    ENUM_LABEL_93(93),
-    /**
-     * <code>ENUM_LABEL_94 = 94;</code>
-     */
-    ENUM_LABEL_94(94),
-    /**
-     * <code>ENUM_LABEL_95 = 95;</code>
-     */
-    ENUM_LABEL_95(95),
-    /**
-     * <code>ENUM_LABEL_96 = 96;</code>
-     */
-    ENUM_LABEL_96(96),
-    /**
-     * <code>ENUM_LABEL_97 = 97;</code>
-     */
-    ENUM_LABEL_97(97),
-    /**
-     * <code>ENUM_LABEL_98 = 98;</code>
-     */
-    ENUM_LABEL_98(98),
-    /**
-     * <code>ENUM_LABEL_99 = 99;</code>
-     */
-    ENUM_LABEL_99(99),
-    /**
-     * <code>ENUM_LABEL_100 = 100;</code>
-     */
-    ENUM_LABEL_100(100),
-    ;
-
-    /**
-     * <code>ENUM_LABEL_DEFAULT = 0;</code>
-     */
-    public static final int ENUM_LABEL_DEFAULT_VALUE = 0;
-    /**
-     * <code>ENUM_LABEL_1 = 1;</code>
-     */
-    public static final int ENUM_LABEL_1_VALUE = 1;
-    /**
-     * <code>ENUM_LABEL_2 = 2;</code>
-     */
-    public static final int ENUM_LABEL_2_VALUE = 2;
-    /**
-     * <code>ENUM_LABEL_3 = 3;</code>
-     */
-    public static final int ENUM_LABEL_3_VALUE = 3;
-    /**
-     * <code>ENUM_LABEL_4 = 4;</code>
-     */
-    public static final int ENUM_LABEL_4_VALUE = 4;
-    /**
-     * <code>ENUM_LABEL_5 = 5;</code>
-     */
-    public static final int ENUM_LABEL_5_VALUE = 5;
-    /**
-     * <code>ENUM_LABEL_6 = 6;</code>
-     */
-    public static final int ENUM_LABEL_6_VALUE = 6;
-    /**
-     * <code>ENUM_LABEL_7 = 7;</code>
-     */
-    public static final int ENUM_LABEL_7_VALUE = 7;
-    /**
-     * <code>ENUM_LABEL_8 = 8;</code>
-     */
-    public static final int ENUM_LABEL_8_VALUE = 8;
-    /**
-     * <code>ENUM_LABEL_9 = 9;</code>
-     */
-    public static final int ENUM_LABEL_9_VALUE = 9;
-    /**
-     * <code>ENUM_LABEL_10 = 10;</code>
-     */
-    public static final int ENUM_LABEL_10_VALUE = 10;
-    /**
-     * <code>ENUM_LABEL_11 = 11;</code>
-     */
-    public static final int ENUM_LABEL_11_VALUE = 11;
-    /**
-     * <code>ENUM_LABEL_12 = 12;</code>
-     */
-    public static final int ENUM_LABEL_12_VALUE = 12;
-    /**
-     * <code>ENUM_LABEL_13 = 13;</code>
-     */
-    public static final int ENUM_LABEL_13_VALUE = 13;
-    /**
-     * <code>ENUM_LABEL_14 = 14;</code>
-     */
-    public static final int ENUM_LABEL_14_VALUE = 14;
-    /**
-     * <code>ENUM_LABEL_15 = 15;</code>
-     */
-    public static final int ENUM_LABEL_15_VALUE = 15;
-    /**
-     * <code>ENUM_LABEL_16 = 16;</code>
-     */
-    public static final int ENUM_LABEL_16_VALUE = 16;
-    /**
-     * <code>ENUM_LABEL_17 = 17;</code>
-     */
-    public static final int ENUM_LABEL_17_VALUE = 17;
-    /**
-     * <code>ENUM_LABEL_18 = 18;</code>
-     */
-    public static final int ENUM_LABEL_18_VALUE = 18;
-    /**
-     * <code>ENUM_LABEL_19 = 19;</code>
-     */
-    public static final int ENUM_LABEL_19_VALUE = 19;
-    /**
-     * <code>ENUM_LABEL_20 = 20;</code>
-     */
-    public static final int ENUM_LABEL_20_VALUE = 20;
-    /**
-     * <code>ENUM_LABEL_21 = 21;</code>
-     */
-    public static final int ENUM_LABEL_21_VALUE = 21;
-    /**
-     * <code>ENUM_LABEL_22 = 22;</code>
-     */
-    public static final int ENUM_LABEL_22_VALUE = 22;
-    /**
-     * <code>ENUM_LABEL_23 = 23;</code>
-     */
-    public static final int ENUM_LABEL_23_VALUE = 23;
-    /**
-     * <code>ENUM_LABEL_24 = 24;</code>
-     */
-    public static final int ENUM_LABEL_24_VALUE = 24;
-    /**
-     * <code>ENUM_LABEL_25 = 25;</code>
-     */
-    public static final int ENUM_LABEL_25_VALUE = 25;
-    /**
-     * <code>ENUM_LABEL_26 = 26;</code>
-     */
-    public static final int ENUM_LABEL_26_VALUE = 26;
-    /**
-     * <code>ENUM_LABEL_27 = 27;</code>
-     */
-    public static final int ENUM_LABEL_27_VALUE = 27;
-    /**
-     * <code>ENUM_LABEL_28 = 28;</code>
-     */
-    public static final int ENUM_LABEL_28_VALUE = 28;
-    /**
-     * <code>ENUM_LABEL_29 = 29;</code>
-     */
-    public static final int ENUM_LABEL_29_VALUE = 29;
-    /**
-     * <code>ENUM_LABEL_30 = 30;</code>
-     */
-    public static final int ENUM_LABEL_30_VALUE = 30;
-    /**
-     * <code>ENUM_LABEL_31 = 31;</code>
-     */
-    public static final int ENUM_LABEL_31_VALUE = 31;
-    /**
-     * <code>ENUM_LABEL_32 = 32;</code>
-     */
-    public static final int ENUM_LABEL_32_VALUE = 32;
-    /**
-     * <code>ENUM_LABEL_33 = 33;</code>
-     */
-    public static final int ENUM_LABEL_33_VALUE = 33;
-    /**
-     * <code>ENUM_LABEL_34 = 34;</code>
-     */
-    public static final int ENUM_LABEL_34_VALUE = 34;
-    /**
-     * <code>ENUM_LABEL_35 = 35;</code>
-     */
-    public static final int ENUM_LABEL_35_VALUE = 35;
-    /**
-     * <code>ENUM_LABEL_36 = 36;</code>
-     */
-    public static final int ENUM_LABEL_36_VALUE = 36;
-    /**
-     * <code>ENUM_LABEL_37 = 37;</code>
-     */
-    public static final int ENUM_LABEL_37_VALUE = 37;
-    /**
-     * <code>ENUM_LABEL_38 = 38;</code>
-     */
-    public static final int ENUM_LABEL_38_VALUE = 38;
-    /**
-     * <code>ENUM_LABEL_39 = 39;</code>
-     */
-    public static final int ENUM_LABEL_39_VALUE = 39;
-    /**
-     * <code>ENUM_LABEL_40 = 40;</code>
-     */
-    public static final int ENUM_LABEL_40_VALUE = 40;
-    /**
-     * <code>ENUM_LABEL_41 = 41;</code>
-     */
-    public static final int ENUM_LABEL_41_VALUE = 41;
-    /**
-     * <code>ENUM_LABEL_42 = 42;</code>
-     */
-    public static final int ENUM_LABEL_42_VALUE = 42;
-    /**
-     * <code>ENUM_LABEL_43 = 43;</code>
-     */
-    public static final int ENUM_LABEL_43_VALUE = 43;
-    /**
-     * <code>ENUM_LABEL_44 = 44;</code>
-     */
-    public static final int ENUM_LABEL_44_VALUE = 44;
-    /**
-     * <code>ENUM_LABEL_45 = 45;</code>
-     */
-    public static final int ENUM_LABEL_45_VALUE = 45;
-    /**
-     * <code>ENUM_LABEL_46 = 46;</code>
-     */
-    public static final int ENUM_LABEL_46_VALUE = 46;
-    /**
-     * <code>ENUM_LABEL_47 = 47;</code>
-     */
-    public static final int ENUM_LABEL_47_VALUE = 47;
-    /**
-     * <code>ENUM_LABEL_48 = 48;</code>
-     */
-    public static final int ENUM_LABEL_48_VALUE = 48;
-    /**
-     * <code>ENUM_LABEL_49 = 49;</code>
-     */
-    public static final int ENUM_LABEL_49_VALUE = 49;
-    /**
-     * <code>ENUM_LABEL_50 = 50;</code>
-     */
-    public static final int ENUM_LABEL_50_VALUE = 50;
-    /**
-     * <code>ENUM_LABEL_51 = 51;</code>
-     */
-    public static final int ENUM_LABEL_51_VALUE = 51;
-    /**
-     * <code>ENUM_LABEL_52 = 52;</code>
-     */
-    public static final int ENUM_LABEL_52_VALUE = 52;
-    /**
-     * <code>ENUM_LABEL_53 = 53;</code>
-     */
-    public static final int ENUM_LABEL_53_VALUE = 53;
-    /**
-     * <code>ENUM_LABEL_54 = 54;</code>
-     */
-    public static final int ENUM_LABEL_54_VALUE = 54;
-    /**
-     * <code>ENUM_LABEL_55 = 55;</code>
-     */
-    public static final int ENUM_LABEL_55_VALUE = 55;
-    /**
-     * <code>ENUM_LABEL_56 = 56;</code>
-     */
-    public static final int ENUM_LABEL_56_VALUE = 56;
-    /**
-     * <code>ENUM_LABEL_57 = 57;</code>
-     */
-    public static final int ENUM_LABEL_57_VALUE = 57;
-    /**
-     * <code>ENUM_LABEL_58 = 58;</code>
-     */
-    public static final int ENUM_LABEL_58_VALUE = 58;
-    /**
-     * <code>ENUM_LABEL_59 = 59;</code>
-     */
-    public static final int ENUM_LABEL_59_VALUE = 59;
-    /**
-     * <code>ENUM_LABEL_60 = 60;</code>
-     */
-    public static final int ENUM_LABEL_60_VALUE = 60;
-    /**
-     * <code>ENUM_LABEL_61 = 61;</code>
-     */
-    public static final int ENUM_LABEL_61_VALUE = 61;
-    /**
-     * <code>ENUM_LABEL_62 = 62;</code>
-     */
-    public static final int ENUM_LABEL_62_VALUE = 62;
-    /**
-     * <code>ENUM_LABEL_63 = 63;</code>
-     */
-    public static final int ENUM_LABEL_63_VALUE = 63;
-    /**
-     * <code>ENUM_LABEL_64 = 64;</code>
-     */
-    public static final int ENUM_LABEL_64_VALUE = 64;
-    /**
-     * <code>ENUM_LABEL_65 = 65;</code>
-     */
-    public static final int ENUM_LABEL_65_VALUE = 65;
-    /**
-     * <code>ENUM_LABEL_66 = 66;</code>
-     */
-    public static final int ENUM_LABEL_66_VALUE = 66;
-    /**
-     * <code>ENUM_LABEL_67 = 67;</code>
-     */
-    public static final int ENUM_LABEL_67_VALUE = 67;
-    /**
-     * <code>ENUM_LABEL_68 = 68;</code>
-     */
-    public static final int ENUM_LABEL_68_VALUE = 68;
-    /**
-     * <code>ENUM_LABEL_69 = 69;</code>
-     */
-    public static final int ENUM_LABEL_69_VALUE = 69;
-    /**
-     * <code>ENUM_LABEL_70 = 70;</code>
-     */
-    public static final int ENUM_LABEL_70_VALUE = 70;
-    /**
-     * <code>ENUM_LABEL_71 = 71;</code>
-     */
-    public static final int ENUM_LABEL_71_VALUE = 71;
-    /**
-     * <code>ENUM_LABEL_72 = 72;</code>
-     */
-    public static final int ENUM_LABEL_72_VALUE = 72;
-    /**
-     * <code>ENUM_LABEL_73 = 73;</code>
-     */
-    public static final int ENUM_LABEL_73_VALUE = 73;
-    /**
-     * <code>ENUM_LABEL_74 = 74;</code>
-     */
-    public static final int ENUM_LABEL_74_VALUE = 74;
-    /**
-     * <code>ENUM_LABEL_75 = 75;</code>
-     */
-    public static final int ENUM_LABEL_75_VALUE = 75;
-    /**
-     * <code>ENUM_LABEL_76 = 76;</code>
-     */
-    public static final int ENUM_LABEL_76_VALUE = 76;
-    /**
-     * <code>ENUM_LABEL_77 = 77;</code>
-     */
-    public static final int ENUM_LABEL_77_VALUE = 77;
-    /**
-     * <code>ENUM_LABEL_78 = 78;</code>
-     */
-    public static final int ENUM_LABEL_78_VALUE = 78;
-    /**
-     * <code>ENUM_LABEL_79 = 79;</code>
-     */
-    public static final int ENUM_LABEL_79_VALUE = 79;
-    /**
-     * <code>ENUM_LABEL_80 = 80;</code>
-     */
-    public static final int ENUM_LABEL_80_VALUE = 80;
-    /**
-     * <code>ENUM_LABEL_81 = 81;</code>
-     */
-    public static final int ENUM_LABEL_81_VALUE = 81;
-    /**
-     * <code>ENUM_LABEL_82 = 82;</code>
-     */
-    public static final int ENUM_LABEL_82_VALUE = 82;
-    /**
-     * <code>ENUM_LABEL_83 = 83;</code>
-     */
-    public static final int ENUM_LABEL_83_VALUE = 83;
-    /**
-     * <code>ENUM_LABEL_84 = 84;</code>
-     */
-    public static final int ENUM_LABEL_84_VALUE = 84;
-    /**
-     * <code>ENUM_LABEL_85 = 85;</code>
-     */
-    public static final int ENUM_LABEL_85_VALUE = 85;
-    /**
-     * <code>ENUM_LABEL_86 = 86;</code>
-     */
-    public static final int ENUM_LABEL_86_VALUE = 86;
-    /**
-     * <code>ENUM_LABEL_87 = 87;</code>
-     */
-    public static final int ENUM_LABEL_87_VALUE = 87;
-    /**
-     * <code>ENUM_LABEL_88 = 88;</code>
-     */
-    public static final int ENUM_LABEL_88_VALUE = 88;
-    /**
-     * <code>ENUM_LABEL_89 = 89;</code>
-     */
-    public static final int ENUM_LABEL_89_VALUE = 89;
-    /**
-     * <code>ENUM_LABEL_90 = 90;</code>
-     */
-    public static final int ENUM_LABEL_90_VALUE = 90;
-    /**
-     * <code>ENUM_LABEL_91 = 91;</code>
-     */
-    public static final int ENUM_LABEL_91_VALUE = 91;
-    /**
-     * <code>ENUM_LABEL_92 = 92;</code>
-     */
-    public static final int ENUM_LABEL_92_VALUE = 92;
-    /**
-     * <code>ENUM_LABEL_93 = 93;</code>
-     */
-    public static final int ENUM_LABEL_93_VALUE = 93;
-    /**
-     * <code>ENUM_LABEL_94 = 94;</code>
-     */
-    public static final int ENUM_LABEL_94_VALUE = 94;
-    /**
-     * <code>ENUM_LABEL_95 = 95;</code>
-     */
-    public static final int ENUM_LABEL_95_VALUE = 95;
-    /**
-     * <code>ENUM_LABEL_96 = 96;</code>
-     */
-    public static final int ENUM_LABEL_96_VALUE = 96;
-    /**
-     * <code>ENUM_LABEL_97 = 97;</code>
-     */
-    public static final int ENUM_LABEL_97_VALUE = 97;
-    /**
-     * <code>ENUM_LABEL_98 = 98;</code>
-     */
-    public static final int ENUM_LABEL_98_VALUE = 98;
-    /**
-     * <code>ENUM_LABEL_99 = 99;</code>
-     */
-    public static final int ENUM_LABEL_99_VALUE = 99;
-    /**
-     * <code>ENUM_LABEL_100 = 100;</code>
-     */
-    public static final int ENUM_LABEL_100_VALUE = 100;
-
-
-    @java.lang.Override
-    public final int getNumber() {
-      return value;
-    }
-
-    /**
-     * @param value The number of the enum to look for.
-     * @return The enum associated with the given number.
-     * @deprecated Use {@link #forNumber(int)} instead.
-     */
-    @java.lang.Deprecated
-    public static VeryLargeEnum valueOf(int value) {
-      return forNumber(value);
-    }
-
-    public static VeryLargeEnum forNumber(int value) {
-      switch (value) {
-        case 0: return ENUM_LABEL_DEFAULT;
-        case 1: return ENUM_LABEL_1;
-        case 2: return ENUM_LABEL_2;
-        case 3: return ENUM_LABEL_3;
-        case 4: return ENUM_LABEL_4;
-        case 5: return ENUM_LABEL_5;
-        case 6: return ENUM_LABEL_6;
-        case 7: return ENUM_LABEL_7;
-        case 8: return ENUM_LABEL_8;
-        case 9: return ENUM_LABEL_9;
-        case 10: return ENUM_LABEL_10;
-        case 11: return ENUM_LABEL_11;
-        case 12: return ENUM_LABEL_12;
-        case 13: return ENUM_LABEL_13;
-        case 14: return ENUM_LABEL_14;
-        case 15: return ENUM_LABEL_15;
-        case 16: return ENUM_LABEL_16;
-        case 17: return ENUM_LABEL_17;
-        case 18: return ENUM_LABEL_18;
-        case 19: return ENUM_LABEL_19;
-        case 20: return ENUM_LABEL_20;
-        case 21: return ENUM_LABEL_21;
-        case 22: return ENUM_LABEL_22;
-        case 23: return ENUM_LABEL_23;
-        case 24: return ENUM_LABEL_24;
-        case 25: return ENUM_LABEL_25;
-        case 26: return ENUM_LABEL_26;
-        case 27: return ENUM_LABEL_27;
-        case 28: return ENUM_LABEL_28;
-        case 29: return ENUM_LABEL_29;
-        case 30: return ENUM_LABEL_30;
-        case 31: return ENUM_LABEL_31;
-        case 32: return ENUM_LABEL_32;
-        case 33: return ENUM_LABEL_33;
-        case 34: return ENUM_LABEL_34;
-        case 35: return ENUM_LABEL_35;
-        case 36: return ENUM_LABEL_36;
-        case 37: return ENUM_LABEL_37;
-        case 38: return ENUM_LABEL_38;
-        case 39: return ENUM_LABEL_39;
-        case 40: return ENUM_LABEL_40;
-        case 41: return ENUM_LABEL_41;
-        case 42: return ENUM_LABEL_42;
-        case 43: return ENUM_LABEL_43;
-        case 44: return ENUM_LABEL_44;
-        case 45: return ENUM_LABEL_45;
-        case 46: return ENUM_LABEL_46;
-        case 47: return ENUM_LABEL_47;
-        case 48: return ENUM_LABEL_48;
-        case 49: return ENUM_LABEL_49;
-        case 50: return ENUM_LABEL_50;
-        case 51: return ENUM_LABEL_51;
-        case 52: return ENUM_LABEL_52;
-        case 53: return ENUM_LABEL_53;
-        case 54: return ENUM_LABEL_54;
-        case 55: return ENUM_LABEL_55;
-        case 56: return ENUM_LABEL_56;
-        case 57: return ENUM_LABEL_57;
-        case 58: return ENUM_LABEL_58;
-        case 59: return ENUM_LABEL_59;
-        case 60: return ENUM_LABEL_60;
-        case 61: return ENUM_LABEL_61;
-        case 62: return ENUM_LABEL_62;
-        case 63: return ENUM_LABEL_63;
-        case 64: return ENUM_LABEL_64;
-        case 65: return ENUM_LABEL_65;
-        case 66: return ENUM_LABEL_66;
-        case 67: return ENUM_LABEL_67;
-        case 68: return ENUM_LABEL_68;
-        case 69: return ENUM_LABEL_69;
-        case 70: return ENUM_LABEL_70;
-        case 71: return ENUM_LABEL_71;
-        case 72: return ENUM_LABEL_72;
-        case 73: return ENUM_LABEL_73;
-        case 74: return ENUM_LABEL_74;
-        case 75: return ENUM_LABEL_75;
-        case 76: return ENUM_LABEL_76;
-        case 77: return ENUM_LABEL_77;
-        case 78: return ENUM_LABEL_78;
-        case 79: return ENUM_LABEL_79;
-        case 80: return ENUM_LABEL_80;
-        case 81: return ENUM_LABEL_81;
-        case 82: return ENUM_LABEL_82;
-        case 83: return ENUM_LABEL_83;
-        case 84: return ENUM_LABEL_84;
-        case 85: return ENUM_LABEL_85;
-        case 86: return ENUM_LABEL_86;
-        case 87: return ENUM_LABEL_87;
-        case 88: return ENUM_LABEL_88;
-        case 89: return ENUM_LABEL_89;
-        case 90: return ENUM_LABEL_90;
-        case 91: return ENUM_LABEL_91;
-        case 92: return ENUM_LABEL_92;
-        case 93: return ENUM_LABEL_93;
-        case 94: return ENUM_LABEL_94;
-        case 95: return ENUM_LABEL_95;
-        case 96: return ENUM_LABEL_96;
-        case 97: return ENUM_LABEL_97;
-        case 98: return ENUM_LABEL_98;
-        case 99: return ENUM_LABEL_99;
-        case 100: return ENUM_LABEL_100;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<VeryLargeEnum>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        VeryLargeEnum> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<VeryLargeEnum>() {
-            @java.lang.Override
-            public VeryLargeEnum findValueByNumber(int number) {
-              return VeryLargeEnum.forNumber(number);
-            }
-          };
-
-    public static com.google.protobuf.Internal.EnumVerifier 
-        internalGetVerifier() {
-      return VeryLargeEnumVerifier.INSTANCE;
-    }
-
-    private static final class VeryLargeEnumVerifier implements 
-         com.google.protobuf.Internal.EnumVerifier { 
-            static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new VeryLargeEnumVerifier();
-            @java.lang.Override
-            public boolean isInRange(int number) {
-              return VeryLargeEnum.forNumber(number) != null;
-            }
-          };
-
-    private final int value;
-
-    private VeryLargeEnum(int value) {
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:protobuf_unittest.VeryLargeEnum)
-  }
-
-  public interface TestAllTypesOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestAllTypes)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>optional int32 optional_int32 = 1;</code>
-     * @return Whether the optionalInt32 field is set.
-     */
-    boolean hasOptionalInt32();
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>optional int32 optional_int32 = 1;</code>
-     * @return The optionalInt32.
-     */
-    int getOptionalInt32();
-
-    /**
-     * <code>optional int64 optional_int64 = 2;</code>
-     * @return Whether the optionalInt64 field is set.
-     */
-    boolean hasOptionalInt64();
-    /**
-     * <code>optional int64 optional_int64 = 2;</code>
-     * @return The optionalInt64.
-     */
-    long getOptionalInt64();
-
-    /**
-     * <code>optional uint32 optional_uint32 = 3;</code>
-     * @return Whether the optionalUint32 field is set.
-     */
-    boolean hasOptionalUint32();
-    /**
-     * <code>optional uint32 optional_uint32 = 3;</code>
-     * @return The optionalUint32.
-     */
-    int getOptionalUint32();
-
-    /**
-     * <code>optional uint64 optional_uint64 = 4;</code>
-     * @return Whether the optionalUint64 field is set.
-     */
-    boolean hasOptionalUint64();
-    /**
-     * <code>optional uint64 optional_uint64 = 4;</code>
-     * @return The optionalUint64.
-     */
-    long getOptionalUint64();
-
-    /**
-     * <code>optional sint32 optional_sint32 = 5;</code>
-     * @return Whether the optionalSint32 field is set.
-     */
-    boolean hasOptionalSint32();
-    /**
-     * <code>optional sint32 optional_sint32 = 5;</code>
-     * @return The optionalSint32.
-     */
-    int getOptionalSint32();
-
-    /**
-     * <code>optional sint64 optional_sint64 = 6;</code>
-     * @return Whether the optionalSint64 field is set.
-     */
-    boolean hasOptionalSint64();
-    /**
-     * <code>optional sint64 optional_sint64 = 6;</code>
-     * @return The optionalSint64.
-     */
-    long getOptionalSint64();
-
-    /**
-     * <code>optional fixed32 optional_fixed32 = 7;</code>
-     * @return Whether the optionalFixed32 field is set.
-     */
-    boolean hasOptionalFixed32();
-    /**
-     * <code>optional fixed32 optional_fixed32 = 7;</code>
-     * @return The optionalFixed32.
-     */
-    int getOptionalFixed32();
-
-    /**
-     * <code>optional fixed64 optional_fixed64 = 8;</code>
-     * @return Whether the optionalFixed64 field is set.
-     */
-    boolean hasOptionalFixed64();
-    /**
-     * <code>optional fixed64 optional_fixed64 = 8;</code>
-     * @return The optionalFixed64.
-     */
-    long getOptionalFixed64();
-
-    /**
-     * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-     * @return Whether the optionalSfixed32 field is set.
-     */
-    boolean hasOptionalSfixed32();
-    /**
-     * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-     * @return The optionalSfixed32.
-     */
-    int getOptionalSfixed32();
-
-    /**
-     * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-     * @return Whether the optionalSfixed64 field is set.
-     */
-    boolean hasOptionalSfixed64();
-    /**
-     * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-     * @return The optionalSfixed64.
-     */
-    long getOptionalSfixed64();
-
-    /**
-     * <code>optional float optional_float = 11;</code>
-     * @return Whether the optionalFloat field is set.
-     */
-    boolean hasOptionalFloat();
-    /**
-     * <code>optional float optional_float = 11;</code>
-     * @return The optionalFloat.
-     */
-    float getOptionalFloat();
-
-    /**
-     * <code>optional double optional_double = 12;</code>
-     * @return Whether the optionalDouble field is set.
-     */
-    boolean hasOptionalDouble();
-    /**
-     * <code>optional double optional_double = 12;</code>
-     * @return The optionalDouble.
-     */
-    double getOptionalDouble();
-
-    /**
-     * <code>optional bool optional_bool = 13;</code>
-     * @return Whether the optionalBool field is set.
-     */
-    boolean hasOptionalBool();
-    /**
-     * <code>optional bool optional_bool = 13;</code>
-     * @return The optionalBool.
-     */
-    boolean getOptionalBool();
-
-    /**
-     * <code>optional string optional_string = 14;</code>
-     * @return Whether the optionalString field is set.
-     */
-    boolean hasOptionalString();
-    /**
-     * <code>optional string optional_string = 14;</code>
-     * @return The optionalString.
-     */
-    java.lang.String getOptionalString();
-    /**
-     * <code>optional string optional_string = 14;</code>
-     * @return The bytes for optionalString.
-     */
-    com.google.protobuf.ByteString
-        getOptionalStringBytes();
-
-    /**
-     * <code>optional bytes optional_bytes = 15;</code>
-     * @return Whether the optionalBytes field is set.
-     */
-    boolean hasOptionalBytes();
-    /**
-     * <code>optional bytes optional_bytes = 15;</code>
-     * @return The optionalBytes.
-     */
-    com.google.protobuf.ByteString getOptionalBytes();
-
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     * @return Whether the optionalgroup field is set.
-     */
-    boolean hasOptionalGroup();
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     * @return The optionalgroup.
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup getOptionalGroup();
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-     * @return Whether the optionalNestedMessage field is set.
-     */
-    boolean hasOptionalNestedMessage();
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-     * @return The optionalNestedMessage.
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage getOptionalNestedMessage();
-
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage optional_foreign_message = 19;</code>
-     * @return Whether the optionalForeignMessage field is set.
-     */
-    boolean hasOptionalForeignMessage();
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage optional_foreign_message = 19;</code>
-     * @return The optionalForeignMessage.
-     */
-    protobuf_unittest.UnittestProto.ForeignMessage getOptionalForeignMessage();
-
-    /**
-     * <code>optional .protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-     * @return Whether the optionalImportMessage field is set.
-     */
-    boolean hasOptionalImportMessage();
-    /**
-     * <code>optional .protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-     * @return The optionalImportMessage.
-     */
-    com.google.protobuf.test.UnittestImport.ImportMessage getOptionalImportMessage();
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-     * @return Whether the optionalNestedEnum field is set.
-     */
-    boolean hasOptionalNestedEnum();
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-     * @return The optionalNestedEnum.
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum getOptionalNestedEnum();
-
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     * @return Whether the optionalForeignEnum field is set.
-     */
-    boolean hasOptionalForeignEnum();
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     * @return The optionalForeignEnum.
-     */
-    protobuf_unittest.UnittestProto.ForeignEnum getOptionalForeignEnum();
-
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnum optional_import_enum = 23;</code>
-     * @return Whether the optionalImportEnum field is set.
-     */
-    boolean hasOptionalImportEnum();
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnum optional_import_enum = 23;</code>
-     * @return The optionalImportEnum.
-     */
-    com.google.protobuf.test.UnittestImport.ImportEnum getOptionalImportEnum();
-
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @return Whether the optionalStringPiece field is set.
-     */
-    boolean hasOptionalStringPiece();
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @return The optionalStringPiece.
-     */
-    java.lang.String getOptionalStringPiece();
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @return The bytes for optionalStringPiece.
-     */
-    com.google.protobuf.ByteString
-        getOptionalStringPieceBytes();
-
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     * @return Whether the optionalCord field is set.
-     */
-    boolean hasOptionalCord();
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     * @return The optionalCord.
-     */
-    java.lang.String getOptionalCord();
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     * @return The bytes for optionalCord.
-     */
-    com.google.protobuf.ByteString
-        getOptionalCordBytes();
-
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>optional .protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-     * @return Whether the optionalPublicImportMessage field is set.
-     */
-    boolean hasOptionalPublicImportMessage();
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>optional .protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-     * @return The optionalPublicImportMessage.
-     */
-    com.google.protobuf.test.UnittestImportPublic.PublicImportMessage getOptionalPublicImportMessage();
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     * @return Whether the optionalLazyMessage field is set.
-     */
-    boolean hasOptionalLazyMessage();
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     * @return The optionalLazyMessage.
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage getOptionalLazyMessage();
-
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @return A list containing the repeatedInt32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedInt32List();
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @return The count of repeatedInt32.
-     */
-    int getRepeatedInt32Count();
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt32 at the given index.
-     */
-    int getRepeatedInt32(int index);
-
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @return A list containing the repeatedInt64.
-     */
-    java.util.List<java.lang.Long> getRepeatedInt64List();
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @return The count of repeatedInt64.
-     */
-    int getRepeatedInt64Count();
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt64 at the given index.
-     */
-    long getRepeatedInt64(int index);
-
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @return A list containing the repeatedUint32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedUint32List();
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @return The count of repeatedUint32.
-     */
-    int getRepeatedUint32Count();
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedUint32 at the given index.
-     */
-    int getRepeatedUint32(int index);
-
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @return A list containing the repeatedUint64.
-     */
-    java.util.List<java.lang.Long> getRepeatedUint64List();
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @return The count of repeatedUint64.
-     */
-    int getRepeatedUint64Count();
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedUint64 at the given index.
-     */
-    long getRepeatedUint64(int index);
-
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @return A list containing the repeatedSint32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedSint32List();
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @return The count of repeatedSint32.
-     */
-    int getRepeatedSint32Count();
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSint32 at the given index.
-     */
-    int getRepeatedSint32(int index);
-
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @return A list containing the repeatedSint64.
-     */
-    java.util.List<java.lang.Long> getRepeatedSint64List();
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @return The count of repeatedSint64.
-     */
-    int getRepeatedSint64Count();
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSint64 at the given index.
-     */
-    long getRepeatedSint64(int index);
-
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @return A list containing the repeatedFixed32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedFixed32List();
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @return The count of repeatedFixed32.
-     */
-    int getRepeatedFixed32Count();
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed32 at the given index.
-     */
-    int getRepeatedFixed32(int index);
-
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @return A list containing the repeatedFixed64.
-     */
-    java.util.List<java.lang.Long> getRepeatedFixed64List();
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @return The count of repeatedFixed64.
-     */
-    int getRepeatedFixed64Count();
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed64 at the given index.
-     */
-    long getRepeatedFixed64(int index);
-
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @return A list containing the repeatedSfixed32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedSfixed32List();
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @return The count of repeatedSfixed32.
-     */
-    int getRepeatedSfixed32Count();
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSfixed32 at the given index.
-     */
-    int getRepeatedSfixed32(int index);
-
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @return A list containing the repeatedSfixed64.
-     */
-    java.util.List<java.lang.Long> getRepeatedSfixed64List();
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @return The count of repeatedSfixed64.
-     */
-    int getRepeatedSfixed64Count();
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSfixed64 at the given index.
-     */
-    long getRepeatedSfixed64(int index);
-
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @return A list containing the repeatedFloat.
-     */
-    java.util.List<java.lang.Float> getRepeatedFloatList();
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @return The count of repeatedFloat.
-     */
-    int getRepeatedFloatCount();
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFloat at the given index.
-     */
-    float getRepeatedFloat(int index);
-
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @return A list containing the repeatedDouble.
-     */
-    java.util.List<java.lang.Double> getRepeatedDoubleList();
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @return The count of repeatedDouble.
-     */
-    int getRepeatedDoubleCount();
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedDouble at the given index.
-     */
-    double getRepeatedDouble(int index);
-
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @return A list containing the repeatedBool.
-     */
-    java.util.List<java.lang.Boolean> getRepeatedBoolList();
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @return The count of repeatedBool.
-     */
-    int getRepeatedBoolCount();
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedBool at the given index.
-     */
-    boolean getRepeatedBool(int index);
-
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @return A list containing the repeatedString.
-     */
-    java.util.List<java.lang.String>
-        getRepeatedStringList();
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @return The count of repeatedString.
-     */
-    int getRepeatedStringCount();
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedString at the given index.
-     */
-    java.lang.String getRepeatedString(int index);
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedString at the given index.
-     */
-    com.google.protobuf.ByteString
-        getRepeatedStringBytes(int index);
-
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @return A list containing the repeatedBytes.
-     */
-    java.util.List<com.google.protobuf.ByteString> getRepeatedBytesList();
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @return The count of repeatedBytes.
-     */
-    int getRepeatedBytesCount();
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedBytes at the given index.
-     */
-    com.google.protobuf.ByteString getRepeatedBytes(int index);
-
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    java.util.List<protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup> 
-        getRepeatedGroupList();
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup getRepeatedGroup(int index);
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    int getRepeatedGroupCount();
-
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    java.util.List<protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage> 
-        getRepeatedNestedMessageList();
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage getRepeatedNestedMessage(int index);
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    int getRepeatedNestedMessageCount();
-
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    java.util.List<protobuf_unittest.UnittestProto.ForeignMessage> 
-        getRepeatedForeignMessageList();
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    protobuf_unittest.UnittestProto.ForeignMessage getRepeatedForeignMessage(int index);
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    int getRepeatedForeignMessageCount();
-
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    java.util.List<com.google.protobuf.test.UnittestImport.ImportMessage> 
-        getRepeatedImportMessageList();
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    com.google.protobuf.test.UnittestImport.ImportMessage getRepeatedImportMessage(int index);
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    int getRepeatedImportMessageCount();
-
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @return A list containing the repeatedNestedEnum.
-     */
-    java.util.List<protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum> getRepeatedNestedEnumList();
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @return The count of repeatedNestedEnum.
-     */
-    int getRepeatedNestedEnumCount();
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedNestedEnum at the given index.
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum getRepeatedNestedEnum(int index);
-
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @return A list containing the repeatedForeignEnum.
-     */
-    java.util.List<protobuf_unittest.UnittestProto.ForeignEnum> getRepeatedForeignEnumList();
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @return The count of repeatedForeignEnum.
-     */
-    int getRepeatedForeignEnumCount();
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedForeignEnum at the given index.
-     */
-    protobuf_unittest.UnittestProto.ForeignEnum getRepeatedForeignEnum(int index);
-
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnum repeated_import_enum = 53;</code>
-     * @return A list containing the repeatedImportEnum.
-     */
-    java.util.List<com.google.protobuf.test.UnittestImport.ImportEnum> getRepeatedImportEnumList();
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnum repeated_import_enum = 53;</code>
-     * @return The count of repeatedImportEnum.
-     */
-    int getRepeatedImportEnumCount();
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnum repeated_import_enum = 53;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedImportEnum at the given index.
-     */
-    com.google.protobuf.test.UnittestImport.ImportEnum getRepeatedImportEnum(int index);
-
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @return A list containing the repeatedStringPiece.
-     */
-    java.util.List<java.lang.String>
-        getRepeatedStringPieceList();
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @return The count of repeatedStringPiece.
-     */
-    int getRepeatedStringPieceCount();
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedStringPiece at the given index.
-     */
-    java.lang.String getRepeatedStringPiece(int index);
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedStringPiece at the given index.
-     */
-    com.google.protobuf.ByteString
-        getRepeatedStringPieceBytes(int index);
-
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @return A list containing the repeatedCord.
-     */
-    java.util.List<java.lang.String>
-        getRepeatedCordList();
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @return The count of repeatedCord.
-     */
-    int getRepeatedCordCount();
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedCord at the given index.
-     */
-    java.lang.String getRepeatedCord(int index);
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedCord at the given index.
-     */
-    com.google.protobuf.ByteString
-        getRepeatedCordBytes(int index);
-
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    java.util.List<protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage> 
-        getRepeatedLazyMessageList();
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage getRepeatedLazyMessage(int index);
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    int getRepeatedLazyMessageCount();
-
-    /**
-     * <pre>
-     * Singular with defaults
-     * </pre>
-     *
-     * <code>optional int32 default_int32 = 61 [default = 41];</code>
-     * @return Whether the defaultInt32 field is set.
-     */
-    boolean hasDefaultInt32();
-    /**
-     * <pre>
-     * Singular with defaults
-     * </pre>
-     *
-     * <code>optional int32 default_int32 = 61 [default = 41];</code>
-     * @return The defaultInt32.
-     */
-    int getDefaultInt32();
-
-    /**
-     * <code>optional int64 default_int64 = 62 [default = 42];</code>
-     * @return Whether the defaultInt64 field is set.
-     */
-    boolean hasDefaultInt64();
-    /**
-     * <code>optional int64 default_int64 = 62 [default = 42];</code>
-     * @return The defaultInt64.
-     */
-    long getDefaultInt64();
-
-    /**
-     * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-     * @return Whether the defaultUint32 field is set.
-     */
-    boolean hasDefaultUint32();
-    /**
-     * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-     * @return The defaultUint32.
-     */
-    int getDefaultUint32();
-
-    /**
-     * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-     * @return Whether the defaultUint64 field is set.
-     */
-    boolean hasDefaultUint64();
-    /**
-     * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-     * @return The defaultUint64.
-     */
-    long getDefaultUint64();
-
-    /**
-     * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-     * @return Whether the defaultSint32 field is set.
-     */
-    boolean hasDefaultSint32();
-    /**
-     * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-     * @return The defaultSint32.
-     */
-    int getDefaultSint32();
-
-    /**
-     * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-     * @return Whether the defaultSint64 field is set.
-     */
-    boolean hasDefaultSint64();
-    /**
-     * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-     * @return The defaultSint64.
-     */
-    long getDefaultSint64();
-
-    /**
-     * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-     * @return Whether the defaultFixed32 field is set.
-     */
-    boolean hasDefaultFixed32();
-    /**
-     * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-     * @return The defaultFixed32.
-     */
-    int getDefaultFixed32();
-
-    /**
-     * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-     * @return Whether the defaultFixed64 field is set.
-     */
-    boolean hasDefaultFixed64();
-    /**
-     * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-     * @return The defaultFixed64.
-     */
-    long getDefaultFixed64();
-
-    /**
-     * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-     * @return Whether the defaultSfixed32 field is set.
-     */
-    boolean hasDefaultSfixed32();
-    /**
-     * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-     * @return The defaultSfixed32.
-     */
-    int getDefaultSfixed32();
-
-    /**
-     * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-     * @return Whether the defaultSfixed64 field is set.
-     */
-    boolean hasDefaultSfixed64();
-    /**
-     * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-     * @return The defaultSfixed64.
-     */
-    long getDefaultSfixed64();
-
-    /**
-     * <code>optional float default_float = 71 [default = 51.5];</code>
-     * @return Whether the defaultFloat field is set.
-     */
-    boolean hasDefaultFloat();
-    /**
-     * <code>optional float default_float = 71 [default = 51.5];</code>
-     * @return The defaultFloat.
-     */
-    float getDefaultFloat();
-
-    /**
-     * <code>optional double default_double = 72 [default = 52000];</code>
-     * @return Whether the defaultDouble field is set.
-     */
-    boolean hasDefaultDouble();
-    /**
-     * <code>optional double default_double = 72 [default = 52000];</code>
-     * @return The defaultDouble.
-     */
-    double getDefaultDouble();
-
-    /**
-     * <code>optional bool default_bool = 73 [default = true];</code>
-     * @return Whether the defaultBool field is set.
-     */
-    boolean hasDefaultBool();
-    /**
-     * <code>optional bool default_bool = 73 [default = true];</code>
-     * @return The defaultBool.
-     */
-    boolean getDefaultBool();
-
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     * @return Whether the defaultString field is set.
-     */
-    boolean hasDefaultString();
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     * @return The defaultString.
-     */
-    java.lang.String getDefaultString();
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     * @return The bytes for defaultString.
-     */
-    com.google.protobuf.ByteString
-        getDefaultStringBytes();
-
-    /**
-     * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-     * @return Whether the defaultBytes field is set.
-     */
-    boolean hasDefaultBytes();
-    /**
-     * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-     * @return The defaultBytes.
-     */
-    com.google.protobuf.ByteString getDefaultBytes();
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-     * @return Whether the defaultNestedEnum field is set.
-     */
-    boolean hasDefaultNestedEnum();
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-     * @return The defaultNestedEnum.
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum getDefaultNestedEnum();
-
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR];</code>
-     * @return Whether the defaultForeignEnum field is set.
-     */
-    boolean hasDefaultForeignEnum();
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR];</code>
-     * @return The defaultForeignEnum.
-     */
-    protobuf_unittest.UnittestProto.ForeignEnum getDefaultForeignEnum();
-
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnum default_import_enum = 83 [default = IMPORT_BAR];</code>
-     * @return Whether the defaultImportEnum field is set.
-     */
-    boolean hasDefaultImportEnum();
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnum default_import_enum = 83 [default = IMPORT_BAR];</code>
-     * @return The defaultImportEnum.
-     */
-    com.google.protobuf.test.UnittestImport.ImportEnum getDefaultImportEnum();
-
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     * @return Whether the defaultStringPiece field is set.
-     */
-    boolean hasDefaultStringPiece();
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     * @return The defaultStringPiece.
-     */
-    java.lang.String getDefaultStringPiece();
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     * @return The bytes for defaultStringPiece.
-     */
-    com.google.protobuf.ByteString
-        getDefaultStringPieceBytes();
-
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     * @return Whether the defaultCord field is set.
-     */
-    boolean hasDefaultCord();
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     * @return The defaultCord.
-     */
-    java.lang.String getDefaultCord();
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     * @return The bytes for defaultCord.
-     */
-    com.google.protobuf.ByteString
-        getDefaultCordBytes();
-
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     * @return Whether the oneofUint32 field is set.
-     */
-    boolean hasOneofUint32();
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     * @return The oneofUint32.
-     */
-    int getOneofUint32();
-
-    /**
-     * <code>.protobuf_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-     * @return Whether the oneofNestedMessage field is set.
-     */
-    boolean hasOneofNestedMessage();
-    /**
-     * <code>.protobuf_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-     * @return The oneofNestedMessage.
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage getOneofNestedMessage();
-
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return Whether the oneofString field is set.
-     */
-    boolean hasOneofString();
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return The oneofString.
-     */
-    java.lang.String getOneofString();
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return The bytes for oneofString.
-     */
-    com.google.protobuf.ByteString
-        getOneofStringBytes();
-
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     * @return Whether the oneofBytes field is set.
-     */
-    boolean hasOneofBytes();
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     * @return The oneofBytes.
-     */
-    com.google.protobuf.ByteString getOneofBytes();
-
-    public protobuf_unittest.UnittestProto.TestAllTypes.OneofFieldCase getOneofFieldCase();
-  }
-  /**
-   * <pre>
-   * This proto includes every type of field in both singular and repeated
-   * forms.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestAllTypes}
-   */
-  public  static final class TestAllTypes extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestAllTypes, TestAllTypes.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestAllTypes)
-      TestAllTypesOrBuilder {
-    private TestAllTypes() {
-      optionalString_ = "";
-      optionalBytes_ = com.google.protobuf.ByteString.EMPTY;
-      optionalNestedEnum_ = 1;
-      optionalForeignEnum_ = 4;
-      optionalImportEnum_ = 7;
-      optionalStringPiece_ = "";
-      optionalCord_ = "";
-      repeatedInt32_ = emptyIntList();
-      repeatedInt64_ = emptyLongList();
-      repeatedUint32_ = emptyIntList();
-      repeatedUint64_ = emptyLongList();
-      repeatedSint32_ = emptyIntList();
-      repeatedSint64_ = emptyLongList();
-      repeatedFixed32_ = emptyIntList();
-      repeatedFixed64_ = emptyLongList();
-      repeatedSfixed32_ = emptyIntList();
-      repeatedSfixed64_ = emptyLongList();
-      repeatedFloat_ = emptyFloatList();
-      repeatedDouble_ = emptyDoubleList();
-      repeatedBool_ = emptyBooleanList();
-      repeatedString_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      repeatedBytes_ = emptyProtobufList();
-      repeatedGroup_ = emptyProtobufList();
-      repeatedNestedMessage_ = emptyProtobufList();
-      repeatedForeignMessage_ = emptyProtobufList();
-      repeatedImportMessage_ = emptyProtobufList();
-      repeatedNestedEnum_ = emptyIntList();
-      repeatedForeignEnum_ = emptyIntList();
-      repeatedImportEnum_ = emptyIntList();
-      repeatedStringPiece_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      repeatedCord_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      repeatedLazyMessage_ = emptyProtobufList();
-      defaultInt32_ = 41;
-      defaultInt64_ = 42L;
-      defaultUint32_ = 43;
-      defaultUint64_ = 44L;
-      defaultSint32_ = -45;
-      defaultSint64_ = 46L;
-      defaultFixed32_ = 47;
-      defaultFixed64_ = 48L;
-      defaultSfixed32_ = 49;
-      defaultSfixed64_ = -50L;
-      defaultFloat_ = 51.5F;
-      defaultDouble_ = 52000D;
-      defaultBool_ = true;
-      defaultString_ = "hello";
-      defaultBytes_ = DEFAULTBYTES_DEFAULT_VALUE;
-      defaultNestedEnum_ = 2;
-      defaultForeignEnum_ = 5;
-      defaultImportEnum_ = 8;
-      defaultStringPiece_ = "abc";
-      defaultCord_ = "123";
-    }
-    /**
-     * Protobuf enum {@code protobuf_unittest.TestAllTypes.NestedEnum}
-     */
-    public enum NestedEnum
-        implements com.google.protobuf.Internal.EnumLite {
-      /**
-       * <code>FOO = 1;</code>
-       */
-      FOO(1),
-      /**
-       * <code>BAR = 2;</code>
-       */
-      BAR(2),
-      /**
-       * <code>BAZ = 3;</code>
-       */
-      BAZ(3),
-      /**
-       * <pre>
-       * Intentionally negative.
-       * </pre>
-       *
-       * <code>NEG = -1;</code>
-       */
-      NEG(-1),
-      ;
-
-      /**
-       * <code>FOO = 1;</code>
-       */
-      public static final int FOO_VALUE = 1;
-      /**
-       * <code>BAR = 2;</code>
-       */
-      public static final int BAR_VALUE = 2;
-      /**
-       * <code>BAZ = 3;</code>
-       */
-      public static final int BAZ_VALUE = 3;
-      /**
-       * <pre>
-       * Intentionally negative.
-       * </pre>
-       *
-       * <code>NEG = -1;</code>
-       */
-      public static final int NEG_VALUE = -1;
-
-
-      @java.lang.Override
-      public final int getNumber() {
-        return value;
-      }
-
-      /**
-       * @param value The number of the enum to look for.
-       * @return The enum associated with the given number.
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static NestedEnum valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static NestedEnum forNumber(int value) {
-        switch (value) {
-          case 1: return FOO;
-          case 2: return BAR;
-          case 3: return BAZ;
-          case -1: return NEG;
-          default: return null;
-        }
-      }
-
-      public static com.google.protobuf.Internal.EnumLiteMap<NestedEnum>
-          internalGetValueMap() {
-        return internalValueMap;
-      }
-      private static final com.google.protobuf.Internal.EnumLiteMap<
-          NestedEnum> internalValueMap =
-            new com.google.protobuf.Internal.EnumLiteMap<NestedEnum>() {
-              @java.lang.Override
-              public NestedEnum findValueByNumber(int number) {
-                return NestedEnum.forNumber(number);
-              }
-            };
-
-      public static com.google.protobuf.Internal.EnumVerifier 
-          internalGetVerifier() {
-        return NestedEnumVerifier.INSTANCE;
-      }
-
-      private static final class NestedEnumVerifier implements 
-           com.google.protobuf.Internal.EnumVerifier { 
-              static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new NestedEnumVerifier();
-              @java.lang.Override
-              public boolean isInRange(int number) {
-                return NestedEnum.forNumber(number) != null;
-              }
-            };
-
-      private final int value;
-
-      private NestedEnum(int value) {
-        this.value = value;
-      }
-
-      // @@protoc_insertion_point(enum_scope:protobuf_unittest.TestAllTypes.NestedEnum)
-    }
-
-    public interface NestedMessageOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestAllTypes.NestedMessage)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <pre>
-       * The field name "b" fails to compile in proto1 because it conflicts with
-       * a local variable named "b" in one of the generated methods.  Doh.
-       * This file needs to compile in proto1 to test backwards-compatibility.
-       * </pre>
-       *
-       * <code>optional int32 bb = 1;</code>
-       * @return Whether the bb field is set.
-       */
-      boolean hasBb();
-      /**
-       * <pre>
-       * The field name "b" fails to compile in proto1 because it conflicts with
-       * a local variable named "b" in one of the generated methods.  Doh.
-       * This file needs to compile in proto1 to test backwards-compatibility.
-       * </pre>
-       *
-       * <code>optional int32 bb = 1;</code>
-       * @return The bb.
-       */
-      int getBb();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestAllTypes.NestedMessage}
-     */
-    public  static final class NestedMessage extends
-        com.google.protobuf.GeneratedMessageLite<
-            NestedMessage, NestedMessage.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestAllTypes.NestedMessage)
-        NestedMessageOrBuilder {
-      private NestedMessage() {
-      }
-      private int bitField0_;
-      public static final int BB_FIELD_NUMBER = 1;
-      private int bb_;
-      /**
-       * <pre>
-       * The field name "b" fails to compile in proto1 because it conflicts with
-       * a local variable named "b" in one of the generated methods.  Doh.
-       * This file needs to compile in proto1 to test backwards-compatibility.
-       * </pre>
-       *
-       * <code>optional int32 bb = 1;</code>
-       * @return Whether the bb field is set.
-       */
-      @java.lang.Override
-      public boolean hasBb() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <pre>
-       * The field name "b" fails to compile in proto1 because it conflicts with
-       * a local variable named "b" in one of the generated methods.  Doh.
-       * This file needs to compile in proto1 to test backwards-compatibility.
-       * </pre>
-       *
-       * <code>optional int32 bb = 1;</code>
-       * @return The bb.
-       */
-      @java.lang.Override
-      public int getBb() {
-        return bb_;
-      }
-      /**
-       * <pre>
-       * The field name "b" fails to compile in proto1 because it conflicts with
-       * a local variable named "b" in one of the generated methods.  Doh.
-       * This file needs to compile in proto1 to test backwards-compatibility.
-       * </pre>
-       *
-       * <code>optional int32 bb = 1;</code>
-       * @param value The bb to set.
-       */
-      private void setBb(int value) {
-        bitField0_ |= 0x00000001;
-        bb_ = value;
-      }
-      /**
-       * <pre>
-       * The field name "b" fails to compile in proto1 because it conflicts with
-       * a local variable named "b" in one of the generated methods.  Doh.
-       * This file needs to compile in proto1 to test backwards-compatibility.
-       * </pre>
-       *
-       * <code>optional int32 bb = 1;</code>
-       */
-      private void clearBb() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        bb_ = 0;
-      }
-
-      public static protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestAllTypes.NestedMessage}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestAllTypes.NestedMessage)
-          protobuf_unittest.UnittestProto.TestAllTypes.NestedMessageOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <pre>
-         * The field name "b" fails to compile in proto1 because it conflicts with
-         * a local variable named "b" in one of the generated methods.  Doh.
-         * This file needs to compile in proto1 to test backwards-compatibility.
-         * </pre>
-         *
-         * <code>optional int32 bb = 1;</code>
-         * @return Whether the bb field is set.
-         */
-        @java.lang.Override
-        public boolean hasBb() {
-          return instance.hasBb();
-        }
-        /**
-         * <pre>
-         * The field name "b" fails to compile in proto1 because it conflicts with
-         * a local variable named "b" in one of the generated methods.  Doh.
-         * This file needs to compile in proto1 to test backwards-compatibility.
-         * </pre>
-         *
-         * <code>optional int32 bb = 1;</code>
-         * @return The bb.
-         */
-        @java.lang.Override
-        public int getBb() {
-          return instance.getBb();
-        }
-        /**
-         * <pre>
-         * The field name "b" fails to compile in proto1 because it conflicts with
-         * a local variable named "b" in one of the generated methods.  Doh.
-         * This file needs to compile in proto1 to test backwards-compatibility.
-         * </pre>
-         *
-         * <code>optional int32 bb = 1;</code>
-         * @param value The bb to set.
-         * @return This builder for chaining.
-         */
-        public Builder setBb(int value) {
-          copyOnWrite();
-          instance.setBb(value);
-          return this;
-        }
-        /**
-         * <pre>
-         * The field name "b" fails to compile in proto1 because it conflicts with
-         * a local variable named "b" in one of the generated methods.  Doh.
-         * This file needs to compile in proto1 to test backwards-compatibility.
-         * </pre>
-         *
-         * <code>optional int32 bb = 1;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearBb() {
-          copyOnWrite();
-          instance.clearBb();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestAllTypes.NestedMessage)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "bb_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1004\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestAllTypes.NestedMessage)
-      private static final protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage DEFAULT_INSTANCE;
-      static {
-        NestedMessage defaultInstance = new NestedMessage();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          NestedMessage.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<NestedMessage> PARSER;
-
-      public static com.google.protobuf.Parser<NestedMessage> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    public interface OptionalGroupOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestAllTypes.OptionalGroup)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return Whether the a field is set.
-       */
-      boolean hasA();
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return The a.
-       */
-      int getA();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestAllTypes.OptionalGroup}
-     */
-    public  static final class OptionalGroup extends
-        com.google.protobuf.GeneratedMessageLite<
-            OptionalGroup, OptionalGroup.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestAllTypes.OptionalGroup)
-        OptionalGroupOrBuilder {
-      private OptionalGroup() {
-      }
-      private int bitField0_;
-      public static final int A_FIELD_NUMBER = 17;
-      private int a_;
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public int getA() {
-        return a_;
-      }
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @param value The a to set.
-       */
-      private void setA(int value) {
-        bitField0_ |= 0x00000001;
-        a_ = value;
-      }
-      /**
-       * <code>optional int32 a = 17;</code>
-       */
-      private void clearA() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        a_ = 0;
-      }
-
-      public static protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestAllTypes.OptionalGroup}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestAllTypes.OptionalGroup)
-          protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroupOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int32 a = 17;</code>
-         * @return Whether the a field is set.
-         */
-        @java.lang.Override
-        public boolean hasA() {
-          return instance.hasA();
-        }
-        /**
-         * <code>optional int32 a = 17;</code>
-         * @return The a.
-         */
-        @java.lang.Override
-        public int getA() {
-          return instance.getA();
-        }
-        /**
-         * <code>optional int32 a = 17;</code>
-         * @param value The a to set.
-         * @return This builder for chaining.
-         */
-        public Builder setA(int value) {
-          copyOnWrite();
-          instance.setA(value);
-          return this;
-        }
-        /**
-         * <code>optional int32 a = 17;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearA() {
-          copyOnWrite();
-          instance.clearA();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestAllTypes.OptionalGroup)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "a_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\u0011\u0011\u0001\u0000\u0000\u0000\u0011\u1004\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestAllTypes.OptionalGroup)
-      private static final protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup DEFAULT_INSTANCE;
-      static {
-        OptionalGroup defaultInstance = new OptionalGroup();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          OptionalGroup.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<OptionalGroup> PARSER;
-
-      public static com.google.protobuf.Parser<OptionalGroup> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    public interface RepeatedGroupOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestAllTypes.RepeatedGroup)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int32 a = 47;</code>
-       * @return Whether the a field is set.
-       */
-      boolean hasA();
-      /**
-       * <code>optional int32 a = 47;</code>
-       * @return The a.
-       */
-      int getA();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestAllTypes.RepeatedGroup}
-     */
-    public  static final class RepeatedGroup extends
-        com.google.protobuf.GeneratedMessageLite<
-            RepeatedGroup, RepeatedGroup.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestAllTypes.RepeatedGroup)
-        RepeatedGroupOrBuilder {
-      private RepeatedGroup() {
-      }
-      private int bitField0_;
-      public static final int A_FIELD_NUMBER = 47;
-      private int a_;
-      /**
-       * <code>optional int32 a = 47;</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int32 a = 47;</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public int getA() {
-        return a_;
-      }
-      /**
-       * <code>optional int32 a = 47;</code>
-       * @param value The a to set.
-       */
-      private void setA(int value) {
-        bitField0_ |= 0x00000001;
-        a_ = value;
-      }
-      /**
-       * <code>optional int32 a = 47;</code>
-       */
-      private void clearA() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        a_ = 0;
-      }
-
-      public static protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestAllTypes.RepeatedGroup}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestAllTypes.RepeatedGroup)
-          protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroupOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int32 a = 47;</code>
-         * @return Whether the a field is set.
-         */
-        @java.lang.Override
-        public boolean hasA() {
-          return instance.hasA();
-        }
-        /**
-         * <code>optional int32 a = 47;</code>
-         * @return The a.
-         */
-        @java.lang.Override
-        public int getA() {
-          return instance.getA();
-        }
-        /**
-         * <code>optional int32 a = 47;</code>
-         * @param value The a to set.
-         * @return This builder for chaining.
-         */
-        public Builder setA(int value) {
-          copyOnWrite();
-          instance.setA(value);
-          return this;
-        }
-        /**
-         * <code>optional int32 a = 47;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearA() {
-          copyOnWrite();
-          instance.clearA();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestAllTypes.RepeatedGroup)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "a_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001//\u0001\u0000\u0000\u0000/\u1004\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestAllTypes.RepeatedGroup)
-      private static final protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup DEFAULT_INSTANCE;
-      static {
-        RepeatedGroup defaultInstance = new RepeatedGroup();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          RepeatedGroup.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<RepeatedGroup> PARSER;
-
-      public static com.google.protobuf.Parser<RepeatedGroup> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int bitField0_;
-    private int bitField1_;
-    private int oneofFieldCase_ = 0;
-    private java.lang.Object oneofField_;
-    public enum OneofFieldCase {
-      ONEOF_UINT32(111),
-      ONEOF_NESTED_MESSAGE(112),
-      ONEOF_STRING(113),
-      ONEOF_BYTES(114),
-      ONEOFFIELD_NOT_SET(0);
-      private final int value;
-      private OneofFieldCase(int value) {
-        this.value = value;
-      }
-      /**
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static OneofFieldCase valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static OneofFieldCase forNumber(int value) {
-        switch (value) {
-          case 111: return ONEOF_UINT32;
-          case 112: return ONEOF_NESTED_MESSAGE;
-          case 113: return ONEOF_STRING;
-          case 114: return ONEOF_BYTES;
-          case 0: return ONEOFFIELD_NOT_SET;
-          default: return null;
-        }
-      }
-      public int getNumber() {
-        return this.value;
-      }
-    };
-
-    @java.lang.Override
-    public OneofFieldCase
-    getOneofFieldCase() {
-      return OneofFieldCase.forNumber(
-          oneofFieldCase_);
-    }
-
-    private void clearOneofField() {
-      oneofFieldCase_ = 0;
-      oneofField_ = null;
-    }
-
-    public static final int OPTIONAL_INT32_FIELD_NUMBER = 1;
-    private int optionalInt32_;
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>optional int32 optional_int32 = 1;</code>
-     * @return Whether the optionalInt32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalInt32() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>optional int32 optional_int32 = 1;</code>
-     * @return The optionalInt32.
-     */
-    @java.lang.Override
-    public int getOptionalInt32() {
-      return optionalInt32_;
-    }
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>optional int32 optional_int32 = 1;</code>
-     * @param value The optionalInt32 to set.
-     */
-    private void setOptionalInt32(int value) {
-      bitField0_ |= 0x00000001;
-      optionalInt32_ = value;
-    }
-    /**
-     * <pre>
-     * Singular
-     * </pre>
-     *
-     * <code>optional int32 optional_int32 = 1;</code>
-     */
-    private void clearOptionalInt32() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      optionalInt32_ = 0;
-    }
-
-    public static final int OPTIONAL_INT64_FIELD_NUMBER = 2;
-    private long optionalInt64_;
-    /**
-     * <code>optional int64 optional_int64 = 2;</code>
-     * @return Whether the optionalInt64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalInt64() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional int64 optional_int64 = 2;</code>
-     * @return The optionalInt64.
-     */
-    @java.lang.Override
-    public long getOptionalInt64() {
-      return optionalInt64_;
-    }
-    /**
-     * <code>optional int64 optional_int64 = 2;</code>
-     * @param value The optionalInt64 to set.
-     */
-    private void setOptionalInt64(long value) {
-      bitField0_ |= 0x00000002;
-      optionalInt64_ = value;
-    }
-    /**
-     * <code>optional int64 optional_int64 = 2;</code>
-     */
-    private void clearOptionalInt64() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      optionalInt64_ = 0L;
-    }
-
-    public static final int OPTIONAL_UINT32_FIELD_NUMBER = 3;
-    private int optionalUint32_;
-    /**
-     * <code>optional uint32 optional_uint32 = 3;</code>
-     * @return Whether the optionalUint32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalUint32() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional uint32 optional_uint32 = 3;</code>
-     * @return The optionalUint32.
-     */
-    @java.lang.Override
-    public int getOptionalUint32() {
-      return optionalUint32_;
-    }
-    /**
-     * <code>optional uint32 optional_uint32 = 3;</code>
-     * @param value The optionalUint32 to set.
-     */
-    private void setOptionalUint32(int value) {
-      bitField0_ |= 0x00000004;
-      optionalUint32_ = value;
-    }
-    /**
-     * <code>optional uint32 optional_uint32 = 3;</code>
-     */
-    private void clearOptionalUint32() {
-      bitField0_ = (bitField0_ & ~0x00000004);
-      optionalUint32_ = 0;
-    }
-
-    public static final int OPTIONAL_UINT64_FIELD_NUMBER = 4;
-    private long optionalUint64_;
-    /**
-     * <code>optional uint64 optional_uint64 = 4;</code>
-     * @return Whether the optionalUint64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalUint64() {
-      return ((bitField0_ & 0x00000008) != 0);
-    }
-    /**
-     * <code>optional uint64 optional_uint64 = 4;</code>
-     * @return The optionalUint64.
-     */
-    @java.lang.Override
-    public long getOptionalUint64() {
-      return optionalUint64_;
-    }
-    /**
-     * <code>optional uint64 optional_uint64 = 4;</code>
-     * @param value The optionalUint64 to set.
-     */
-    private void setOptionalUint64(long value) {
-      bitField0_ |= 0x00000008;
-      optionalUint64_ = value;
-    }
-    /**
-     * <code>optional uint64 optional_uint64 = 4;</code>
-     */
-    private void clearOptionalUint64() {
-      bitField0_ = (bitField0_ & ~0x00000008);
-      optionalUint64_ = 0L;
-    }
-
-    public static final int OPTIONAL_SINT32_FIELD_NUMBER = 5;
-    private int optionalSint32_;
-    /**
-     * <code>optional sint32 optional_sint32 = 5;</code>
-     * @return Whether the optionalSint32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalSint32() {
-      return ((bitField0_ & 0x00000010) != 0);
-    }
-    /**
-     * <code>optional sint32 optional_sint32 = 5;</code>
-     * @return The optionalSint32.
-     */
-    @java.lang.Override
-    public int getOptionalSint32() {
-      return optionalSint32_;
-    }
-    /**
-     * <code>optional sint32 optional_sint32 = 5;</code>
-     * @param value The optionalSint32 to set.
-     */
-    private void setOptionalSint32(int value) {
-      bitField0_ |= 0x00000010;
-      optionalSint32_ = value;
-    }
-    /**
-     * <code>optional sint32 optional_sint32 = 5;</code>
-     */
-    private void clearOptionalSint32() {
-      bitField0_ = (bitField0_ & ~0x00000010);
-      optionalSint32_ = 0;
-    }
-
-    public static final int OPTIONAL_SINT64_FIELD_NUMBER = 6;
-    private long optionalSint64_;
-    /**
-     * <code>optional sint64 optional_sint64 = 6;</code>
-     * @return Whether the optionalSint64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalSint64() {
-      return ((bitField0_ & 0x00000020) != 0);
-    }
-    /**
-     * <code>optional sint64 optional_sint64 = 6;</code>
-     * @return The optionalSint64.
-     */
-    @java.lang.Override
-    public long getOptionalSint64() {
-      return optionalSint64_;
-    }
-    /**
-     * <code>optional sint64 optional_sint64 = 6;</code>
-     * @param value The optionalSint64 to set.
-     */
-    private void setOptionalSint64(long value) {
-      bitField0_ |= 0x00000020;
-      optionalSint64_ = value;
-    }
-    /**
-     * <code>optional sint64 optional_sint64 = 6;</code>
-     */
-    private void clearOptionalSint64() {
-      bitField0_ = (bitField0_ & ~0x00000020);
-      optionalSint64_ = 0L;
-    }
-
-    public static final int OPTIONAL_FIXED32_FIELD_NUMBER = 7;
-    private int optionalFixed32_;
-    /**
-     * <code>optional fixed32 optional_fixed32 = 7;</code>
-     * @return Whether the optionalFixed32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalFixed32() {
-      return ((bitField0_ & 0x00000040) != 0);
-    }
-    /**
-     * <code>optional fixed32 optional_fixed32 = 7;</code>
-     * @return The optionalFixed32.
-     */
-    @java.lang.Override
-    public int getOptionalFixed32() {
-      return optionalFixed32_;
-    }
-    /**
-     * <code>optional fixed32 optional_fixed32 = 7;</code>
-     * @param value The optionalFixed32 to set.
-     */
-    private void setOptionalFixed32(int value) {
-      bitField0_ |= 0x00000040;
-      optionalFixed32_ = value;
-    }
-    /**
-     * <code>optional fixed32 optional_fixed32 = 7;</code>
-     */
-    private void clearOptionalFixed32() {
-      bitField0_ = (bitField0_ & ~0x00000040);
-      optionalFixed32_ = 0;
-    }
-
-    public static final int OPTIONAL_FIXED64_FIELD_NUMBER = 8;
-    private long optionalFixed64_;
-    /**
-     * <code>optional fixed64 optional_fixed64 = 8;</code>
-     * @return Whether the optionalFixed64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalFixed64() {
-      return ((bitField0_ & 0x00000080) != 0);
-    }
-    /**
-     * <code>optional fixed64 optional_fixed64 = 8;</code>
-     * @return The optionalFixed64.
-     */
-    @java.lang.Override
-    public long getOptionalFixed64() {
-      return optionalFixed64_;
-    }
-    /**
-     * <code>optional fixed64 optional_fixed64 = 8;</code>
-     * @param value The optionalFixed64 to set.
-     */
-    private void setOptionalFixed64(long value) {
-      bitField0_ |= 0x00000080;
-      optionalFixed64_ = value;
-    }
-    /**
-     * <code>optional fixed64 optional_fixed64 = 8;</code>
-     */
-    private void clearOptionalFixed64() {
-      bitField0_ = (bitField0_ & ~0x00000080);
-      optionalFixed64_ = 0L;
-    }
-
-    public static final int OPTIONAL_SFIXED32_FIELD_NUMBER = 9;
-    private int optionalSfixed32_;
-    /**
-     * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-     * @return Whether the optionalSfixed32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalSfixed32() {
-      return ((bitField0_ & 0x00000100) != 0);
-    }
-    /**
-     * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-     * @return The optionalSfixed32.
-     */
-    @java.lang.Override
-    public int getOptionalSfixed32() {
-      return optionalSfixed32_;
-    }
-    /**
-     * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-     * @param value The optionalSfixed32 to set.
-     */
-    private void setOptionalSfixed32(int value) {
-      bitField0_ |= 0x00000100;
-      optionalSfixed32_ = value;
-    }
-    /**
-     * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-     */
-    private void clearOptionalSfixed32() {
-      bitField0_ = (bitField0_ & ~0x00000100);
-      optionalSfixed32_ = 0;
-    }
-
-    public static final int OPTIONAL_SFIXED64_FIELD_NUMBER = 10;
-    private long optionalSfixed64_;
-    /**
-     * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-     * @return Whether the optionalSfixed64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalSfixed64() {
-      return ((bitField0_ & 0x00000200) != 0);
-    }
-    /**
-     * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-     * @return The optionalSfixed64.
-     */
-    @java.lang.Override
-    public long getOptionalSfixed64() {
-      return optionalSfixed64_;
-    }
-    /**
-     * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-     * @param value The optionalSfixed64 to set.
-     */
-    private void setOptionalSfixed64(long value) {
-      bitField0_ |= 0x00000200;
-      optionalSfixed64_ = value;
-    }
-    /**
-     * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-     */
-    private void clearOptionalSfixed64() {
-      bitField0_ = (bitField0_ & ~0x00000200);
-      optionalSfixed64_ = 0L;
-    }
-
-    public static final int OPTIONAL_FLOAT_FIELD_NUMBER = 11;
-    private float optionalFloat_;
-    /**
-     * <code>optional float optional_float = 11;</code>
-     * @return Whether the optionalFloat field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalFloat() {
-      return ((bitField0_ & 0x00000400) != 0);
-    }
-    /**
-     * <code>optional float optional_float = 11;</code>
-     * @return The optionalFloat.
-     */
-    @java.lang.Override
-    public float getOptionalFloat() {
-      return optionalFloat_;
-    }
-    /**
-     * <code>optional float optional_float = 11;</code>
-     * @param value The optionalFloat to set.
-     */
-    private void setOptionalFloat(float value) {
-      bitField0_ |= 0x00000400;
-      optionalFloat_ = value;
-    }
-    /**
-     * <code>optional float optional_float = 11;</code>
-     */
-    private void clearOptionalFloat() {
-      bitField0_ = (bitField0_ & ~0x00000400);
-      optionalFloat_ = 0F;
-    }
-
-    public static final int OPTIONAL_DOUBLE_FIELD_NUMBER = 12;
-    private double optionalDouble_;
-    /**
-     * <code>optional double optional_double = 12;</code>
-     * @return Whether the optionalDouble field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalDouble() {
-      return ((bitField0_ & 0x00000800) != 0);
-    }
-    /**
-     * <code>optional double optional_double = 12;</code>
-     * @return The optionalDouble.
-     */
-    @java.lang.Override
-    public double getOptionalDouble() {
-      return optionalDouble_;
-    }
-    /**
-     * <code>optional double optional_double = 12;</code>
-     * @param value The optionalDouble to set.
-     */
-    private void setOptionalDouble(double value) {
-      bitField0_ |= 0x00000800;
-      optionalDouble_ = value;
-    }
-    /**
-     * <code>optional double optional_double = 12;</code>
-     */
-    private void clearOptionalDouble() {
-      bitField0_ = (bitField0_ & ~0x00000800);
-      optionalDouble_ = 0D;
-    }
-
-    public static final int OPTIONAL_BOOL_FIELD_NUMBER = 13;
-    private boolean optionalBool_;
-    /**
-     * <code>optional bool optional_bool = 13;</code>
-     * @return Whether the optionalBool field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalBool() {
-      return ((bitField0_ & 0x00001000) != 0);
-    }
-    /**
-     * <code>optional bool optional_bool = 13;</code>
-     * @return The optionalBool.
-     */
-    @java.lang.Override
-    public boolean getOptionalBool() {
-      return optionalBool_;
-    }
-    /**
-     * <code>optional bool optional_bool = 13;</code>
-     * @param value The optionalBool to set.
-     */
-    private void setOptionalBool(boolean value) {
-      bitField0_ |= 0x00001000;
-      optionalBool_ = value;
-    }
-    /**
-     * <code>optional bool optional_bool = 13;</code>
-     */
-    private void clearOptionalBool() {
-      bitField0_ = (bitField0_ & ~0x00001000);
-      optionalBool_ = false;
-    }
-
-    public static final int OPTIONAL_STRING_FIELD_NUMBER = 14;
-    private java.lang.String optionalString_;
-    /**
-     * <code>optional string optional_string = 14;</code>
-     * @return Whether the optionalString field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalString() {
-      return ((bitField0_ & 0x00002000) != 0);
-    }
-    /**
-     * <code>optional string optional_string = 14;</code>
-     * @return The optionalString.
-     */
-    @java.lang.Override
-    public java.lang.String getOptionalString() {
-      return optionalString_;
-    }
-    /**
-     * <code>optional string optional_string = 14;</code>
-     * @return The bytes for optionalString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOptionalStringBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(optionalString_);
-    }
-    /**
-     * <code>optional string optional_string = 14;</code>
-     * @param value The optionalString to set.
-     */
-    private void setOptionalString(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00002000;
-      optionalString_ = value;
-    }
-    /**
-     * <code>optional string optional_string = 14;</code>
-     */
-    private void clearOptionalString() {
-      bitField0_ = (bitField0_ & ~0x00002000);
-      optionalString_ = getDefaultInstance().getOptionalString();
-    }
-    /**
-     * <code>optional string optional_string = 14;</code>
-     * @param value The bytes for optionalString to set.
-     */
-    private void setOptionalStringBytes(
-        com.google.protobuf.ByteString value) {
-      optionalString_ = value.toStringUtf8();
-      bitField0_ |= 0x00002000;
-    }
-
-    public static final int OPTIONAL_BYTES_FIELD_NUMBER = 15;
-    private com.google.protobuf.ByteString optionalBytes_;
-    /**
-     * <code>optional bytes optional_bytes = 15;</code>
-     * @return Whether the optionalBytes field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalBytes() {
-      return ((bitField0_ & 0x00004000) != 0);
-    }
-    /**
-     * <code>optional bytes optional_bytes = 15;</code>
-     * @return The optionalBytes.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getOptionalBytes() {
-      return optionalBytes_;
-    }
-    /**
-     * <code>optional bytes optional_bytes = 15;</code>
-     * @param value The optionalBytes to set.
-     */
-    private void setOptionalBytes(com.google.protobuf.ByteString value) {
-      value.getClass();
-  bitField0_ |= 0x00004000;
-      optionalBytes_ = value;
-    }
-    /**
-     * <code>optional bytes optional_bytes = 15;</code>
-     */
-    private void clearOptionalBytes() {
-      bitField0_ = (bitField0_ & ~0x00004000);
-      optionalBytes_ = getDefaultInstance().getOptionalBytes();
-    }
-
-    public static final int OPTIONALGROUP_FIELD_NUMBER = 16;
-    private protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup optionalGroup_;
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalGroup() {
-      return ((bitField0_ & 0x00008000) != 0);
-    }
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup getOptionalGroup() {
-      return optionalGroup_ == null ? protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup.getDefaultInstance() : optionalGroup_;
-    }
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     */
-    private void setOptionalGroup(protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup value) {
-      value.getClass();
-  optionalGroup_ = value;
-      bitField0_ |= 0x00008000;
-      }
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalGroup(protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup value) {
-      value.getClass();
-  if (optionalGroup_ != null &&
-          optionalGroup_ != protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup.getDefaultInstance()) {
-        optionalGroup_ =
-          protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup.newBuilder(optionalGroup_).mergeFrom(value).buildPartial();
-      } else {
-        optionalGroup_ = value;
-      }
-      bitField0_ |= 0x00008000;
-    }
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     */
-    private void clearOptionalGroup() {  optionalGroup_ = null;
-      bitField0_ = (bitField0_ & ~0x00008000);
-    }
-
-    public static final int OPTIONAL_NESTED_MESSAGE_FIELD_NUMBER = 18;
-    private protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage optionalNestedMessage_;
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalNestedMessage() {
-      return ((bitField0_ & 0x00010000) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage getOptionalNestedMessage() {
-      return optionalNestedMessage_ == null ? protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.getDefaultInstance() : optionalNestedMessage_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-     */
-    private void setOptionalNestedMessage(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  optionalNestedMessage_ = value;
-      bitField0_ |= 0x00010000;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalNestedMessage(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  if (optionalNestedMessage_ != null &&
-          optionalNestedMessage_ != protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.getDefaultInstance()) {
-        optionalNestedMessage_ =
-          protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.newBuilder(optionalNestedMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalNestedMessage_ = value;
-      }
-      bitField0_ |= 0x00010000;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-     */
-    private void clearOptionalNestedMessage() {  optionalNestedMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x00010000);
-    }
-
-    public static final int OPTIONAL_FOREIGN_MESSAGE_FIELD_NUMBER = 19;
-    private protobuf_unittest.UnittestProto.ForeignMessage optionalForeignMessage_;
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage optional_foreign_message = 19;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalForeignMessage() {
-      return ((bitField0_ & 0x00020000) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage optional_foreign_message = 19;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.ForeignMessage getOptionalForeignMessage() {
-      return optionalForeignMessage_ == null ? protobuf_unittest.UnittestProto.ForeignMessage.getDefaultInstance() : optionalForeignMessage_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage optional_foreign_message = 19;</code>
-     */
-    private void setOptionalForeignMessage(protobuf_unittest.UnittestProto.ForeignMessage value) {
-      value.getClass();
-  optionalForeignMessage_ = value;
-      bitField0_ |= 0x00020000;
-      }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage optional_foreign_message = 19;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalForeignMessage(protobuf_unittest.UnittestProto.ForeignMessage value) {
-      value.getClass();
-  if (optionalForeignMessage_ != null &&
-          optionalForeignMessage_ != protobuf_unittest.UnittestProto.ForeignMessage.getDefaultInstance()) {
-        optionalForeignMessage_ =
-          protobuf_unittest.UnittestProto.ForeignMessage.newBuilder(optionalForeignMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalForeignMessage_ = value;
-      }
-      bitField0_ |= 0x00020000;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage optional_foreign_message = 19;</code>
-     */
-    private void clearOptionalForeignMessage() {  optionalForeignMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x00020000);
-    }
-
-    public static final int OPTIONAL_IMPORT_MESSAGE_FIELD_NUMBER = 20;
-    private com.google.protobuf.test.UnittestImport.ImportMessage optionalImportMessage_;
-    /**
-     * <code>optional .protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalImportMessage() {
-      return ((bitField0_ & 0x00040000) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.test.UnittestImport.ImportMessage getOptionalImportMessage() {
-      return optionalImportMessage_ == null ? com.google.protobuf.test.UnittestImport.ImportMessage.getDefaultInstance() : optionalImportMessage_;
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-     */
-    private void setOptionalImportMessage(com.google.protobuf.test.UnittestImport.ImportMessage value) {
-      value.getClass();
-  optionalImportMessage_ = value;
-      bitField0_ |= 0x00040000;
-      }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalImportMessage(com.google.protobuf.test.UnittestImport.ImportMessage value) {
-      value.getClass();
-  if (optionalImportMessage_ != null &&
-          optionalImportMessage_ != com.google.protobuf.test.UnittestImport.ImportMessage.getDefaultInstance()) {
-        optionalImportMessage_ =
-          com.google.protobuf.test.UnittestImport.ImportMessage.newBuilder(optionalImportMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalImportMessage_ = value;
-      }
-      bitField0_ |= 0x00040000;
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-     */
-    private void clearOptionalImportMessage() {  optionalImportMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x00040000);
-    }
-
-    public static final int OPTIONAL_NESTED_ENUM_FIELD_NUMBER = 21;
-    private int optionalNestedEnum_;
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-     * @return Whether the optionalNestedEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalNestedEnum() {
-      return ((bitField0_ & 0x00080000) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-     * @return The optionalNestedEnum.
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum getOptionalNestedEnum() {
-      protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum result = protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum.forNumber(optionalNestedEnum_);
-      return result == null ? protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum.FOO : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-     * @param value The optionalNestedEnum to set.
-     */
-    private void setOptionalNestedEnum(protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum value) {
-      optionalNestedEnum_ = value.getNumber();
-      bitField0_ |= 0x00080000;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-     */
-    private void clearOptionalNestedEnum() {
-      bitField0_ = (bitField0_ & ~0x00080000);
-      optionalNestedEnum_ = 1;
-    }
-
-    public static final int OPTIONAL_FOREIGN_ENUM_FIELD_NUMBER = 22;
-    private int optionalForeignEnum_;
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     * @return Whether the optionalForeignEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalForeignEnum() {
-      return ((bitField0_ & 0x00100000) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     * @return The optionalForeignEnum.
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.ForeignEnum getOptionalForeignEnum() {
-      protobuf_unittest.UnittestProto.ForeignEnum result = protobuf_unittest.UnittestProto.ForeignEnum.forNumber(optionalForeignEnum_);
-      return result == null ? protobuf_unittest.UnittestProto.ForeignEnum.FOREIGN_FOO : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     * @param value The optionalForeignEnum to set.
-     */
-    private void setOptionalForeignEnum(protobuf_unittest.UnittestProto.ForeignEnum value) {
-      optionalForeignEnum_ = value.getNumber();
-      bitField0_ |= 0x00100000;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     */
-    private void clearOptionalForeignEnum() {
-      bitField0_ = (bitField0_ & ~0x00100000);
-      optionalForeignEnum_ = 4;
-    }
-
-    public static final int OPTIONAL_IMPORT_ENUM_FIELD_NUMBER = 23;
-    private int optionalImportEnum_;
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnum optional_import_enum = 23;</code>
-     * @return Whether the optionalImportEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalImportEnum() {
-      return ((bitField0_ & 0x00200000) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnum optional_import_enum = 23;</code>
-     * @return The optionalImportEnum.
-     */
-    @java.lang.Override
-    public com.google.protobuf.test.UnittestImport.ImportEnum getOptionalImportEnum() {
-      com.google.protobuf.test.UnittestImport.ImportEnum result = com.google.protobuf.test.UnittestImport.ImportEnum.forNumber(optionalImportEnum_);
-      return result == null ? com.google.protobuf.test.UnittestImport.ImportEnum.IMPORT_FOO : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnum optional_import_enum = 23;</code>
-     * @param value The optionalImportEnum to set.
-     */
-    private void setOptionalImportEnum(com.google.protobuf.test.UnittestImport.ImportEnum value) {
-      optionalImportEnum_ = value.getNumber();
-      bitField0_ |= 0x00200000;
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnum optional_import_enum = 23;</code>
-     */
-    private void clearOptionalImportEnum() {
-      bitField0_ = (bitField0_ & ~0x00200000);
-      optionalImportEnum_ = 7;
-    }
-
-    public static final int OPTIONAL_STRING_PIECE_FIELD_NUMBER = 24;
-    private java.lang.String optionalStringPiece_;
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @return Whether the optionalStringPiece field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalStringPiece() {
-      return ((bitField0_ & 0x00400000) != 0);
-    }
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @return The optionalStringPiece.
-     */
-    @java.lang.Override
-    public java.lang.String getOptionalStringPiece() {
-      return optionalStringPiece_;
-    }
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @return The bytes for optionalStringPiece.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOptionalStringPieceBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(optionalStringPiece_);
-    }
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @param value The optionalStringPiece to set.
-     */
-    private void setOptionalStringPiece(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00400000;
-      optionalStringPiece_ = value;
-    }
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     */
-    private void clearOptionalStringPiece() {
-      bitField0_ = (bitField0_ & ~0x00400000);
-      optionalStringPiece_ = getDefaultInstance().getOptionalStringPiece();
-    }
-    /**
-     * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-     * @param value The bytes for optionalStringPiece to set.
-     */
-    private void setOptionalStringPieceBytes(
-        com.google.protobuf.ByteString value) {
-      optionalStringPiece_ = value.toStringUtf8();
-      bitField0_ |= 0x00400000;
-    }
-
-    public static final int OPTIONAL_CORD_FIELD_NUMBER = 25;
-    private java.lang.String optionalCord_;
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     * @return Whether the optionalCord field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalCord() {
-      return ((bitField0_ & 0x00800000) != 0);
-    }
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     * @return The optionalCord.
-     */
-    @java.lang.Override
-    public java.lang.String getOptionalCord() {
-      return optionalCord_;
-    }
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     * @return The bytes for optionalCord.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOptionalCordBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(optionalCord_);
-    }
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     * @param value The optionalCord to set.
-     */
-    private void setOptionalCord(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00800000;
-      optionalCord_ = value;
-    }
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     */
-    private void clearOptionalCord() {
-      bitField0_ = (bitField0_ & ~0x00800000);
-      optionalCord_ = getDefaultInstance().getOptionalCord();
-    }
-    /**
-     * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-     * @param value The bytes for optionalCord to set.
-     */
-    private void setOptionalCordBytes(
-        com.google.protobuf.ByteString value) {
-      optionalCord_ = value.toStringUtf8();
-      bitField0_ |= 0x00800000;
-    }
-
-    public static final int OPTIONAL_PUBLIC_IMPORT_MESSAGE_FIELD_NUMBER = 26;
-    private com.google.protobuf.test.UnittestImportPublic.PublicImportMessage optionalPublicImportMessage_;
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>optional .protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalPublicImportMessage() {
-      return ((bitField0_ & 0x01000000) != 0);
-    }
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>optional .protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.test.UnittestImportPublic.PublicImportMessage getOptionalPublicImportMessage() {
-      return optionalPublicImportMessage_ == null ? com.google.protobuf.test.UnittestImportPublic.PublicImportMessage.getDefaultInstance() : optionalPublicImportMessage_;
-    }
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>optional .protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-     */
-    private void setOptionalPublicImportMessage(com.google.protobuf.test.UnittestImportPublic.PublicImportMessage value) {
-      value.getClass();
-  optionalPublicImportMessage_ = value;
-      bitField0_ |= 0x01000000;
-      }
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>optional .protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalPublicImportMessage(com.google.protobuf.test.UnittestImportPublic.PublicImportMessage value) {
-      value.getClass();
-  if (optionalPublicImportMessage_ != null &&
-          optionalPublicImportMessage_ != com.google.protobuf.test.UnittestImportPublic.PublicImportMessage.getDefaultInstance()) {
-        optionalPublicImportMessage_ =
-          com.google.protobuf.test.UnittestImportPublic.PublicImportMessage.newBuilder(optionalPublicImportMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalPublicImportMessage_ = value;
-      }
-      bitField0_ |= 0x01000000;
-    }
-    /**
-     * <pre>
-     * Defined in unittest_import_public.proto
-     * </pre>
-     *
-     * <code>optional .protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-     */
-    private void clearOptionalPublicImportMessage() {  optionalPublicImportMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x01000000);
-    }
-
-    public static final int OPTIONAL_LAZY_MESSAGE_FIELD_NUMBER = 27;
-    private protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage optionalLazyMessage_;
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalLazyMessage() {
-      return ((bitField0_ & 0x02000000) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage getOptionalLazyMessage() {
-      return optionalLazyMessage_ == null ? protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.getDefaultInstance() : optionalLazyMessage_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     */
-    private void setOptionalLazyMessage(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  optionalLazyMessage_ = value;
-      bitField0_ |= 0x02000000;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalLazyMessage(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  if (optionalLazyMessage_ != null &&
-          optionalLazyMessage_ != protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.getDefaultInstance()) {
-        optionalLazyMessage_ =
-          protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.newBuilder(optionalLazyMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalLazyMessage_ = value;
-      }
-      bitField0_ |= 0x02000000;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-     */
-    private void clearOptionalLazyMessage() {  optionalLazyMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x02000000);
-    }
-
-    public static final int REPEATED_INT32_FIELD_NUMBER = 31;
-    private com.google.protobuf.Internal.IntList repeatedInt32_;
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @return A list containing the repeatedInt32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedInt32List() {
-      return repeatedInt32_;
-    }
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @return The count of repeatedInt32.
-     */
-    @java.lang.Override
-    public int getRepeatedInt32Count() {
-      return repeatedInt32_.size();
-    }
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedInt32(int index) {
-      return repeatedInt32_.getInt(index);
-    }
-    private void ensureRepeatedInt32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedInt32_;
-      if (!tmp.isModifiable()) {
-        repeatedInt32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt32 to set.
-     */
-    private void setRepeatedInt32(
-        int index, int value) {
-      ensureRepeatedInt32IsMutable();
-      repeatedInt32_.setInt(index, value);
-    }
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param value The repeatedInt32 to add.
-     */
-    private void addRepeatedInt32(int value) {
-      ensureRepeatedInt32IsMutable();
-      repeatedInt32_.addInt(value);
-    }
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     * @param values The repeatedInt32 to add.
-     */
-    private void addAllRepeatedInt32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedInt32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedInt32_);
-    }
-    /**
-     * <pre>
-     * Repeated
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 31;</code>
-     */
-    private void clearRepeatedInt32() {
-      repeatedInt32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_INT64_FIELD_NUMBER = 32;
-    private com.google.protobuf.Internal.LongList repeatedInt64_;
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @return A list containing the repeatedInt64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedInt64List() {
-      return repeatedInt64_;
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @return The count of repeatedInt64.
-     */
-    @java.lang.Override
-    public int getRepeatedInt64Count() {
-      return repeatedInt64_.size();
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedInt64(int index) {
-      return repeatedInt64_.getLong(index);
-    }
-    private void ensureRepeatedInt64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedInt64_;
-      if (!tmp.isModifiable()) {
-        repeatedInt64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt64 to set.
-     */
-    private void setRepeatedInt64(
-        int index, long value) {
-      ensureRepeatedInt64IsMutable();
-      repeatedInt64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param value The repeatedInt64 to add.
-     */
-    private void addRepeatedInt64(long value) {
-      ensureRepeatedInt64IsMutable();
-      repeatedInt64_.addLong(value);
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     * @param values The repeatedInt64 to add.
-     */
-    private void addAllRepeatedInt64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedInt64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedInt64_);
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 32;</code>
-     */
-    private void clearRepeatedInt64() {
-      repeatedInt64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_UINT32_FIELD_NUMBER = 33;
-    private com.google.protobuf.Internal.IntList repeatedUint32_;
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @return A list containing the repeatedUint32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedUint32List() {
-      return repeatedUint32_;
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @return The count of repeatedUint32.
-     */
-    @java.lang.Override
-    public int getRepeatedUint32Count() {
-      return repeatedUint32_.size();
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedUint32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedUint32(int index) {
-      return repeatedUint32_.getInt(index);
-    }
-    private void ensureRepeatedUint32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedUint32_;
-      if (!tmp.isModifiable()) {
-        repeatedUint32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedUint32 to set.
-     */
-    private void setRepeatedUint32(
-        int index, int value) {
-      ensureRepeatedUint32IsMutable();
-      repeatedUint32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param value The repeatedUint32 to add.
-     */
-    private void addRepeatedUint32(int value) {
-      ensureRepeatedUint32IsMutable();
-      repeatedUint32_.addInt(value);
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     * @param values The repeatedUint32 to add.
-     */
-    private void addAllRepeatedUint32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedUint32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedUint32_);
-    }
-    /**
-     * <code>repeated uint32 repeated_uint32 = 33;</code>
-     */
-    private void clearRepeatedUint32() {
-      repeatedUint32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_UINT64_FIELD_NUMBER = 34;
-    private com.google.protobuf.Internal.LongList repeatedUint64_;
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @return A list containing the repeatedUint64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedUint64List() {
-      return repeatedUint64_;
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @return The count of repeatedUint64.
-     */
-    @java.lang.Override
-    public int getRepeatedUint64Count() {
-      return repeatedUint64_.size();
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedUint64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedUint64(int index) {
-      return repeatedUint64_.getLong(index);
-    }
-    private void ensureRepeatedUint64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedUint64_;
-      if (!tmp.isModifiable()) {
-        repeatedUint64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedUint64 to set.
-     */
-    private void setRepeatedUint64(
-        int index, long value) {
-      ensureRepeatedUint64IsMutable();
-      repeatedUint64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param value The repeatedUint64 to add.
-     */
-    private void addRepeatedUint64(long value) {
-      ensureRepeatedUint64IsMutable();
-      repeatedUint64_.addLong(value);
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     * @param values The repeatedUint64 to add.
-     */
-    private void addAllRepeatedUint64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedUint64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedUint64_);
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 34;</code>
-     */
-    private void clearRepeatedUint64() {
-      repeatedUint64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_SINT32_FIELD_NUMBER = 35;
-    private com.google.protobuf.Internal.IntList repeatedSint32_;
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @return A list containing the repeatedSint32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedSint32List() {
-      return repeatedSint32_;
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @return The count of repeatedSint32.
-     */
-    @java.lang.Override
-    public int getRepeatedSint32Count() {
-      return repeatedSint32_.size();
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSint32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedSint32(int index) {
-      return repeatedSint32_.getInt(index);
-    }
-    private void ensureRepeatedSint32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedSint32_;
-      if (!tmp.isModifiable()) {
-        repeatedSint32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSint32 to set.
-     */
-    private void setRepeatedSint32(
-        int index, int value) {
-      ensureRepeatedSint32IsMutable();
-      repeatedSint32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param value The repeatedSint32 to add.
-     */
-    private void addRepeatedSint32(int value) {
-      ensureRepeatedSint32IsMutable();
-      repeatedSint32_.addInt(value);
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     * @param values The repeatedSint32 to add.
-     */
-    private void addAllRepeatedSint32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedSint32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedSint32_);
-    }
-    /**
-     * <code>repeated sint32 repeated_sint32 = 35;</code>
-     */
-    private void clearRepeatedSint32() {
-      repeatedSint32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_SINT64_FIELD_NUMBER = 36;
-    private com.google.protobuf.Internal.LongList repeatedSint64_;
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @return A list containing the repeatedSint64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedSint64List() {
-      return repeatedSint64_;
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @return The count of repeatedSint64.
-     */
-    @java.lang.Override
-    public int getRepeatedSint64Count() {
-      return repeatedSint64_.size();
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSint64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedSint64(int index) {
-      return repeatedSint64_.getLong(index);
-    }
-    private void ensureRepeatedSint64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedSint64_;
-      if (!tmp.isModifiable()) {
-        repeatedSint64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSint64 to set.
-     */
-    private void setRepeatedSint64(
-        int index, long value) {
-      ensureRepeatedSint64IsMutable();
-      repeatedSint64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param value The repeatedSint64 to add.
-     */
-    private void addRepeatedSint64(long value) {
-      ensureRepeatedSint64IsMutable();
-      repeatedSint64_.addLong(value);
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     * @param values The repeatedSint64 to add.
-     */
-    private void addAllRepeatedSint64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedSint64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedSint64_);
-    }
-    /**
-     * <code>repeated sint64 repeated_sint64 = 36;</code>
-     */
-    private void clearRepeatedSint64() {
-      repeatedSint64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_FIXED32_FIELD_NUMBER = 37;
-    private com.google.protobuf.Internal.IntList repeatedFixed32_;
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @return A list containing the repeatedFixed32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedFixed32List() {
-      return repeatedFixed32_;
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @return The count of repeatedFixed32.
-     */
-    @java.lang.Override
-    public int getRepeatedFixed32Count() {
-      return repeatedFixed32_.size();
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedFixed32(int index) {
-      return repeatedFixed32_.getInt(index);
-    }
-    private void ensureRepeatedFixed32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedFixed32_;
-      if (!tmp.isModifiable()) {
-        repeatedFixed32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed32 to set.
-     */
-    private void setRepeatedFixed32(
-        int index, int value) {
-      ensureRepeatedFixed32IsMutable();
-      repeatedFixed32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param value The repeatedFixed32 to add.
-     */
-    private void addRepeatedFixed32(int value) {
-      ensureRepeatedFixed32IsMutable();
-      repeatedFixed32_.addInt(value);
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     * @param values The repeatedFixed32 to add.
-     */
-    private void addAllRepeatedFixed32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedFixed32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedFixed32_);
-    }
-    /**
-     * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-     */
-    private void clearRepeatedFixed32() {
-      repeatedFixed32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_FIXED64_FIELD_NUMBER = 38;
-    private com.google.protobuf.Internal.LongList repeatedFixed64_;
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @return A list containing the repeatedFixed64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedFixed64List() {
-      return repeatedFixed64_;
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @return The count of repeatedFixed64.
-     */
-    @java.lang.Override
-    public int getRepeatedFixed64Count() {
-      return repeatedFixed64_.size();
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedFixed64(int index) {
-      return repeatedFixed64_.getLong(index);
-    }
-    private void ensureRepeatedFixed64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedFixed64_;
-      if (!tmp.isModifiable()) {
-        repeatedFixed64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed64 to set.
-     */
-    private void setRepeatedFixed64(
-        int index, long value) {
-      ensureRepeatedFixed64IsMutable();
-      repeatedFixed64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param value The repeatedFixed64 to add.
-     */
-    private void addRepeatedFixed64(long value) {
-      ensureRepeatedFixed64IsMutable();
-      repeatedFixed64_.addLong(value);
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     * @param values The repeatedFixed64 to add.
-     */
-    private void addAllRepeatedFixed64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedFixed64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedFixed64_);
-    }
-    /**
-     * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-     */
-    private void clearRepeatedFixed64() {
-      repeatedFixed64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_SFIXED32_FIELD_NUMBER = 39;
-    private com.google.protobuf.Internal.IntList repeatedSfixed32_;
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @return A list containing the repeatedSfixed32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedSfixed32List() {
-      return repeatedSfixed32_;
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @return The count of repeatedSfixed32.
-     */
-    @java.lang.Override
-    public int getRepeatedSfixed32Count() {
-      return repeatedSfixed32_.size();
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSfixed32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedSfixed32(int index) {
-      return repeatedSfixed32_.getInt(index);
-    }
-    private void ensureRepeatedSfixed32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedSfixed32_;
-      if (!tmp.isModifiable()) {
-        repeatedSfixed32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSfixed32 to set.
-     */
-    private void setRepeatedSfixed32(
-        int index, int value) {
-      ensureRepeatedSfixed32IsMutable();
-      repeatedSfixed32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param value The repeatedSfixed32 to add.
-     */
-    private void addRepeatedSfixed32(int value) {
-      ensureRepeatedSfixed32IsMutable();
-      repeatedSfixed32_.addInt(value);
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     * @param values The repeatedSfixed32 to add.
-     */
-    private void addAllRepeatedSfixed32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedSfixed32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedSfixed32_);
-    }
-    /**
-     * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-     */
-    private void clearRepeatedSfixed32() {
-      repeatedSfixed32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_SFIXED64_FIELD_NUMBER = 40;
-    private com.google.protobuf.Internal.LongList repeatedSfixed64_;
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @return A list containing the repeatedSfixed64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedSfixed64List() {
-      return repeatedSfixed64_;
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @return The count of repeatedSfixed64.
-     */
-    @java.lang.Override
-    public int getRepeatedSfixed64Count() {
-      return repeatedSfixed64_.size();
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedSfixed64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedSfixed64(int index) {
-      return repeatedSfixed64_.getLong(index);
-    }
-    private void ensureRepeatedSfixed64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedSfixed64_;
-      if (!tmp.isModifiable()) {
-        repeatedSfixed64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedSfixed64 to set.
-     */
-    private void setRepeatedSfixed64(
-        int index, long value) {
-      ensureRepeatedSfixed64IsMutable();
-      repeatedSfixed64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param value The repeatedSfixed64 to add.
-     */
-    private void addRepeatedSfixed64(long value) {
-      ensureRepeatedSfixed64IsMutable();
-      repeatedSfixed64_.addLong(value);
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     * @param values The repeatedSfixed64 to add.
-     */
-    private void addAllRepeatedSfixed64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedSfixed64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedSfixed64_);
-    }
-    /**
-     * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-     */
-    private void clearRepeatedSfixed64() {
-      repeatedSfixed64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_FLOAT_FIELD_NUMBER = 41;
-    private com.google.protobuf.Internal.FloatList repeatedFloat_;
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @return A list containing the repeatedFloat.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Float>
-        getRepeatedFloatList() {
-      return repeatedFloat_;
-    }
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @return The count of repeatedFloat.
-     */
-    @java.lang.Override
-    public int getRepeatedFloatCount() {
-      return repeatedFloat_.size();
-    }
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFloat at the given index.
-     */
-    @java.lang.Override
-    public float getRepeatedFloat(int index) {
-      return repeatedFloat_.getFloat(index);
-    }
-    private void ensureRepeatedFloatIsMutable() {
-      com.google.protobuf.Internal.FloatList tmp = repeatedFloat_;
-      if (!tmp.isModifiable()) {
-        repeatedFloat_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFloat to set.
-     */
-    private void setRepeatedFloat(
-        int index, float value) {
-      ensureRepeatedFloatIsMutable();
-      repeatedFloat_.setFloat(index, value);
-    }
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param value The repeatedFloat to add.
-     */
-    private void addRepeatedFloat(float value) {
-      ensureRepeatedFloatIsMutable();
-      repeatedFloat_.addFloat(value);
-    }
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     * @param values The repeatedFloat to add.
-     */
-    private void addAllRepeatedFloat(
-        java.lang.Iterable<? extends java.lang.Float> values) {
-      ensureRepeatedFloatIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedFloat_);
-    }
-    /**
-     * <code>repeated float repeated_float = 41;</code>
-     */
-    private void clearRepeatedFloat() {
-      repeatedFloat_ = emptyFloatList();
-    }
-
-    public static final int REPEATED_DOUBLE_FIELD_NUMBER = 42;
-    private com.google.protobuf.Internal.DoubleList repeatedDouble_;
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @return A list containing the repeatedDouble.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Double>
-        getRepeatedDoubleList() {
-      return repeatedDouble_;
-    }
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @return The count of repeatedDouble.
-     */
-    @java.lang.Override
-    public int getRepeatedDoubleCount() {
-      return repeatedDouble_.size();
-    }
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedDouble at the given index.
-     */
-    @java.lang.Override
-    public double getRepeatedDouble(int index) {
-      return repeatedDouble_.getDouble(index);
-    }
-    private void ensureRepeatedDoubleIsMutable() {
-      com.google.protobuf.Internal.DoubleList tmp = repeatedDouble_;
-      if (!tmp.isModifiable()) {
-        repeatedDouble_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedDouble to set.
-     */
-    private void setRepeatedDouble(
-        int index, double value) {
-      ensureRepeatedDoubleIsMutable();
-      repeatedDouble_.setDouble(index, value);
-    }
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param value The repeatedDouble to add.
-     */
-    private void addRepeatedDouble(double value) {
-      ensureRepeatedDoubleIsMutable();
-      repeatedDouble_.addDouble(value);
-    }
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     * @param values The repeatedDouble to add.
-     */
-    private void addAllRepeatedDouble(
-        java.lang.Iterable<? extends java.lang.Double> values) {
-      ensureRepeatedDoubleIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedDouble_);
-    }
-    /**
-     * <code>repeated double repeated_double = 42;</code>
-     */
-    private void clearRepeatedDouble() {
-      repeatedDouble_ = emptyDoubleList();
-    }
-
-    public static final int REPEATED_BOOL_FIELD_NUMBER = 43;
-    private com.google.protobuf.Internal.BooleanList repeatedBool_;
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @return A list containing the repeatedBool.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Boolean>
-        getRepeatedBoolList() {
-      return repeatedBool_;
-    }
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @return The count of repeatedBool.
-     */
-    @java.lang.Override
-    public int getRepeatedBoolCount() {
-      return repeatedBool_.size();
-    }
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedBool at the given index.
-     */
-    @java.lang.Override
-    public boolean getRepeatedBool(int index) {
-      return repeatedBool_.getBoolean(index);
-    }
-    private void ensureRepeatedBoolIsMutable() {
-      com.google.protobuf.Internal.BooleanList tmp = repeatedBool_;
-      if (!tmp.isModifiable()) {
-        repeatedBool_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedBool to set.
-     */
-    private void setRepeatedBool(
-        int index, boolean value) {
-      ensureRepeatedBoolIsMutable();
-      repeatedBool_.setBoolean(index, value);
-    }
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param value The repeatedBool to add.
-     */
-    private void addRepeatedBool(boolean value) {
-      ensureRepeatedBoolIsMutable();
-      repeatedBool_.addBoolean(value);
-    }
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     * @param values The repeatedBool to add.
-     */
-    private void addAllRepeatedBool(
-        java.lang.Iterable<? extends java.lang.Boolean> values) {
-      ensureRepeatedBoolIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedBool_);
-    }
-    /**
-     * <code>repeated bool repeated_bool = 43;</code>
-     */
-    private void clearRepeatedBool() {
-      repeatedBool_ = emptyBooleanList();
-    }
-
-    public static final int REPEATED_STRING_FIELD_NUMBER = 44;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> repeatedString_;
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @return A list containing the repeatedString.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getRepeatedStringList() {
-      return repeatedString_;
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @return The count of repeatedString.
-     */
-    @java.lang.Override
-    public int getRepeatedStringCount() {
-      return repeatedString_.size();
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedString at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getRepeatedString(int index) {
-      return repeatedString_.get(index);
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the repeatedString at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getRepeatedStringBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          repeatedString_.get(index));
-    }
-    private void ensureRepeatedStringIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          repeatedString_;  if (!tmp.isModifiable()) {
-        repeatedString_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedString to set.
-     */
-    private void setRepeatedString(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureRepeatedStringIsMutable();
-      repeatedString_.set(index, value);
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param value The repeatedString to add.
-     */
-    private void addRepeatedString(
-        java.lang.String value) {
-      value.getClass();
-  ensureRepeatedStringIsMutable();
-      repeatedString_.add(value);
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param values The repeatedString to add.
-     */
-    private void addAllRepeatedString(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureRepeatedStringIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedString_);
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     */
-    private void clearRepeatedString() {
-      repeatedString_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string repeated_string = 44;</code>
-     * @param value The bytes of the repeatedString to add.
-     */
-    private void addRepeatedStringBytes(
-        com.google.protobuf.ByteString value) {
-      ensureRepeatedStringIsMutable();
-      repeatedString_.add(value.toStringUtf8());
-    }
-
-    public static final int REPEATED_BYTES_FIELD_NUMBER = 45;
-    private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.ByteString> repeatedBytes_;
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @return A list containing the repeatedBytes.
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.ByteString>
-        getRepeatedBytesList() {
-      return repeatedBytes_;
-    }
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @return The count of repeatedBytes.
-     */
-    @java.lang.Override
-    public int getRepeatedBytesCount() {
-      return repeatedBytes_.size();
-    }
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedBytes at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getRepeatedBytes(int index) {
-      return repeatedBytes_.get(index);
-    }
-    private void ensureRepeatedBytesIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<com.google.protobuf.ByteString> tmp = repeatedBytes_;
-      if (!tmp.isModifiable()) {
-        repeatedBytes_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedBytes to set.
-     */
-    private void setRepeatedBytes(
-        int index, com.google.protobuf.ByteString value) {
-      value.getClass();
-  ensureRepeatedBytesIsMutable();
-      repeatedBytes_.set(index, value);
-    }
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param value The repeatedBytes to add.
-     */
-    private void addRepeatedBytes(com.google.protobuf.ByteString value) {
-      value.getClass();
-  ensureRepeatedBytesIsMutable();
-      repeatedBytes_.add(value);
-    }
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     * @param values The repeatedBytes to add.
-     */
-    private void addAllRepeatedBytes(
-        java.lang.Iterable<? extends com.google.protobuf.ByteString> values) {
-      ensureRepeatedBytesIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedBytes_);
-    }
-    /**
-     * <code>repeated bytes repeated_bytes = 45;</code>
-     */
-    private void clearRepeatedBytes() {
-      repeatedBytes_ = emptyProtobufList();
-    }
-
-    public static final int REPEATEDGROUP_FIELD_NUMBER = 46;
-    private com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup> repeatedGroup_;
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    @java.lang.Override
-    public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup> getRepeatedGroupList() {
-      return repeatedGroup_;
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    public java.util.List<? extends protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroupOrBuilder> 
-        getRepeatedGroupOrBuilderList() {
-      return repeatedGroup_;
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    @java.lang.Override
-    public int getRepeatedGroupCount() {
-      return repeatedGroup_.size();
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup getRepeatedGroup(int index) {
-      return repeatedGroup_.get(index);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    public protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroupOrBuilder getRepeatedGroupOrBuilder(
-        int index) {
-      return repeatedGroup_.get(index);
-    }
-    private void ensureRepeatedGroupIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup> tmp = repeatedGroup_;
-      if (!tmp.isModifiable()) {
-        repeatedGroup_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    private void setRepeatedGroup(
-        int index, protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup value) {
-      value.getClass();
-  ensureRepeatedGroupIsMutable();
-      repeatedGroup_.set(index, value);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    private void addRepeatedGroup(protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup value) {
-      value.getClass();
-  ensureRepeatedGroupIsMutable();
-      repeatedGroup_.add(value);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    private void addRepeatedGroup(
-        int index, protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup value) {
-      value.getClass();
-  ensureRepeatedGroupIsMutable();
-      repeatedGroup_.add(index, value);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    private void addAllRepeatedGroup(
-        java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup> values) {
-      ensureRepeatedGroupIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedGroup_);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    private void clearRepeatedGroup() {
-      repeatedGroup_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 46 { ... }</code>
-     */
-    private void removeRepeatedGroup(int index) {
-      ensureRepeatedGroupIsMutable();
-      repeatedGroup_.remove(index);
-    }
-
-    public static final int REPEATED_NESTED_MESSAGE_FIELD_NUMBER = 48;
-    private com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage> repeatedNestedMessage_;
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    @java.lang.Override
-    public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage> getRepeatedNestedMessageList() {
-      return repeatedNestedMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    public java.util.List<? extends protobuf_unittest.UnittestProto.TestAllTypes.NestedMessageOrBuilder> 
-        getRepeatedNestedMessageOrBuilderList() {
-      return repeatedNestedMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    @java.lang.Override
-    public int getRepeatedNestedMessageCount() {
-      return repeatedNestedMessage_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage getRepeatedNestedMessage(int index) {
-      return repeatedNestedMessage_.get(index);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    public protobuf_unittest.UnittestProto.TestAllTypes.NestedMessageOrBuilder getRepeatedNestedMessageOrBuilder(
-        int index) {
-      return repeatedNestedMessage_.get(index);
-    }
-    private void ensureRepeatedNestedMessageIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage> tmp = repeatedNestedMessage_;
-      if (!tmp.isModifiable()) {
-        repeatedNestedMessage_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    private void setRepeatedNestedMessage(
-        int index, protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  ensureRepeatedNestedMessageIsMutable();
-      repeatedNestedMessage_.set(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    private void addRepeatedNestedMessage(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  ensureRepeatedNestedMessageIsMutable();
-      repeatedNestedMessage_.add(value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    private void addRepeatedNestedMessage(
-        int index, protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  ensureRepeatedNestedMessageIsMutable();
-      repeatedNestedMessage_.add(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    private void addAllRepeatedNestedMessage(
-        java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage> values) {
-      ensureRepeatedNestedMessageIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedNestedMessage_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    private void clearRepeatedNestedMessage() {
-      repeatedNestedMessage_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-     */
-    private void removeRepeatedNestedMessage(int index) {
-      ensureRepeatedNestedMessageIsMutable();
-      repeatedNestedMessage_.remove(index);
-    }
-
-    public static final int REPEATED_FOREIGN_MESSAGE_FIELD_NUMBER = 49;
-    private com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.ForeignMessage> repeatedForeignMessage_;
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    @java.lang.Override
-    public java.util.List<protobuf_unittest.UnittestProto.ForeignMessage> getRepeatedForeignMessageList() {
-      return repeatedForeignMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    public java.util.List<? extends protobuf_unittest.UnittestProto.ForeignMessageOrBuilder> 
-        getRepeatedForeignMessageOrBuilderList() {
-      return repeatedForeignMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    @java.lang.Override
-    public int getRepeatedForeignMessageCount() {
-      return repeatedForeignMessage_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.ForeignMessage getRepeatedForeignMessage(int index) {
-      return repeatedForeignMessage_.get(index);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    public protobuf_unittest.UnittestProto.ForeignMessageOrBuilder getRepeatedForeignMessageOrBuilder(
-        int index) {
-      return repeatedForeignMessage_.get(index);
-    }
-    private void ensureRepeatedForeignMessageIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.ForeignMessage> tmp = repeatedForeignMessage_;
-      if (!tmp.isModifiable()) {
-        repeatedForeignMessage_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    private void setRepeatedForeignMessage(
-        int index, protobuf_unittest.UnittestProto.ForeignMessage value) {
-      value.getClass();
-  ensureRepeatedForeignMessageIsMutable();
-      repeatedForeignMessage_.set(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    private void addRepeatedForeignMessage(protobuf_unittest.UnittestProto.ForeignMessage value) {
-      value.getClass();
-  ensureRepeatedForeignMessageIsMutable();
-      repeatedForeignMessage_.add(value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    private void addRepeatedForeignMessage(
-        int index, protobuf_unittest.UnittestProto.ForeignMessage value) {
-      value.getClass();
-  ensureRepeatedForeignMessageIsMutable();
-      repeatedForeignMessage_.add(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    private void addAllRepeatedForeignMessage(
-        java.lang.Iterable<? extends protobuf_unittest.UnittestProto.ForeignMessage> values) {
-      ensureRepeatedForeignMessageIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedForeignMessage_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    private void clearRepeatedForeignMessage() {
-      repeatedForeignMessage_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-     */
-    private void removeRepeatedForeignMessage(int index) {
-      ensureRepeatedForeignMessageIsMutable();
-      repeatedForeignMessage_.remove(index);
-    }
-
-    public static final int REPEATED_IMPORT_MESSAGE_FIELD_NUMBER = 50;
-    private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.test.UnittestImport.ImportMessage> repeatedImportMessage_;
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.test.UnittestImport.ImportMessage> getRepeatedImportMessageList() {
-      return repeatedImportMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    public java.util.List<? extends com.google.protobuf.test.UnittestImport.ImportMessageOrBuilder> 
-        getRepeatedImportMessageOrBuilderList() {
-      return repeatedImportMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    @java.lang.Override
-    public int getRepeatedImportMessageCount() {
-      return repeatedImportMessage_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    @java.lang.Override
-    public com.google.protobuf.test.UnittestImport.ImportMessage getRepeatedImportMessage(int index) {
-      return repeatedImportMessage_.get(index);
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    public com.google.protobuf.test.UnittestImport.ImportMessageOrBuilder getRepeatedImportMessageOrBuilder(
-        int index) {
-      return repeatedImportMessage_.get(index);
-    }
-    private void ensureRepeatedImportMessageIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<com.google.protobuf.test.UnittestImport.ImportMessage> tmp = repeatedImportMessage_;
-      if (!tmp.isModifiable()) {
-        repeatedImportMessage_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    private void setRepeatedImportMessage(
-        int index, com.google.protobuf.test.UnittestImport.ImportMessage value) {
-      value.getClass();
-  ensureRepeatedImportMessageIsMutable();
-      repeatedImportMessage_.set(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    private void addRepeatedImportMessage(com.google.protobuf.test.UnittestImport.ImportMessage value) {
-      value.getClass();
-  ensureRepeatedImportMessageIsMutable();
-      repeatedImportMessage_.add(value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    private void addRepeatedImportMessage(
-        int index, com.google.protobuf.test.UnittestImport.ImportMessage value) {
-      value.getClass();
-  ensureRepeatedImportMessageIsMutable();
-      repeatedImportMessage_.add(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    private void addAllRepeatedImportMessage(
-        java.lang.Iterable<? extends com.google.protobuf.test.UnittestImport.ImportMessage> values) {
-      ensureRepeatedImportMessageIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedImportMessage_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    private void clearRepeatedImportMessage() {
-      repeatedImportMessage_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-     */
-    private void removeRepeatedImportMessage(int index) {
-      ensureRepeatedImportMessageIsMutable();
-      repeatedImportMessage_.remove(index);
-    }
-
-    public static final int REPEATED_NESTED_ENUM_FIELD_NUMBER = 51;
-    private com.google.protobuf.Internal.IntList repeatedNestedEnum_;
-    private static final com.google.protobuf.Internal.ListAdapter.Converter<
-        java.lang.Integer, protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum> repeatedNestedEnum_converter_ =
-            new com.google.protobuf.Internal.ListAdapter.Converter<
-                java.lang.Integer, protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum>() {
-              @java.lang.Override
-              public protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum convert(java.lang.Integer from) {
-                protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum result = protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum.forNumber(from);
-                return result == null ? protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum.FOO : result;
-              }
-            };
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @return A list containing the repeatedNestedEnum.
-     */
-    @java.lang.Override
-    public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum> getRepeatedNestedEnumList() {
-      return new com.google.protobuf.Internal.ListAdapter<
-          java.lang.Integer, protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum>(repeatedNestedEnum_, repeatedNestedEnum_converter_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @return The count of repeatedNestedEnum.
-     */
-    @java.lang.Override
-    public int getRepeatedNestedEnumCount() {
-      return repeatedNestedEnum_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedNestedEnum at the given index.
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum getRepeatedNestedEnum(int index) {
-      return repeatedNestedEnum_converter_.convert(repeatedNestedEnum_.getInt(index));
-    }
-    private void ensureRepeatedNestedEnumIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedNestedEnum_;
-      if (!tmp.isModifiable()) {
-        repeatedNestedEnum_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedNestedEnum to set.
-     */
-    private void setRepeatedNestedEnum(
-        int index, protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum value) {
-      value.getClass();
-  ensureRepeatedNestedEnumIsMutable();
-      repeatedNestedEnum_.setInt(index, value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param value The repeatedNestedEnum to add.
-     */
-    private void addRepeatedNestedEnum(protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum value) {
-      value.getClass();
-  ensureRepeatedNestedEnumIsMutable();
-      repeatedNestedEnum_.addInt(value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     * @param values The repeatedNestedEnum to add.
-     */
-    private void addAllRepeatedNestedEnum(
-        java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum> values) {
-      ensureRepeatedNestedEnumIsMutable();
-      for (protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum value : values) {
-        repeatedNestedEnum_.addInt(value.getNumber());
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-     */
-    private void clearRepeatedNestedEnum() {
-      repeatedNestedEnum_ = emptyIntList();
-    }
-
-    public static final int REPEATED_FOREIGN_ENUM_FIELD_NUMBER = 52;
-    private com.google.protobuf.Internal.IntList repeatedForeignEnum_;
-    private static final com.google.protobuf.Internal.ListAdapter.Converter<
-        java.lang.Integer, protobuf_unittest.UnittestProto.ForeignEnum> repeatedForeignEnum_converter_ =
-            new com.google.protobuf.Internal.ListAdapter.Converter<
-                java.lang.Integer, protobuf_unittest.UnittestProto.ForeignEnum>() {
-              @java.lang.Override
-              public protobuf_unittest.UnittestProto.ForeignEnum convert(java.lang.Integer from) {
-                protobuf_unittest.UnittestProto.ForeignEnum result = protobuf_unittest.UnittestProto.ForeignEnum.forNumber(from);
-                return result == null ? protobuf_unittest.UnittestProto.ForeignEnum.FOREIGN_FOO : result;
-              }
-            };
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @return A list containing the repeatedForeignEnum.
-     */
-    @java.lang.Override
-    public java.util.List<protobuf_unittest.UnittestProto.ForeignEnum> getRepeatedForeignEnumList() {
-      return new com.google.protobuf.Internal.ListAdapter<
-          java.lang.Integer, protobuf_unittest.UnittestProto.ForeignEnum>(repeatedForeignEnum_, repeatedForeignEnum_converter_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @return The count of repeatedForeignEnum.
-     */
-    @java.lang.Override
-    public int getRepeatedForeignEnumCount() {
-      return repeatedForeignEnum_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedForeignEnum at the given index.
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.ForeignEnum getRepeatedForeignEnum(int index) {
-      return repeatedForeignEnum_converter_.convert(repeatedForeignEnum_.getInt(index));
-    }
-    private void ensureRepeatedForeignEnumIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedForeignEnum_;
-      if (!tmp.isModifiable()) {
-        repeatedForeignEnum_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedForeignEnum to set.
-     */
-    private void setRepeatedForeignEnum(
-        int index, protobuf_unittest.UnittestProto.ForeignEnum value) {
-      value.getClass();
-  ensureRepeatedForeignEnumIsMutable();
-      repeatedForeignEnum_.setInt(index, value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param value The repeatedForeignEnum to add.
-     */
-    private void addRepeatedForeignEnum(protobuf_unittest.UnittestProto.ForeignEnum value) {
-      value.getClass();
-  ensureRepeatedForeignEnumIsMutable();
-      repeatedForeignEnum_.addInt(value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     * @param values The repeatedForeignEnum to add.
-     */
-    private void addAllRepeatedForeignEnum(
-        java.lang.Iterable<? extends protobuf_unittest.UnittestProto.ForeignEnum> values) {
-      ensureRepeatedForeignEnumIsMutable();
-      for (protobuf_unittest.UnittestProto.ForeignEnum value : values) {
-        repeatedForeignEnum_.addInt(value.getNumber());
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-     */
-    private void clearRepeatedForeignEnum() {
-      repeatedForeignEnum_ = emptyIntList();
-    }
-
-    public static final int REPEATED_IMPORT_ENUM_FIELD_NUMBER = 53;
-    private com.google.protobuf.Internal.IntList repeatedImportEnum_;
-    private static final com.google.protobuf.Internal.ListAdapter.Converter<
-        java.lang.Integer, com.google.protobuf.test.UnittestImport.ImportEnum> repeatedImportEnum_converter_ =
-            new com.google.protobuf.Internal.ListAdapter.Converter<
-                java.lang.Integer, com.google.protobuf.test.UnittestImport.ImportEnum>() {
-              @java.lang.Override
-              public com.google.protobuf.test.UnittestImport.ImportEnum convert(java.lang.Integer from) {
-                com.google.protobuf.test.UnittestImport.ImportEnum result = com.google.protobuf.test.UnittestImport.ImportEnum.forNumber(from);
-                return result == null ? com.google.protobuf.test.UnittestImport.ImportEnum.IMPORT_FOO : result;
-              }
-            };
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnum repeated_import_enum = 53;</code>
-     * @return A list containing the repeatedImportEnum.
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.test.UnittestImport.ImportEnum> getRepeatedImportEnumList() {
-      return new com.google.protobuf.Internal.ListAdapter<
-          java.lang.Integer, com.google.protobuf.test.UnittestImport.ImportEnum>(repeatedImportEnum_, repeatedImportEnum_converter_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnum repeated_import_enum = 53;</code>
-     * @return The count of repeatedImportEnum.
-     */
-    @java.lang.Override
-    public int getRepeatedImportEnumCount() {
-      return repeatedImportEnum_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnum repeated_import_enum = 53;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedImportEnum at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.test.UnittestImport.ImportEnum getRepeatedImportEnum(int index) {
-      return repeatedImportEnum_converter_.convert(repeatedImportEnum_.getInt(index));
-    }
-    private void ensureRepeatedImportEnumIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedImportEnum_;
-      if (!tmp.isModifiable()) {
-        repeatedImportEnum_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnum repeated_import_enum = 53;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedImportEnum to set.
-     */
-    private void setRepeatedImportEnum(
-        int index, com.google.protobuf.test.UnittestImport.ImportEnum value) {
-      value.getClass();
-  ensureRepeatedImportEnumIsMutable();
-      repeatedImportEnum_.setInt(index, value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnum repeated_import_enum = 53;</code>
-     * @param value The repeatedImportEnum to add.
-     */
-    private void addRepeatedImportEnum(com.google.protobuf.test.UnittestImport.ImportEnum value) {
-      value.getClass();
-  ensureRepeatedImportEnumIsMutable();
-      repeatedImportEnum_.addInt(value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnum repeated_import_enum = 53;</code>
-     * @param values The repeatedImportEnum to add.
-     */
-    private void addAllRepeatedImportEnum(
-        java.lang.Iterable<? extends com.google.protobuf.test.UnittestImport.ImportEnum> values) {
-      ensureRepeatedImportEnumIsMutable();
-      for (com.google.protobuf.test.UnittestImport.ImportEnum value : values) {
-        repeatedImportEnum_.addInt(value.getNumber());
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest_import.ImportEnum repeated_import_enum = 53;</code>
-     */
-    private void clearRepeatedImportEnum() {
-      repeatedImportEnum_ = emptyIntList();
-    }
-
-    public static final int REPEATED_STRING_PIECE_FIELD_NUMBER = 54;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> repeatedStringPiece_;
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @return A list containing the repeatedStringPiece.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getRepeatedStringPieceList() {
-      return repeatedStringPiece_;
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @return The count of repeatedStringPiece.
-     */
-    @java.lang.Override
-    public int getRepeatedStringPieceCount() {
-      return repeatedStringPiece_.size();
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedStringPiece at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getRepeatedStringPiece(int index) {
-      return repeatedStringPiece_.get(index);
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the repeatedStringPiece at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getRepeatedStringPieceBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          repeatedStringPiece_.get(index));
-    }
-    private void ensureRepeatedStringPieceIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          repeatedStringPiece_;  if (!tmp.isModifiable()) {
-        repeatedStringPiece_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedStringPiece to set.
-     */
-    private void setRepeatedStringPiece(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureRepeatedStringPieceIsMutable();
-      repeatedStringPiece_.set(index, value);
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param value The repeatedStringPiece to add.
-     */
-    private void addRepeatedStringPiece(
-        java.lang.String value) {
-      value.getClass();
-  ensureRepeatedStringPieceIsMutable();
-      repeatedStringPiece_.add(value);
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param values The repeatedStringPiece to add.
-     */
-    private void addAllRepeatedStringPiece(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureRepeatedStringPieceIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedStringPiece_);
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     */
-    private void clearRepeatedStringPiece() {
-      repeatedStringPiece_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-     * @param value The bytes of the repeatedStringPiece to add.
-     */
-    private void addRepeatedStringPieceBytes(
-        com.google.protobuf.ByteString value) {
-      ensureRepeatedStringPieceIsMutable();
-      repeatedStringPiece_.add(value.toStringUtf8());
-    }
-
-    public static final int REPEATED_CORD_FIELD_NUMBER = 55;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> repeatedCord_;
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @return A list containing the repeatedCord.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getRepeatedCordList() {
-      return repeatedCord_;
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @return The count of repeatedCord.
-     */
-    @java.lang.Override
-    public int getRepeatedCordCount() {
-      return repeatedCord_.size();
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedCord at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getRepeatedCord(int index) {
-      return repeatedCord_.get(index);
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the repeatedCord at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getRepeatedCordBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          repeatedCord_.get(index));
-    }
-    private void ensureRepeatedCordIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          repeatedCord_;  if (!tmp.isModifiable()) {
-        repeatedCord_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedCord to set.
-     */
-    private void setRepeatedCord(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureRepeatedCordIsMutable();
-      repeatedCord_.set(index, value);
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param value The repeatedCord to add.
-     */
-    private void addRepeatedCord(
-        java.lang.String value) {
-      value.getClass();
-  ensureRepeatedCordIsMutable();
-      repeatedCord_.add(value);
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param values The repeatedCord to add.
-     */
-    private void addAllRepeatedCord(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureRepeatedCordIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedCord_);
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     */
-    private void clearRepeatedCord() {
-      repeatedCord_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-     * @param value The bytes of the repeatedCord to add.
-     */
-    private void addRepeatedCordBytes(
-        com.google.protobuf.ByteString value) {
-      ensureRepeatedCordIsMutable();
-      repeatedCord_.add(value.toStringUtf8());
-    }
-
-    public static final int REPEATED_LAZY_MESSAGE_FIELD_NUMBER = 57;
-    private com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage> repeatedLazyMessage_;
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage> getRepeatedLazyMessageList() {
-      return repeatedLazyMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    public java.util.List<? extends protobuf_unittest.UnittestProto.TestAllTypes.NestedMessageOrBuilder> 
-        getRepeatedLazyMessageOrBuilderList() {
-      return repeatedLazyMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public int getRepeatedLazyMessageCount() {
-      return repeatedLazyMessage_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage getRepeatedLazyMessage(int index) {
-      return repeatedLazyMessage_.get(index);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    public protobuf_unittest.UnittestProto.TestAllTypes.NestedMessageOrBuilder getRepeatedLazyMessageOrBuilder(
-        int index) {
-      return repeatedLazyMessage_.get(index);
-    }
-    private void ensureRepeatedLazyMessageIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage> tmp = repeatedLazyMessage_;
-      if (!tmp.isModifiable()) {
-        repeatedLazyMessage_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    private void setRepeatedLazyMessage(
-        int index, protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  ensureRepeatedLazyMessageIsMutable();
-      repeatedLazyMessage_.set(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    private void addRepeatedLazyMessage(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  ensureRepeatedLazyMessageIsMutable();
-      repeatedLazyMessage_.add(value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    private void addRepeatedLazyMessage(
-        int index, protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  ensureRepeatedLazyMessageIsMutable();
-      repeatedLazyMessage_.add(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    private void addAllRepeatedLazyMessage(
-        java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage> values) {
-      ensureRepeatedLazyMessageIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedLazyMessage_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    private void clearRepeatedLazyMessage() {
-      repeatedLazyMessage_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-     */
-    private void removeRepeatedLazyMessage(int index) {
-      ensureRepeatedLazyMessageIsMutable();
-      repeatedLazyMessage_.remove(index);
-    }
-
-    public static final int DEFAULT_INT32_FIELD_NUMBER = 61;
-    private int defaultInt32_;
-    /**
-     * <pre>
-     * Singular with defaults
-     * </pre>
-     *
-     * <code>optional int32 default_int32 = 61 [default = 41];</code>
-     * @return Whether the defaultInt32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultInt32() {
-      return ((bitField0_ & 0x04000000) != 0);
-    }
-    /**
-     * <pre>
-     * Singular with defaults
-     * </pre>
-     *
-     * <code>optional int32 default_int32 = 61 [default = 41];</code>
-     * @return The defaultInt32.
-     */
-    @java.lang.Override
-    public int getDefaultInt32() {
-      return defaultInt32_;
-    }
-    /**
-     * <pre>
-     * Singular with defaults
-     * </pre>
-     *
-     * <code>optional int32 default_int32 = 61 [default = 41];</code>
-     * @param value The defaultInt32 to set.
-     */
-    private void setDefaultInt32(int value) {
-      bitField0_ |= 0x04000000;
-      defaultInt32_ = value;
-    }
-    /**
-     * <pre>
-     * Singular with defaults
-     * </pre>
-     *
-     * <code>optional int32 default_int32 = 61 [default = 41];</code>
-     */
-    private void clearDefaultInt32() {
-      bitField0_ = (bitField0_ & ~0x04000000);
-      defaultInt32_ = 41;
-    }
-
-    public static final int DEFAULT_INT64_FIELD_NUMBER = 62;
-    private long defaultInt64_;
-    /**
-     * <code>optional int64 default_int64 = 62 [default = 42];</code>
-     * @return Whether the defaultInt64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultInt64() {
-      return ((bitField0_ & 0x08000000) != 0);
-    }
-    /**
-     * <code>optional int64 default_int64 = 62 [default = 42];</code>
-     * @return The defaultInt64.
-     */
-    @java.lang.Override
-    public long getDefaultInt64() {
-      return defaultInt64_;
-    }
-    /**
-     * <code>optional int64 default_int64 = 62 [default = 42];</code>
-     * @param value The defaultInt64 to set.
-     */
-    private void setDefaultInt64(long value) {
-      bitField0_ |= 0x08000000;
-      defaultInt64_ = value;
-    }
-    /**
-     * <code>optional int64 default_int64 = 62 [default = 42];</code>
-     */
-    private void clearDefaultInt64() {
-      bitField0_ = (bitField0_ & ~0x08000000);
-      defaultInt64_ = 42L;
-    }
-
-    public static final int DEFAULT_UINT32_FIELD_NUMBER = 63;
-    private int defaultUint32_;
-    /**
-     * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-     * @return Whether the defaultUint32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultUint32() {
-      return ((bitField0_ & 0x10000000) != 0);
-    }
-    /**
-     * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-     * @return The defaultUint32.
-     */
-    @java.lang.Override
-    public int getDefaultUint32() {
-      return defaultUint32_;
-    }
-    /**
-     * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-     * @param value The defaultUint32 to set.
-     */
-    private void setDefaultUint32(int value) {
-      bitField0_ |= 0x10000000;
-      defaultUint32_ = value;
-    }
-    /**
-     * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-     */
-    private void clearDefaultUint32() {
-      bitField0_ = (bitField0_ & ~0x10000000);
-      defaultUint32_ = 43;
-    }
-
-    public static final int DEFAULT_UINT64_FIELD_NUMBER = 64;
-    private long defaultUint64_;
-    /**
-     * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-     * @return Whether the defaultUint64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultUint64() {
-      return ((bitField0_ & 0x20000000) != 0);
-    }
-    /**
-     * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-     * @return The defaultUint64.
-     */
-    @java.lang.Override
-    public long getDefaultUint64() {
-      return defaultUint64_;
-    }
-    /**
-     * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-     * @param value The defaultUint64 to set.
-     */
-    private void setDefaultUint64(long value) {
-      bitField0_ |= 0x20000000;
-      defaultUint64_ = value;
-    }
-    /**
-     * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-     */
-    private void clearDefaultUint64() {
-      bitField0_ = (bitField0_ & ~0x20000000);
-      defaultUint64_ = 44L;
-    }
-
-    public static final int DEFAULT_SINT32_FIELD_NUMBER = 65;
-    private int defaultSint32_;
-    /**
-     * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-     * @return Whether the defaultSint32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultSint32() {
-      return ((bitField0_ & 0x40000000) != 0);
-    }
-    /**
-     * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-     * @return The defaultSint32.
-     */
-    @java.lang.Override
-    public int getDefaultSint32() {
-      return defaultSint32_;
-    }
-    /**
-     * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-     * @param value The defaultSint32 to set.
-     */
-    private void setDefaultSint32(int value) {
-      bitField0_ |= 0x40000000;
-      defaultSint32_ = value;
-    }
-    /**
-     * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-     */
-    private void clearDefaultSint32() {
-      bitField0_ = (bitField0_ & ~0x40000000);
-      defaultSint32_ = -45;
-    }
-
-    public static final int DEFAULT_SINT64_FIELD_NUMBER = 66;
-    private long defaultSint64_;
-    /**
-     * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-     * @return Whether the defaultSint64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultSint64() {
-      return ((bitField0_ & 0x80000000) != 0);
-    }
-    /**
-     * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-     * @return The defaultSint64.
-     */
-    @java.lang.Override
-    public long getDefaultSint64() {
-      return defaultSint64_;
-    }
-    /**
-     * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-     * @param value The defaultSint64 to set.
-     */
-    private void setDefaultSint64(long value) {
-      bitField0_ |= 0x80000000;
-      defaultSint64_ = value;
-    }
-    /**
-     * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-     */
-    private void clearDefaultSint64() {
-      bitField0_ = (bitField0_ & ~0x80000000);
-      defaultSint64_ = 46L;
-    }
-
-    public static final int DEFAULT_FIXED32_FIELD_NUMBER = 67;
-    private int defaultFixed32_;
-    /**
-     * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-     * @return Whether the defaultFixed32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultFixed32() {
-      return ((bitField1_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-     * @return The defaultFixed32.
-     */
-    @java.lang.Override
-    public int getDefaultFixed32() {
-      return defaultFixed32_;
-    }
-    /**
-     * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-     * @param value The defaultFixed32 to set.
-     */
-    private void setDefaultFixed32(int value) {
-      bitField1_ |= 0x00000001;
-      defaultFixed32_ = value;
-    }
-    /**
-     * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-     */
-    private void clearDefaultFixed32() {
-      bitField1_ = (bitField1_ & ~0x00000001);
-      defaultFixed32_ = 47;
-    }
-
-    public static final int DEFAULT_FIXED64_FIELD_NUMBER = 68;
-    private long defaultFixed64_;
-    /**
-     * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-     * @return Whether the defaultFixed64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultFixed64() {
-      return ((bitField1_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-     * @return The defaultFixed64.
-     */
-    @java.lang.Override
-    public long getDefaultFixed64() {
-      return defaultFixed64_;
-    }
-    /**
-     * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-     * @param value The defaultFixed64 to set.
-     */
-    private void setDefaultFixed64(long value) {
-      bitField1_ |= 0x00000002;
-      defaultFixed64_ = value;
-    }
-    /**
-     * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-     */
-    private void clearDefaultFixed64() {
-      bitField1_ = (bitField1_ & ~0x00000002);
-      defaultFixed64_ = 48L;
-    }
-
-    public static final int DEFAULT_SFIXED32_FIELD_NUMBER = 69;
-    private int defaultSfixed32_;
-    /**
-     * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-     * @return Whether the defaultSfixed32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultSfixed32() {
-      return ((bitField1_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-     * @return The defaultSfixed32.
-     */
-    @java.lang.Override
-    public int getDefaultSfixed32() {
-      return defaultSfixed32_;
-    }
-    /**
-     * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-     * @param value The defaultSfixed32 to set.
-     */
-    private void setDefaultSfixed32(int value) {
-      bitField1_ |= 0x00000004;
-      defaultSfixed32_ = value;
-    }
-    /**
-     * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-     */
-    private void clearDefaultSfixed32() {
-      bitField1_ = (bitField1_ & ~0x00000004);
-      defaultSfixed32_ = 49;
-    }
-
-    public static final int DEFAULT_SFIXED64_FIELD_NUMBER = 70;
-    private long defaultSfixed64_;
-    /**
-     * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-     * @return Whether the defaultSfixed64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultSfixed64() {
-      return ((bitField1_ & 0x00000008) != 0);
-    }
-    /**
-     * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-     * @return The defaultSfixed64.
-     */
-    @java.lang.Override
-    public long getDefaultSfixed64() {
-      return defaultSfixed64_;
-    }
-    /**
-     * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-     * @param value The defaultSfixed64 to set.
-     */
-    private void setDefaultSfixed64(long value) {
-      bitField1_ |= 0x00000008;
-      defaultSfixed64_ = value;
-    }
-    /**
-     * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-     */
-    private void clearDefaultSfixed64() {
-      bitField1_ = (bitField1_ & ~0x00000008);
-      defaultSfixed64_ = -50L;
-    }
-
-    public static final int DEFAULT_FLOAT_FIELD_NUMBER = 71;
-    private float defaultFloat_;
-    /**
-     * <code>optional float default_float = 71 [default = 51.5];</code>
-     * @return Whether the defaultFloat field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultFloat() {
-      return ((bitField1_ & 0x00000010) != 0);
-    }
-    /**
-     * <code>optional float default_float = 71 [default = 51.5];</code>
-     * @return The defaultFloat.
-     */
-    @java.lang.Override
-    public float getDefaultFloat() {
-      return defaultFloat_;
-    }
-    /**
-     * <code>optional float default_float = 71 [default = 51.5];</code>
-     * @param value The defaultFloat to set.
-     */
-    private void setDefaultFloat(float value) {
-      bitField1_ |= 0x00000010;
-      defaultFloat_ = value;
-    }
-    /**
-     * <code>optional float default_float = 71 [default = 51.5];</code>
-     */
-    private void clearDefaultFloat() {
-      bitField1_ = (bitField1_ & ~0x00000010);
-      defaultFloat_ = 51.5F;
-    }
-
-    public static final int DEFAULT_DOUBLE_FIELD_NUMBER = 72;
-    private double defaultDouble_;
-    /**
-     * <code>optional double default_double = 72 [default = 52000];</code>
-     * @return Whether the defaultDouble field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultDouble() {
-      return ((bitField1_ & 0x00000020) != 0);
-    }
-    /**
-     * <code>optional double default_double = 72 [default = 52000];</code>
-     * @return The defaultDouble.
-     */
-    @java.lang.Override
-    public double getDefaultDouble() {
-      return defaultDouble_;
-    }
-    /**
-     * <code>optional double default_double = 72 [default = 52000];</code>
-     * @param value The defaultDouble to set.
-     */
-    private void setDefaultDouble(double value) {
-      bitField1_ |= 0x00000020;
-      defaultDouble_ = value;
-    }
-    /**
-     * <code>optional double default_double = 72 [default = 52000];</code>
-     */
-    private void clearDefaultDouble() {
-      bitField1_ = (bitField1_ & ~0x00000020);
-      defaultDouble_ = 52000D;
-    }
-
-    public static final int DEFAULT_BOOL_FIELD_NUMBER = 73;
-    private boolean defaultBool_;
-    /**
-     * <code>optional bool default_bool = 73 [default = true];</code>
-     * @return Whether the defaultBool field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultBool() {
-      return ((bitField1_ & 0x00000040) != 0);
-    }
-    /**
-     * <code>optional bool default_bool = 73 [default = true];</code>
-     * @return The defaultBool.
-     */
-    @java.lang.Override
-    public boolean getDefaultBool() {
-      return defaultBool_;
-    }
-    /**
-     * <code>optional bool default_bool = 73 [default = true];</code>
-     * @param value The defaultBool to set.
-     */
-    private void setDefaultBool(boolean value) {
-      bitField1_ |= 0x00000040;
-      defaultBool_ = value;
-    }
-    /**
-     * <code>optional bool default_bool = 73 [default = true];</code>
-     */
-    private void clearDefaultBool() {
-      bitField1_ = (bitField1_ & ~0x00000040);
-      defaultBool_ = true;
-    }
-
-    public static final int DEFAULT_STRING_FIELD_NUMBER = 74;
-    private java.lang.String defaultString_;
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     * @return Whether the defaultString field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultString() {
-      return ((bitField1_ & 0x00000080) != 0);
-    }
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     * @return The defaultString.
-     */
-    @java.lang.Override
-    public java.lang.String getDefaultString() {
-      return defaultString_;
-    }
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     * @return The bytes for defaultString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getDefaultStringBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(defaultString_);
-    }
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     * @param value The defaultString to set.
-     */
-    private void setDefaultString(
-        java.lang.String value) {
-      value.getClass();
-  bitField1_ |= 0x00000080;
-      defaultString_ = value;
-    }
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     */
-    private void clearDefaultString() {
-      bitField1_ = (bitField1_ & ~0x00000080);
-      defaultString_ = getDefaultInstance().getDefaultString();
-    }
-    /**
-     * <code>optional string default_string = 74 [default = "hello"];</code>
-     * @param value The bytes for defaultString to set.
-     */
-    private void setDefaultStringBytes(
-        com.google.protobuf.ByteString value) {
-      defaultString_ = value.toStringUtf8();
-      bitField1_ |= 0x00000080;
-    }
-
-    public static final int DEFAULT_BYTES_FIELD_NUMBER = 75;
-    private static final com.google.protobuf.ByteString DEFAULTBYTES_DEFAULT_VALUE = com.google.protobuf.Internal.bytesDefaultValue("world");
-    private com.google.protobuf.ByteString defaultBytes_;
-    /**
-     * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-     * @return Whether the defaultBytes field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultBytes() {
-      return ((bitField1_ & 0x00000100) != 0);
-    }
-    /**
-     * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-     * @return The defaultBytes.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getDefaultBytes() {
-      return defaultBytes_;
-    }
-    /**
-     * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-     * @param value The defaultBytes to set.
-     */
-    private void setDefaultBytes(com.google.protobuf.ByteString value) {
-      value.getClass();
-  bitField1_ |= 0x00000100;
-      defaultBytes_ = value;
-    }
-    /**
-     * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-     */
-    private void clearDefaultBytes() {
-      bitField1_ = (bitField1_ & ~0x00000100);
-      defaultBytes_ = getDefaultInstance().getDefaultBytes();
-    }
-
-    public static final int DEFAULT_NESTED_ENUM_FIELD_NUMBER = 81;
-    private int defaultNestedEnum_;
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-     * @return Whether the defaultNestedEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultNestedEnum() {
-      return ((bitField1_ & 0x00000200) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-     * @return The defaultNestedEnum.
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum getDefaultNestedEnum() {
-      protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum result = protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum.forNumber(defaultNestedEnum_);
-      return result == null ? protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum.BAR : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-     * @param value The defaultNestedEnum to set.
-     */
-    private void setDefaultNestedEnum(protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum value) {
-      defaultNestedEnum_ = value.getNumber();
-      bitField1_ |= 0x00000200;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-     */
-    private void clearDefaultNestedEnum() {
-      bitField1_ = (bitField1_ & ~0x00000200);
-      defaultNestedEnum_ = 2;
-    }
-
-    public static final int DEFAULT_FOREIGN_ENUM_FIELD_NUMBER = 82;
-    private int defaultForeignEnum_;
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR];</code>
-     * @return Whether the defaultForeignEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultForeignEnum() {
-      return ((bitField1_ & 0x00000400) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR];</code>
-     * @return The defaultForeignEnum.
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.ForeignEnum getDefaultForeignEnum() {
-      protobuf_unittest.UnittestProto.ForeignEnum result = protobuf_unittest.UnittestProto.ForeignEnum.forNumber(defaultForeignEnum_);
-      return result == null ? protobuf_unittest.UnittestProto.ForeignEnum.FOREIGN_BAR : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR];</code>
-     * @param value The defaultForeignEnum to set.
-     */
-    private void setDefaultForeignEnum(protobuf_unittest.UnittestProto.ForeignEnum value) {
-      defaultForeignEnum_ = value.getNumber();
-      bitField1_ |= 0x00000400;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR];</code>
-     */
-    private void clearDefaultForeignEnum() {
-      bitField1_ = (bitField1_ & ~0x00000400);
-      defaultForeignEnum_ = 5;
-    }
-
-    public static final int DEFAULT_IMPORT_ENUM_FIELD_NUMBER = 83;
-    private int defaultImportEnum_;
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnum default_import_enum = 83 [default = IMPORT_BAR];</code>
-     * @return Whether the defaultImportEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultImportEnum() {
-      return ((bitField1_ & 0x00000800) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnum default_import_enum = 83 [default = IMPORT_BAR];</code>
-     * @return The defaultImportEnum.
-     */
-    @java.lang.Override
-    public com.google.protobuf.test.UnittestImport.ImportEnum getDefaultImportEnum() {
-      com.google.protobuf.test.UnittestImport.ImportEnum result = com.google.protobuf.test.UnittestImport.ImportEnum.forNumber(defaultImportEnum_);
-      return result == null ? com.google.protobuf.test.UnittestImport.ImportEnum.IMPORT_BAR : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnum default_import_enum = 83 [default = IMPORT_BAR];</code>
-     * @param value The defaultImportEnum to set.
-     */
-    private void setDefaultImportEnum(com.google.protobuf.test.UnittestImport.ImportEnum value) {
-      defaultImportEnum_ = value.getNumber();
-      bitField1_ |= 0x00000800;
-    }
-    /**
-     * <code>optional .protobuf_unittest_import.ImportEnum default_import_enum = 83 [default = IMPORT_BAR];</code>
-     */
-    private void clearDefaultImportEnum() {
-      bitField1_ = (bitField1_ & ~0x00000800);
-      defaultImportEnum_ = 8;
-    }
-
-    public static final int DEFAULT_STRING_PIECE_FIELD_NUMBER = 84;
-    private java.lang.String defaultStringPiece_;
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     * @return Whether the defaultStringPiece field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultStringPiece() {
-      return ((bitField1_ & 0x00001000) != 0);
-    }
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     * @return The defaultStringPiece.
-     */
-    @java.lang.Override
-    public java.lang.String getDefaultStringPiece() {
-      return defaultStringPiece_;
-    }
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     * @return The bytes for defaultStringPiece.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getDefaultStringPieceBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(defaultStringPiece_);
-    }
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     * @param value The defaultStringPiece to set.
-     */
-    private void setDefaultStringPiece(
-        java.lang.String value) {
-      value.getClass();
-  bitField1_ |= 0x00001000;
-      defaultStringPiece_ = value;
-    }
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     */
-    private void clearDefaultStringPiece() {
-      bitField1_ = (bitField1_ & ~0x00001000);
-      defaultStringPiece_ = getDefaultInstance().getDefaultStringPiece();
-    }
-    /**
-     * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-     * @param value The bytes for defaultStringPiece to set.
-     */
-    private void setDefaultStringPieceBytes(
-        com.google.protobuf.ByteString value) {
-      defaultStringPiece_ = value.toStringUtf8();
-      bitField1_ |= 0x00001000;
-    }
-
-    public static final int DEFAULT_CORD_FIELD_NUMBER = 85;
-    private java.lang.String defaultCord_;
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     * @return Whether the defaultCord field is set.
-     */
-    @java.lang.Override
-    public boolean hasDefaultCord() {
-      return ((bitField1_ & 0x00002000) != 0);
-    }
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     * @return The defaultCord.
-     */
-    @java.lang.Override
-    public java.lang.String getDefaultCord() {
-      return defaultCord_;
-    }
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     * @return The bytes for defaultCord.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getDefaultCordBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(defaultCord_);
-    }
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     * @param value The defaultCord to set.
-     */
-    private void setDefaultCord(
-        java.lang.String value) {
-      value.getClass();
-  bitField1_ |= 0x00002000;
-      defaultCord_ = value;
-    }
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     */
-    private void clearDefaultCord() {
-      bitField1_ = (bitField1_ & ~0x00002000);
-      defaultCord_ = getDefaultInstance().getDefaultCord();
-    }
-    /**
-     * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-     * @param value The bytes for defaultCord to set.
-     */
-    private void setDefaultCordBytes(
-        com.google.protobuf.ByteString value) {
-      defaultCord_ = value.toStringUtf8();
-      bitField1_ |= 0x00002000;
-    }
-
-    public static final int ONEOF_UINT32_FIELD_NUMBER = 111;
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     * @return Whether the oneofUint32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofUint32() {
-      return oneofFieldCase_ == 111;
-    }
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     * @return The oneofUint32.
-     */
-    @java.lang.Override
-    public int getOneofUint32() {
-      if (oneofFieldCase_ == 111) {
-        return (java.lang.Integer) oneofField_;
-      }
-      return 0;
-    }
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     * @param value The oneofUint32 to set.
-     */
-    private void setOneofUint32(int value) {
-      oneofFieldCase_ = 111;
-      oneofField_ = value;
-    }
-    /**
-     * <code>uint32 oneof_uint32 = 111;</code>
-     */
-    private void clearOneofUint32() {
-      if (oneofFieldCase_ == 111) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static final int ONEOF_NESTED_MESSAGE_FIELD_NUMBER = 112;
-    /**
-     * <code>.protobuf_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-     */
-    @java.lang.Override
-    public boolean hasOneofNestedMessage() {
-      return oneofFieldCase_ == 112;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage getOneofNestedMessage() {
-      if (oneofFieldCase_ == 112) {
-         return (protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage) oneofField_;
-      }
-      return protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.getDefaultInstance();
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-     */
-    private void setOneofNestedMessage(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  oneofField_ = value;
-      oneofFieldCase_ = 112;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-     */
-    private void mergeOneofNestedMessage(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  if (oneofFieldCase_ == 112 &&
-          oneofField_ != protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.getDefaultInstance()) {
-        oneofField_ = protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.newBuilder((protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage) oneofField_)
-            .mergeFrom(value).buildPartial();
-      } else {
-        oneofField_ = value;
-      }
-      oneofFieldCase_ = 112;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-     */
-    private void clearOneofNestedMessage() {
-      if (oneofFieldCase_ == 112) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static final int ONEOF_STRING_FIELD_NUMBER = 113;
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return Whether the oneofString field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofString() {
-      return oneofFieldCase_ == 113;
-    }
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return The oneofString.
-     */
-    @java.lang.Override
-    public java.lang.String getOneofString() {
-      java.lang.String ref = "";
-      if (oneofFieldCase_ == 113) {
-        ref = (java.lang.String) oneofField_;
-      }
-      return ref;
-    }
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @return The bytes for oneofString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOneofStringBytes() {
-      java.lang.String ref = "";
-      if (oneofFieldCase_ == 113) {
-        ref = (java.lang.String) oneofField_;
-      }
-      return com.google.protobuf.ByteString.copyFromUtf8(ref);
-    }
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @param value The oneofString to set.
-     */
-    private void setOneofString(
-        java.lang.String value) {
-      value.getClass();
-  oneofFieldCase_ = 113;
-      oneofField_ = value;
-    }
-    /**
-     * <code>string oneof_string = 113;</code>
-     */
-    private void clearOneofString() {
-      if (oneofFieldCase_ == 113) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-    /**
-     * <code>string oneof_string = 113;</code>
-     * @param value The bytes for oneofString to set.
-     */
-    private void setOneofStringBytes(
-        com.google.protobuf.ByteString value) {
-      oneofField_ = value.toStringUtf8();
-      oneofFieldCase_ = 113;
-    }
-
-    public static final int ONEOF_BYTES_FIELD_NUMBER = 114;
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     * @return Whether the oneofBytes field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofBytes() {
-      return oneofFieldCase_ == 114;
-    }
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     * @return The oneofBytes.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getOneofBytes() {
-      if (oneofFieldCase_ == 114) {
-        return (com.google.protobuf.ByteString) oneofField_;
-      }
-      return com.google.protobuf.ByteString.EMPTY;
-    }
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     * @param value The oneofBytes to set.
-     */
-    private void setOneofBytes(com.google.protobuf.ByteString value) {
-      value.getClass();
-  oneofFieldCase_ = 114;
-      oneofField_ = value;
-    }
-    /**
-     * <code>bytes oneof_bytes = 114;</code>
-     */
-    private void clearOneofBytes() {
-      if (oneofFieldCase_ == 114) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static protobuf_unittest.UnittestProto.TestAllTypes parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllTypes parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllTypes parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllTypes parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllTypes parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllTypes parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllTypes parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllTypes parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllTypes parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllTypes parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllTypes parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllTypes parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestAllTypes prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * This proto includes every type of field in both singular and repeated
-     * forms.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestAllTypes}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestAllTypes, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestAllTypes)
-        protobuf_unittest.UnittestProto.TestAllTypesOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestAllTypes.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-      @java.lang.Override
-      public OneofFieldCase
-          getOneofFieldCase() {
-        return instance.getOneofFieldCase();
-      }
-
-      public Builder clearOneofField() {
-        copyOnWrite();
-        instance.clearOneofField();
-        return this;
-      }
-
-
-      /**
-       * <pre>
-       * Singular
-       * </pre>
-       *
-       * <code>optional int32 optional_int32 = 1;</code>
-       * @return Whether the optionalInt32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalInt32() {
-        return instance.hasOptionalInt32();
-      }
-      /**
-       * <pre>
-       * Singular
-       * </pre>
-       *
-       * <code>optional int32 optional_int32 = 1;</code>
-       * @return The optionalInt32.
-       */
-      @java.lang.Override
-      public int getOptionalInt32() {
-        return instance.getOptionalInt32();
-      }
-      /**
-       * <pre>
-       * Singular
-       * </pre>
-       *
-       * <code>optional int32 optional_int32 = 1;</code>
-       * @param value The optionalInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalInt32(int value) {
-        copyOnWrite();
-        instance.setOptionalInt32(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Singular
-       * </pre>
-       *
-       * <code>optional int32 optional_int32 = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalInt32() {
-        copyOnWrite();
-        instance.clearOptionalInt32();
-        return this;
-      }
-
-      /**
-       * <code>optional int64 optional_int64 = 2;</code>
-       * @return Whether the optionalInt64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalInt64() {
-        return instance.hasOptionalInt64();
-      }
-      /**
-       * <code>optional int64 optional_int64 = 2;</code>
-       * @return The optionalInt64.
-       */
-      @java.lang.Override
-      public long getOptionalInt64() {
-        return instance.getOptionalInt64();
-      }
-      /**
-       * <code>optional int64 optional_int64 = 2;</code>
-       * @param value The optionalInt64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalInt64(long value) {
-        copyOnWrite();
-        instance.setOptionalInt64(value);
-        return this;
-      }
-      /**
-       * <code>optional int64 optional_int64 = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalInt64() {
-        copyOnWrite();
-        instance.clearOptionalInt64();
-        return this;
-      }
-
-      /**
-       * <code>optional uint32 optional_uint32 = 3;</code>
-       * @return Whether the optionalUint32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalUint32() {
-        return instance.hasOptionalUint32();
-      }
-      /**
-       * <code>optional uint32 optional_uint32 = 3;</code>
-       * @return The optionalUint32.
-       */
-      @java.lang.Override
-      public int getOptionalUint32() {
-        return instance.getOptionalUint32();
-      }
-      /**
-       * <code>optional uint32 optional_uint32 = 3;</code>
-       * @param value The optionalUint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalUint32(int value) {
-        copyOnWrite();
-        instance.setOptionalUint32(value);
-        return this;
-      }
-      /**
-       * <code>optional uint32 optional_uint32 = 3;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalUint32() {
-        copyOnWrite();
-        instance.clearOptionalUint32();
-        return this;
-      }
-
-      /**
-       * <code>optional uint64 optional_uint64 = 4;</code>
-       * @return Whether the optionalUint64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalUint64() {
-        return instance.hasOptionalUint64();
-      }
-      /**
-       * <code>optional uint64 optional_uint64 = 4;</code>
-       * @return The optionalUint64.
-       */
-      @java.lang.Override
-      public long getOptionalUint64() {
-        return instance.getOptionalUint64();
-      }
-      /**
-       * <code>optional uint64 optional_uint64 = 4;</code>
-       * @param value The optionalUint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalUint64(long value) {
-        copyOnWrite();
-        instance.setOptionalUint64(value);
-        return this;
-      }
-      /**
-       * <code>optional uint64 optional_uint64 = 4;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalUint64() {
-        copyOnWrite();
-        instance.clearOptionalUint64();
-        return this;
-      }
-
-      /**
-       * <code>optional sint32 optional_sint32 = 5;</code>
-       * @return Whether the optionalSint32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalSint32() {
-        return instance.hasOptionalSint32();
-      }
-      /**
-       * <code>optional sint32 optional_sint32 = 5;</code>
-       * @return The optionalSint32.
-       */
-      @java.lang.Override
-      public int getOptionalSint32() {
-        return instance.getOptionalSint32();
-      }
-      /**
-       * <code>optional sint32 optional_sint32 = 5;</code>
-       * @param value The optionalSint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalSint32(int value) {
-        copyOnWrite();
-        instance.setOptionalSint32(value);
-        return this;
-      }
-      /**
-       * <code>optional sint32 optional_sint32 = 5;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalSint32() {
-        copyOnWrite();
-        instance.clearOptionalSint32();
-        return this;
-      }
-
-      /**
-       * <code>optional sint64 optional_sint64 = 6;</code>
-       * @return Whether the optionalSint64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalSint64() {
-        return instance.hasOptionalSint64();
-      }
-      /**
-       * <code>optional sint64 optional_sint64 = 6;</code>
-       * @return The optionalSint64.
-       */
-      @java.lang.Override
-      public long getOptionalSint64() {
-        return instance.getOptionalSint64();
-      }
-      /**
-       * <code>optional sint64 optional_sint64 = 6;</code>
-       * @param value The optionalSint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalSint64(long value) {
-        copyOnWrite();
-        instance.setOptionalSint64(value);
-        return this;
-      }
-      /**
-       * <code>optional sint64 optional_sint64 = 6;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalSint64() {
-        copyOnWrite();
-        instance.clearOptionalSint64();
-        return this;
-      }
-
-      /**
-       * <code>optional fixed32 optional_fixed32 = 7;</code>
-       * @return Whether the optionalFixed32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalFixed32() {
-        return instance.hasOptionalFixed32();
-      }
-      /**
-       * <code>optional fixed32 optional_fixed32 = 7;</code>
-       * @return The optionalFixed32.
-       */
-      @java.lang.Override
-      public int getOptionalFixed32() {
-        return instance.getOptionalFixed32();
-      }
-      /**
-       * <code>optional fixed32 optional_fixed32 = 7;</code>
-       * @param value The optionalFixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalFixed32(int value) {
-        copyOnWrite();
-        instance.setOptionalFixed32(value);
-        return this;
-      }
-      /**
-       * <code>optional fixed32 optional_fixed32 = 7;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalFixed32() {
-        copyOnWrite();
-        instance.clearOptionalFixed32();
-        return this;
-      }
-
-      /**
-       * <code>optional fixed64 optional_fixed64 = 8;</code>
-       * @return Whether the optionalFixed64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalFixed64() {
-        return instance.hasOptionalFixed64();
-      }
-      /**
-       * <code>optional fixed64 optional_fixed64 = 8;</code>
-       * @return The optionalFixed64.
-       */
-      @java.lang.Override
-      public long getOptionalFixed64() {
-        return instance.getOptionalFixed64();
-      }
-      /**
-       * <code>optional fixed64 optional_fixed64 = 8;</code>
-       * @param value The optionalFixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalFixed64(long value) {
-        copyOnWrite();
-        instance.setOptionalFixed64(value);
-        return this;
-      }
-      /**
-       * <code>optional fixed64 optional_fixed64 = 8;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalFixed64() {
-        copyOnWrite();
-        instance.clearOptionalFixed64();
-        return this;
-      }
-
-      /**
-       * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-       * @return Whether the optionalSfixed32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalSfixed32() {
-        return instance.hasOptionalSfixed32();
-      }
-      /**
-       * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-       * @return The optionalSfixed32.
-       */
-      @java.lang.Override
-      public int getOptionalSfixed32() {
-        return instance.getOptionalSfixed32();
-      }
-      /**
-       * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-       * @param value The optionalSfixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalSfixed32(int value) {
-        copyOnWrite();
-        instance.setOptionalSfixed32(value);
-        return this;
-      }
-      /**
-       * <code>optional sfixed32 optional_sfixed32 = 9;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalSfixed32() {
-        copyOnWrite();
-        instance.clearOptionalSfixed32();
-        return this;
-      }
-
-      /**
-       * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-       * @return Whether the optionalSfixed64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalSfixed64() {
-        return instance.hasOptionalSfixed64();
-      }
-      /**
-       * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-       * @return The optionalSfixed64.
-       */
-      @java.lang.Override
-      public long getOptionalSfixed64() {
-        return instance.getOptionalSfixed64();
-      }
-      /**
-       * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-       * @param value The optionalSfixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalSfixed64(long value) {
-        copyOnWrite();
-        instance.setOptionalSfixed64(value);
-        return this;
-      }
-      /**
-       * <code>optional sfixed64 optional_sfixed64 = 10;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalSfixed64() {
-        copyOnWrite();
-        instance.clearOptionalSfixed64();
-        return this;
-      }
-
-      /**
-       * <code>optional float optional_float = 11;</code>
-       * @return Whether the optionalFloat field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalFloat() {
-        return instance.hasOptionalFloat();
-      }
-      /**
-       * <code>optional float optional_float = 11;</code>
-       * @return The optionalFloat.
-       */
-      @java.lang.Override
-      public float getOptionalFloat() {
-        return instance.getOptionalFloat();
-      }
-      /**
-       * <code>optional float optional_float = 11;</code>
-       * @param value The optionalFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalFloat(float value) {
-        copyOnWrite();
-        instance.setOptionalFloat(value);
-        return this;
-      }
-      /**
-       * <code>optional float optional_float = 11;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalFloat() {
-        copyOnWrite();
-        instance.clearOptionalFloat();
-        return this;
-      }
-
-      /**
-       * <code>optional double optional_double = 12;</code>
-       * @return Whether the optionalDouble field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalDouble() {
-        return instance.hasOptionalDouble();
-      }
-      /**
-       * <code>optional double optional_double = 12;</code>
-       * @return The optionalDouble.
-       */
-      @java.lang.Override
-      public double getOptionalDouble() {
-        return instance.getOptionalDouble();
-      }
-      /**
-       * <code>optional double optional_double = 12;</code>
-       * @param value The optionalDouble to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalDouble(double value) {
-        copyOnWrite();
-        instance.setOptionalDouble(value);
-        return this;
-      }
-      /**
-       * <code>optional double optional_double = 12;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalDouble() {
-        copyOnWrite();
-        instance.clearOptionalDouble();
-        return this;
-      }
-
-      /**
-       * <code>optional bool optional_bool = 13;</code>
-       * @return Whether the optionalBool field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalBool() {
-        return instance.hasOptionalBool();
-      }
-      /**
-       * <code>optional bool optional_bool = 13;</code>
-       * @return The optionalBool.
-       */
-      @java.lang.Override
-      public boolean getOptionalBool() {
-        return instance.getOptionalBool();
-      }
-      /**
-       * <code>optional bool optional_bool = 13;</code>
-       * @param value The optionalBool to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalBool(boolean value) {
-        copyOnWrite();
-        instance.setOptionalBool(value);
-        return this;
-      }
-      /**
-       * <code>optional bool optional_bool = 13;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalBool() {
-        copyOnWrite();
-        instance.clearOptionalBool();
-        return this;
-      }
-
-      /**
-       * <code>optional string optional_string = 14;</code>
-       * @return Whether the optionalString field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalString() {
-        return instance.hasOptionalString();
-      }
-      /**
-       * <code>optional string optional_string = 14;</code>
-       * @return The optionalString.
-       */
-      @java.lang.Override
-      public java.lang.String getOptionalString() {
-        return instance.getOptionalString();
-      }
-      /**
-       * <code>optional string optional_string = 14;</code>
-       * @return The bytes for optionalString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getOptionalStringBytes() {
-        return instance.getOptionalStringBytes();
-      }
-      /**
-       * <code>optional string optional_string = 14;</code>
-       * @param value The optionalString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setOptionalString(value);
-        return this;
-      }
-      /**
-       * <code>optional string optional_string = 14;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalString() {
-        copyOnWrite();
-        instance.clearOptionalString();
-        return this;
-      }
-      /**
-       * <code>optional string optional_string = 14;</code>
-       * @param value The bytes for optionalString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOptionalStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional bytes optional_bytes = 15;</code>
-       * @return Whether the optionalBytes field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalBytes() {
-        return instance.hasOptionalBytes();
-      }
-      /**
-       * <code>optional bytes optional_bytes = 15;</code>
-       * @return The optionalBytes.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getOptionalBytes() {
-        return instance.getOptionalBytes();
-      }
-      /**
-       * <code>optional bytes optional_bytes = 15;</code>
-       * @param value The optionalBytes to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalBytes(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOptionalBytes(value);
-        return this;
-      }
-      /**
-       * <code>optional bytes optional_bytes = 15;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalBytes() {
-        copyOnWrite();
-        instance.clearOptionalBytes();
-        return this;
-      }
-
-      /**
-       * <code>optional group OptionalGroup = 16 { ... }</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalGroup() {
-        return instance.hasOptionalGroup();
-      }
-      /**
-       * <code>optional group OptionalGroup = 16 { ... }</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup getOptionalGroup() {
-        return instance.getOptionalGroup();
-      }
-      /**
-       * <code>optional group OptionalGroup = 16 { ... }</code>
-       */
-      public Builder setOptionalGroup(protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup value) {
-        copyOnWrite();
-        instance.setOptionalGroup(value);
-        return this;
-        }
-      /**
-       * <code>optional group OptionalGroup = 16 { ... }</code>
-       */
-      public Builder setOptionalGroup(
-          protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalGroup(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional group OptionalGroup = 16 { ... }</code>
-       */
-      public Builder mergeOptionalGroup(protobuf_unittest.UnittestProto.TestAllTypes.OptionalGroup value) {
-        copyOnWrite();
-        instance.mergeOptionalGroup(value);
-        return this;
-      }
-      /**
-       * <code>optional group OptionalGroup = 16 { ... }</code>
-       */
-      public Builder clearOptionalGroup() {  copyOnWrite();
-        instance.clearOptionalGroup();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalNestedMessage() {
-        return instance.hasOptionalNestedMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage getOptionalNestedMessage() {
-        return instance.getOptionalNestedMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-       */
-      public Builder setOptionalNestedMessage(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.setOptionalNestedMessage(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-       */
-      public Builder setOptionalNestedMessage(
-          protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalNestedMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-       */
-      public Builder mergeOptionalNestedMessage(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.mergeOptionalNestedMessage(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_nested_message = 18;</code>
-       */
-      public Builder clearOptionalNestedMessage() {  copyOnWrite();
-        instance.clearOptionalNestedMessage();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage optional_foreign_message = 19;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalForeignMessage() {
-        return instance.hasOptionalForeignMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage optional_foreign_message = 19;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.ForeignMessage getOptionalForeignMessage() {
-        return instance.getOptionalForeignMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage optional_foreign_message = 19;</code>
-       */
-      public Builder setOptionalForeignMessage(protobuf_unittest.UnittestProto.ForeignMessage value) {
-        copyOnWrite();
-        instance.setOptionalForeignMessage(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage optional_foreign_message = 19;</code>
-       */
-      public Builder setOptionalForeignMessage(
-          protobuf_unittest.UnittestProto.ForeignMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalForeignMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage optional_foreign_message = 19;</code>
-       */
-      public Builder mergeOptionalForeignMessage(protobuf_unittest.UnittestProto.ForeignMessage value) {
-        copyOnWrite();
-        instance.mergeOptionalForeignMessage(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage optional_foreign_message = 19;</code>
-       */
-      public Builder clearOptionalForeignMessage() {  copyOnWrite();
-        instance.clearOptionalForeignMessage();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalImportMessage() {
-        return instance.hasOptionalImportMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.test.UnittestImport.ImportMessage getOptionalImportMessage() {
-        return instance.getOptionalImportMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-       */
-      public Builder setOptionalImportMessage(com.google.protobuf.test.UnittestImport.ImportMessage value) {
-        copyOnWrite();
-        instance.setOptionalImportMessage(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-       */
-      public Builder setOptionalImportMessage(
-          com.google.protobuf.test.UnittestImport.ImportMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalImportMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-       */
-      public Builder mergeOptionalImportMessage(com.google.protobuf.test.UnittestImport.ImportMessage value) {
-        copyOnWrite();
-        instance.mergeOptionalImportMessage(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportMessage optional_import_message = 20;</code>
-       */
-      public Builder clearOptionalImportMessage() {  copyOnWrite();
-        instance.clearOptionalImportMessage();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-       * @return Whether the optionalNestedEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalNestedEnum() {
-        return instance.hasOptionalNestedEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-       * @return The optionalNestedEnum.
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum getOptionalNestedEnum() {
-        return instance.getOptionalNestedEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-       * @param value The enum numeric value on the wire for optionalNestedEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalNestedEnum(protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum value) {
-        copyOnWrite();
-        instance.setOptionalNestedEnum(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum optional_nested_enum = 21;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalNestedEnum() {
-        copyOnWrite();
-        instance.clearOptionalNestedEnum();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-       * @return Whether the optionalForeignEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalForeignEnum() {
-        return instance.hasOptionalForeignEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-       * @return The optionalForeignEnum.
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.ForeignEnum getOptionalForeignEnum() {
-        return instance.getOptionalForeignEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-       * @param value The enum numeric value on the wire for optionalForeignEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalForeignEnum(protobuf_unittest.UnittestProto.ForeignEnum value) {
-        copyOnWrite();
-        instance.setOptionalForeignEnum(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalForeignEnum() {
-        copyOnWrite();
-        instance.clearOptionalForeignEnum();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest_import.ImportEnum optional_import_enum = 23;</code>
-       * @return Whether the optionalImportEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalImportEnum() {
-        return instance.hasOptionalImportEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportEnum optional_import_enum = 23;</code>
-       * @return The optionalImportEnum.
-       */
-      @java.lang.Override
-      public com.google.protobuf.test.UnittestImport.ImportEnum getOptionalImportEnum() {
-        return instance.getOptionalImportEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportEnum optional_import_enum = 23;</code>
-       * @param value The enum numeric value on the wire for optionalImportEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalImportEnum(com.google.protobuf.test.UnittestImport.ImportEnum value) {
-        copyOnWrite();
-        instance.setOptionalImportEnum(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportEnum optional_import_enum = 23;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalImportEnum() {
-        copyOnWrite();
-        instance.clearOptionalImportEnum();
-        return this;
-      }
-
-      /**
-       * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-       * @return Whether the optionalStringPiece field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalStringPiece() {
-        return instance.hasOptionalStringPiece();
-      }
-      /**
-       * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-       * @return The optionalStringPiece.
-       */
-      @java.lang.Override
-      public java.lang.String getOptionalStringPiece() {
-        return instance.getOptionalStringPiece();
-      }
-      /**
-       * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-       * @return The bytes for optionalStringPiece.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getOptionalStringPieceBytes() {
-        return instance.getOptionalStringPieceBytes();
-      }
-      /**
-       * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-       * @param value The optionalStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalStringPiece(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setOptionalStringPiece(value);
-        return this;
-      }
-      /**
-       * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalStringPiece() {
-        copyOnWrite();
-        instance.clearOptionalStringPiece();
-        return this;
-      }
-      /**
-       * <code>optional string optional_string_piece = 24 [ctype = STRING_PIECE];</code>
-       * @param value The bytes for optionalStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalStringPieceBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOptionalStringPieceBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-       * @return Whether the optionalCord field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalCord() {
-        return instance.hasOptionalCord();
-      }
-      /**
-       * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-       * @return The optionalCord.
-       */
-      @java.lang.Override
-      public java.lang.String getOptionalCord() {
-        return instance.getOptionalCord();
-      }
-      /**
-       * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-       * @return The bytes for optionalCord.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getOptionalCordBytes() {
-        return instance.getOptionalCordBytes();
-      }
-      /**
-       * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-       * @param value The optionalCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalCord(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setOptionalCord(value);
-        return this;
-      }
-      /**
-       * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalCord() {
-        copyOnWrite();
-        instance.clearOptionalCord();
-        return this;
-      }
-      /**
-       * <code>optional string optional_cord = 25 [ctype = CORD];</code>
-       * @param value The bytes for optionalCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalCordBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOptionalCordBytes(value);
-        return this;
-      }
-
-      /**
-       * <pre>
-       * Defined in unittest_import_public.proto
-       * </pre>
-       *
-       * <code>optional .protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalPublicImportMessage() {
-        return instance.hasOptionalPublicImportMessage();
-      }
-      /**
-       * <pre>
-       * Defined in unittest_import_public.proto
-       * </pre>
-       *
-       * <code>optional .protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.test.UnittestImportPublic.PublicImportMessage getOptionalPublicImportMessage() {
-        return instance.getOptionalPublicImportMessage();
-      }
-      /**
-       * <pre>
-       * Defined in unittest_import_public.proto
-       * </pre>
-       *
-       * <code>optional .protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-       */
-      public Builder setOptionalPublicImportMessage(com.google.protobuf.test.UnittestImportPublic.PublicImportMessage value) {
-        copyOnWrite();
-        instance.setOptionalPublicImportMessage(value);
-        return this;
-        }
-      /**
-       * <pre>
-       * Defined in unittest_import_public.proto
-       * </pre>
-       *
-       * <code>optional .protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-       */
-      public Builder setOptionalPublicImportMessage(
-          com.google.protobuf.test.UnittestImportPublic.PublicImportMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalPublicImportMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <pre>
-       * Defined in unittest_import_public.proto
-       * </pre>
-       *
-       * <code>optional .protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-       */
-      public Builder mergeOptionalPublicImportMessage(com.google.protobuf.test.UnittestImportPublic.PublicImportMessage value) {
-        copyOnWrite();
-        instance.mergeOptionalPublicImportMessage(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Defined in unittest_import_public.proto
-       * </pre>
-       *
-       * <code>optional .protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26;</code>
-       */
-      public Builder clearOptionalPublicImportMessage() {  copyOnWrite();
-        instance.clearOptionalPublicImportMessage();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalLazyMessage() {
-        return instance.hasOptionalLazyMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage getOptionalLazyMessage() {
-        return instance.getOptionalLazyMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-       */
-      public Builder setOptionalLazyMessage(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.setOptionalLazyMessage(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-       */
-      public Builder setOptionalLazyMessage(
-          protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalLazyMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-       */
-      public Builder mergeOptionalLazyMessage(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.mergeOptionalLazyMessage(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage optional_lazy_message = 27 [lazy = true];</code>
-       */
-      public Builder clearOptionalLazyMessage() {  copyOnWrite();
-        instance.clearOptionalLazyMessage();
-        return this;
-      }
-
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @return A list containing the repeatedInt32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedInt32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedInt32List());
-      }
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @return The count of repeatedInt32.
-       */
-      @java.lang.Override
-      public int getRepeatedInt32Count() {
-        return instance.getRepeatedInt32Count();
-      }
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedInt32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedInt32(int index) {
-        return instance.getRepeatedInt32(index);
-      }
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @param value The repeatedInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedInt32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedInt32(index, value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @param value The repeatedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedInt32(int value) {
-        copyOnWrite();
-        instance.addRepeatedInt32(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @param values The repeatedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedInt32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedInt32(values);
-        return this;
-      }
-      /**
-       * <pre>
-       * Repeated
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 31;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedInt32() {
-        copyOnWrite();
-        instance.clearRepeatedInt32();
-        return this;
-      }
-
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @return A list containing the repeatedInt64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedInt64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedInt64List());
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @return The count of repeatedInt64.
-       */
-      @java.lang.Override
-      public int getRepeatedInt64Count() {
-        return instance.getRepeatedInt64Count();
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedInt64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedInt64(int index) {
-        return instance.getRepeatedInt64(index);
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @param value The repeatedInt64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedInt64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedInt64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @param value The repeatedInt64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedInt64(long value) {
-        copyOnWrite();
-        instance.addRepeatedInt64(value);
-        return this;
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @param values The repeatedInt64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedInt64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedInt64(values);
-        return this;
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 32;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedInt64() {
-        copyOnWrite();
-        instance.clearRepeatedInt64();
-        return this;
-      }
-
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @return A list containing the repeatedUint32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedUint32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedUint32List());
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @return The count of repeatedUint32.
-       */
-      @java.lang.Override
-      public int getRepeatedUint32Count() {
-        return instance.getRepeatedUint32Count();
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedUint32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedUint32(int index) {
-        return instance.getRepeatedUint32(index);
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @param value The repeatedUint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedUint32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedUint32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @param value The repeatedUint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedUint32(int value) {
-        copyOnWrite();
-        instance.addRepeatedUint32(value);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @param values The repeatedUint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedUint32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedUint32(values);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 repeated_uint32 = 33;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedUint32() {
-        copyOnWrite();
-        instance.clearRepeatedUint32();
-        return this;
-      }
-
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @return A list containing the repeatedUint64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedUint64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedUint64List());
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @return The count of repeatedUint64.
-       */
-      @java.lang.Override
-      public int getRepeatedUint64Count() {
-        return instance.getRepeatedUint64Count();
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedUint64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedUint64(int index) {
-        return instance.getRepeatedUint64(index);
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @param value The repeatedUint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedUint64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedUint64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @param value The repeatedUint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedUint64(long value) {
-        copyOnWrite();
-        instance.addRepeatedUint64(value);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @param values The repeatedUint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedUint64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedUint64(values);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 34;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedUint64() {
-        copyOnWrite();
-        instance.clearRepeatedUint64();
-        return this;
-      }
-
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @return A list containing the repeatedSint32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedSint32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedSint32List());
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @return The count of repeatedSint32.
-       */
-      @java.lang.Override
-      public int getRepeatedSint32Count() {
-        return instance.getRepeatedSint32Count();
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedSint32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedSint32(int index) {
-        return instance.getRepeatedSint32(index);
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @param value The repeatedSint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedSint32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedSint32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @param value The repeatedSint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedSint32(int value) {
-        copyOnWrite();
-        instance.addRepeatedSint32(value);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @param values The repeatedSint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedSint32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedSint32(values);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 repeated_sint32 = 35;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedSint32() {
-        copyOnWrite();
-        instance.clearRepeatedSint32();
-        return this;
-      }
-
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @return A list containing the repeatedSint64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedSint64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedSint64List());
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @return The count of repeatedSint64.
-       */
-      @java.lang.Override
-      public int getRepeatedSint64Count() {
-        return instance.getRepeatedSint64Count();
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedSint64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedSint64(int index) {
-        return instance.getRepeatedSint64(index);
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @param value The repeatedSint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedSint64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedSint64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @param value The repeatedSint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedSint64(long value) {
-        copyOnWrite();
-        instance.addRepeatedSint64(value);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @param values The repeatedSint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedSint64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedSint64(values);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 repeated_sint64 = 36;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedSint64() {
-        copyOnWrite();
-        instance.clearRepeatedSint64();
-        return this;
-      }
-
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @return A list containing the repeatedFixed32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedFixed32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedFixed32List());
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @return The count of repeatedFixed32.
-       */
-      @java.lang.Override
-      public int getRepeatedFixed32Count() {
-        return instance.getRepeatedFixed32Count();
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedFixed32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedFixed32(int index) {
-        return instance.getRepeatedFixed32(index);
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @param value The repeatedFixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedFixed32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedFixed32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @param value The repeatedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedFixed32(int value) {
-        copyOnWrite();
-        instance.addRepeatedFixed32(value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @param values The repeatedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedFixed32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedFixed32(values);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 repeated_fixed32 = 37;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedFixed32() {
-        copyOnWrite();
-        instance.clearRepeatedFixed32();
-        return this;
-      }
-
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @return A list containing the repeatedFixed64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedFixed64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedFixed64List());
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @return The count of repeatedFixed64.
-       */
-      @java.lang.Override
-      public int getRepeatedFixed64Count() {
-        return instance.getRepeatedFixed64Count();
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedFixed64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedFixed64(int index) {
-        return instance.getRepeatedFixed64(index);
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @param value The repeatedFixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedFixed64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedFixed64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @param value The repeatedFixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedFixed64(long value) {
-        copyOnWrite();
-        instance.addRepeatedFixed64(value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @param values The repeatedFixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedFixed64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedFixed64(values);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 repeated_fixed64 = 38;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedFixed64() {
-        copyOnWrite();
-        instance.clearRepeatedFixed64();
-        return this;
-      }
-
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @return A list containing the repeatedSfixed32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedSfixed32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedSfixed32List());
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @return The count of repeatedSfixed32.
-       */
-      @java.lang.Override
-      public int getRepeatedSfixed32Count() {
-        return instance.getRepeatedSfixed32Count();
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedSfixed32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedSfixed32(int index) {
-        return instance.getRepeatedSfixed32(index);
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @param value The repeatedSfixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedSfixed32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedSfixed32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @param value The repeatedSfixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedSfixed32(int value) {
-        copyOnWrite();
-        instance.addRepeatedSfixed32(value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @param values The repeatedSfixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedSfixed32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedSfixed32(values);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 repeated_sfixed32 = 39;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedSfixed32() {
-        copyOnWrite();
-        instance.clearRepeatedSfixed32();
-        return this;
-      }
-
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @return A list containing the repeatedSfixed64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedSfixed64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedSfixed64List());
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @return The count of repeatedSfixed64.
-       */
-      @java.lang.Override
-      public int getRepeatedSfixed64Count() {
-        return instance.getRepeatedSfixed64Count();
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedSfixed64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedSfixed64(int index) {
-        return instance.getRepeatedSfixed64(index);
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @param value The repeatedSfixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedSfixed64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedSfixed64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @param value The repeatedSfixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedSfixed64(long value) {
-        copyOnWrite();
-        instance.addRepeatedSfixed64(value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @param values The repeatedSfixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedSfixed64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedSfixed64(values);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 repeated_sfixed64 = 40;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedSfixed64() {
-        copyOnWrite();
-        instance.clearRepeatedSfixed64();
-        return this;
-      }
-
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @return A list containing the repeatedFloat.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Float>
-          getRepeatedFloatList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedFloatList());
-      }
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @return The count of repeatedFloat.
-       */
-      @java.lang.Override
-      public int getRepeatedFloatCount() {
-        return instance.getRepeatedFloatCount();
-      }
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedFloat at the given index.
-       */
-      @java.lang.Override
-      public float getRepeatedFloat(int index) {
-        return instance.getRepeatedFloat(index);
-      }
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @param value The repeatedFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedFloat(
-          int index, float value) {
-        copyOnWrite();
-        instance.setRepeatedFloat(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @param value The repeatedFloat to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedFloat(float value) {
-        copyOnWrite();
-        instance.addRepeatedFloat(value);
-        return this;
-      }
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @param values The repeatedFloat to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedFloat(
-          java.lang.Iterable<? extends java.lang.Float> values) {
-        copyOnWrite();
-        instance.addAllRepeatedFloat(values);
-        return this;
-      }
-      /**
-       * <code>repeated float repeated_float = 41;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedFloat() {
-        copyOnWrite();
-        instance.clearRepeatedFloat();
-        return this;
-      }
-
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @return A list containing the repeatedDouble.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Double>
-          getRepeatedDoubleList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedDoubleList());
-      }
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @return The count of repeatedDouble.
-       */
-      @java.lang.Override
-      public int getRepeatedDoubleCount() {
-        return instance.getRepeatedDoubleCount();
-      }
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedDouble at the given index.
-       */
-      @java.lang.Override
-      public double getRepeatedDouble(int index) {
-        return instance.getRepeatedDouble(index);
-      }
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @param value The repeatedDouble to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedDouble(
-          int index, double value) {
-        copyOnWrite();
-        instance.setRepeatedDouble(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @param value The repeatedDouble to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedDouble(double value) {
-        copyOnWrite();
-        instance.addRepeatedDouble(value);
-        return this;
-      }
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @param values The repeatedDouble to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedDouble(
-          java.lang.Iterable<? extends java.lang.Double> values) {
-        copyOnWrite();
-        instance.addAllRepeatedDouble(values);
-        return this;
-      }
-      /**
-       * <code>repeated double repeated_double = 42;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedDouble() {
-        copyOnWrite();
-        instance.clearRepeatedDouble();
-        return this;
-      }
-
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @return A list containing the repeatedBool.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Boolean>
-          getRepeatedBoolList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedBoolList());
-      }
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @return The count of repeatedBool.
-       */
-      @java.lang.Override
-      public int getRepeatedBoolCount() {
-        return instance.getRepeatedBoolCount();
-      }
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedBool at the given index.
-       */
-      @java.lang.Override
-      public boolean getRepeatedBool(int index) {
-        return instance.getRepeatedBool(index);
-      }
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @param value The repeatedBool to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedBool(
-          int index, boolean value) {
-        copyOnWrite();
-        instance.setRepeatedBool(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @param value The repeatedBool to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedBool(boolean value) {
-        copyOnWrite();
-        instance.addRepeatedBool(value);
-        return this;
-      }
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @param values The repeatedBool to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedBool(
-          java.lang.Iterable<? extends java.lang.Boolean> values) {
-        copyOnWrite();
-        instance.addAllRepeatedBool(values);
-        return this;
-      }
-      /**
-       * <code>repeated bool repeated_bool = 43;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedBool() {
-        copyOnWrite();
-        instance.clearRepeatedBool();
-        return this;
-      }
-
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @return A list containing the repeatedString.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getRepeatedStringList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedStringList());
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @return The count of repeatedString.
-       */
-      @java.lang.Override
-      public int getRepeatedStringCount() {
-        return instance.getRepeatedStringCount();
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedString at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getRepeatedString(int index) {
-        return instance.getRepeatedString(index);
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the repeatedString at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getRepeatedStringBytes(int index) {
-        return instance.getRepeatedStringBytes(index);
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedString(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setRepeatedString(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @param value The repeatedString to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addRepeatedString(value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @param values The repeatedString to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedString(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllRepeatedString(values);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedString() {
-        copyOnWrite();
-        instance.clearRepeatedString();
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string = 44;</code>
-       * @param value The bytes of the repeatedString to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addRepeatedStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @return A list containing the repeatedBytes.
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.ByteString>
-          getRepeatedBytesList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedBytesList());
-      }
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @return The count of repeatedBytes.
-       */
-      @java.lang.Override
-      public int getRepeatedBytesCount() {
-        return instance.getRepeatedBytesCount();
-      }
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedBytes at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getRepeatedBytes(int index) {
-        return instance.getRepeatedBytes(index);
-      }
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @param value The repeatedBytes to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedBytes(
-          int index, com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setRepeatedBytes(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @param value The repeatedBytes to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedBytes(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addRepeatedBytes(value);
-        return this;
-      }
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @param values The repeatedBytes to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedBytes(
-          java.lang.Iterable<? extends com.google.protobuf.ByteString> values) {
-        copyOnWrite();
-        instance.addAllRepeatedBytes(values);
-        return this;
-      }
-      /**
-       * <code>repeated bytes repeated_bytes = 45;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedBytes() {
-        copyOnWrite();
-        instance.clearRepeatedBytes();
-        return this;
-      }
-
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup> getRepeatedGroupList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedGroupList());
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      @java.lang.Override
-      public int getRepeatedGroupCount() {
-        return instance.getRepeatedGroupCount();
-      }/**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup getRepeatedGroup(int index) {
-        return instance.getRepeatedGroup(index);
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      public Builder setRepeatedGroup(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup value) {
-        copyOnWrite();
-        instance.setRepeatedGroup(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      public Builder setRepeatedGroup(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedGroup(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      public Builder addRepeatedGroup(protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup value) {
-        copyOnWrite();
-        instance.addRepeatedGroup(value);
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      public Builder addRepeatedGroup(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup value) {
-        copyOnWrite();
-        instance.addRepeatedGroup(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      public Builder addRepeatedGroup(
-          protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedGroup(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      public Builder addRepeatedGroup(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedGroup(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      public Builder addAllRepeatedGroup(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup> values) {
-        copyOnWrite();
-        instance.addAllRepeatedGroup(values);
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      public Builder clearRepeatedGroup() {
-        copyOnWrite();
-        instance.clearRepeatedGroup();
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 46 { ... }</code>
-       */
-      public Builder removeRepeatedGroup(int index) {
-        copyOnWrite();
-        instance.removeRepeatedGroup(index);
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage> getRepeatedNestedMessageList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedNestedMessageList());
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      @java.lang.Override
-      public int getRepeatedNestedMessageCount() {
-        return instance.getRepeatedNestedMessageCount();
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage getRepeatedNestedMessage(int index) {
-        return instance.getRepeatedNestedMessage(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder setRepeatedNestedMessage(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.setRepeatedNestedMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder setRepeatedNestedMessage(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedNestedMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder addRepeatedNestedMessage(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.addRepeatedNestedMessage(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder addRepeatedNestedMessage(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.addRepeatedNestedMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder addRepeatedNestedMessage(
-          protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedNestedMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder addRepeatedNestedMessage(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedNestedMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder addAllRepeatedNestedMessage(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage> values) {
-        copyOnWrite();
-        instance.addAllRepeatedNestedMessage(values);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder clearRepeatedNestedMessage() {
-        copyOnWrite();
-        instance.clearRepeatedNestedMessage();
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_nested_message = 48;</code>
-       */
-      public Builder removeRepeatedNestedMessage(int index) {
-        copyOnWrite();
-        instance.removeRepeatedNestedMessage(index);
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.ForeignMessage> getRepeatedForeignMessageList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedForeignMessageList());
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      @java.lang.Override
-      public int getRepeatedForeignMessageCount() {
-        return instance.getRepeatedForeignMessageCount();
-      }/**
-       * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.ForeignMessage getRepeatedForeignMessage(int index) {
-        return instance.getRepeatedForeignMessage(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      public Builder setRepeatedForeignMessage(
-          int index, protobuf_unittest.UnittestProto.ForeignMessage value) {
-        copyOnWrite();
-        instance.setRepeatedForeignMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      public Builder setRepeatedForeignMessage(
-          int index, protobuf_unittest.UnittestProto.ForeignMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedForeignMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      public Builder addRepeatedForeignMessage(protobuf_unittest.UnittestProto.ForeignMessage value) {
-        copyOnWrite();
-        instance.addRepeatedForeignMessage(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      public Builder addRepeatedForeignMessage(
-          int index, protobuf_unittest.UnittestProto.ForeignMessage value) {
-        copyOnWrite();
-        instance.addRepeatedForeignMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      public Builder addRepeatedForeignMessage(
-          protobuf_unittest.UnittestProto.ForeignMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedForeignMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      public Builder addRepeatedForeignMessage(
-          int index, protobuf_unittest.UnittestProto.ForeignMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedForeignMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      public Builder addAllRepeatedForeignMessage(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.ForeignMessage> values) {
-        copyOnWrite();
-        instance.addAllRepeatedForeignMessage(values);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      public Builder clearRepeatedForeignMessage() {
-        copyOnWrite();
-        instance.clearRepeatedForeignMessage();
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage repeated_foreign_message = 49;</code>
-       */
-      public Builder removeRepeatedForeignMessage(int index) {
-        copyOnWrite();
-        instance.removeRepeatedForeignMessage(index);
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.test.UnittestImport.ImportMessage> getRepeatedImportMessageList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedImportMessageList());
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      @java.lang.Override
-      public int getRepeatedImportMessageCount() {
-        return instance.getRepeatedImportMessageCount();
-      }/**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      @java.lang.Override
-      public com.google.protobuf.test.UnittestImport.ImportMessage getRepeatedImportMessage(int index) {
-        return instance.getRepeatedImportMessage(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      public Builder setRepeatedImportMessage(
-          int index, com.google.protobuf.test.UnittestImport.ImportMessage value) {
-        copyOnWrite();
-        instance.setRepeatedImportMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      public Builder setRepeatedImportMessage(
-          int index, com.google.protobuf.test.UnittestImport.ImportMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedImportMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      public Builder addRepeatedImportMessage(com.google.protobuf.test.UnittestImport.ImportMessage value) {
-        copyOnWrite();
-        instance.addRepeatedImportMessage(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      public Builder addRepeatedImportMessage(
-          int index, com.google.protobuf.test.UnittestImport.ImportMessage value) {
-        copyOnWrite();
-        instance.addRepeatedImportMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      public Builder addRepeatedImportMessage(
-          com.google.protobuf.test.UnittestImport.ImportMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedImportMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      public Builder addRepeatedImportMessage(
-          int index, com.google.protobuf.test.UnittestImport.ImportMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedImportMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      public Builder addAllRepeatedImportMessage(
-          java.lang.Iterable<? extends com.google.protobuf.test.UnittestImport.ImportMessage> values) {
-        copyOnWrite();
-        instance.addAllRepeatedImportMessage(values);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      public Builder clearRepeatedImportMessage() {
-        copyOnWrite();
-        instance.clearRepeatedImportMessage();
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportMessage repeated_import_message = 50;</code>
-       */
-      public Builder removeRepeatedImportMessage(int index) {
-        copyOnWrite();
-        instance.removeRepeatedImportMessage(index);
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-       * @return A list containing the repeatedNestedEnum.
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum> getRepeatedNestedEnumList() {
-        return instance.getRepeatedNestedEnumList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-       * @return The count of repeatedNestedEnum.
-       */
-      @java.lang.Override
-      public int getRepeatedNestedEnumCount() {
-        return instance.getRepeatedNestedEnumCount();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedNestedEnum at the given index.
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum getRepeatedNestedEnum(int index) {
-        return instance.getRepeatedNestedEnum(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedNestedEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedNestedEnum(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum value) {
-        copyOnWrite();
-        instance.setRepeatedNestedEnum(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-       * @param value The repeatedNestedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedNestedEnum(protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum value) {
-        copyOnWrite();
-        instance.addRepeatedNestedEnum(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-       * @param values The repeatedNestedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedNestedEnum(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum> values) {
-        copyOnWrite();
-        instance.addAllRepeatedNestedEnum(values);  return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedEnum repeated_nested_enum = 51;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedNestedEnum() {
-        copyOnWrite();
-        instance.clearRepeatedNestedEnum();
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-       * @return A list containing the repeatedForeignEnum.
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.ForeignEnum> getRepeatedForeignEnumList() {
-        return instance.getRepeatedForeignEnumList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-       * @return The count of repeatedForeignEnum.
-       */
-      @java.lang.Override
-      public int getRepeatedForeignEnumCount() {
-        return instance.getRepeatedForeignEnumCount();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedForeignEnum at the given index.
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.ForeignEnum getRepeatedForeignEnum(int index) {
-        return instance.getRepeatedForeignEnum(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedForeignEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedForeignEnum(
-          int index, protobuf_unittest.UnittestProto.ForeignEnum value) {
-        copyOnWrite();
-        instance.setRepeatedForeignEnum(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-       * @param value The repeatedForeignEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedForeignEnum(protobuf_unittest.UnittestProto.ForeignEnum value) {
-        copyOnWrite();
-        instance.addRepeatedForeignEnum(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-       * @param values The repeatedForeignEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedForeignEnum(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.ForeignEnum> values) {
-        copyOnWrite();
-        instance.addAllRepeatedForeignEnum(values);  return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum repeated_foreign_enum = 52;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedForeignEnum() {
-        copyOnWrite();
-        instance.clearRepeatedForeignEnum();
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportEnum repeated_import_enum = 53;</code>
-       * @return A list containing the repeatedImportEnum.
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.test.UnittestImport.ImportEnum> getRepeatedImportEnumList() {
-        return instance.getRepeatedImportEnumList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportEnum repeated_import_enum = 53;</code>
-       * @return The count of repeatedImportEnum.
-       */
-      @java.lang.Override
-      public int getRepeatedImportEnumCount() {
-        return instance.getRepeatedImportEnumCount();
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportEnum repeated_import_enum = 53;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedImportEnum at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.test.UnittestImport.ImportEnum getRepeatedImportEnum(int index) {
-        return instance.getRepeatedImportEnum(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportEnum repeated_import_enum = 53;</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedImportEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedImportEnum(
-          int index, com.google.protobuf.test.UnittestImport.ImportEnum value) {
-        copyOnWrite();
-        instance.setRepeatedImportEnum(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportEnum repeated_import_enum = 53;</code>
-       * @param value The repeatedImportEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedImportEnum(com.google.protobuf.test.UnittestImport.ImportEnum value) {
-        copyOnWrite();
-        instance.addRepeatedImportEnum(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportEnum repeated_import_enum = 53;</code>
-       * @param values The repeatedImportEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedImportEnum(
-          java.lang.Iterable<? extends com.google.protobuf.test.UnittestImport.ImportEnum> values) {
-        copyOnWrite();
-        instance.addAllRepeatedImportEnum(values);  return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest_import.ImportEnum repeated_import_enum = 53;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedImportEnum() {
-        copyOnWrite();
-        instance.clearRepeatedImportEnum();
-        return this;
-      }
-
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @return A list containing the repeatedStringPiece.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getRepeatedStringPieceList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedStringPieceList());
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @return The count of repeatedStringPiece.
-       */
-      @java.lang.Override
-      public int getRepeatedStringPieceCount() {
-        return instance.getRepeatedStringPieceCount();
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedStringPiece at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getRepeatedStringPiece(int index) {
-        return instance.getRepeatedStringPiece(index);
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the repeatedStringPiece at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getRepeatedStringPieceBytes(int index) {
-        return instance.getRepeatedStringPieceBytes(index);
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedStringPiece(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setRepeatedStringPiece(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @param value The repeatedStringPiece to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedStringPiece(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addRepeatedStringPiece(value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @param values The repeatedStringPiece to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedStringPiece(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllRepeatedStringPiece(values);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedStringPiece() {
-        copyOnWrite();
-        instance.clearRepeatedStringPiece();
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];</code>
-       * @param value The bytes of the repeatedStringPiece to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedStringPieceBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addRepeatedStringPieceBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @return A list containing the repeatedCord.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getRepeatedCordList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedCordList());
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @return The count of repeatedCord.
-       */
-      @java.lang.Override
-      public int getRepeatedCordCount() {
-        return instance.getRepeatedCordCount();
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedCord at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getRepeatedCord(int index) {
-        return instance.getRepeatedCord(index);
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the repeatedCord at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getRepeatedCordBytes(int index) {
-        return instance.getRepeatedCordBytes(index);
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedCord(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setRepeatedCord(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @param value The repeatedCord to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedCord(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addRepeatedCord(value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @param values The repeatedCord to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedCord(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllRepeatedCord(values);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedCord() {
-        copyOnWrite();
-        instance.clearRepeatedCord();
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_cord = 55 [ctype = CORD];</code>
-       * @param value The bytes of the repeatedCord to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedCordBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addRepeatedCordBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage> getRepeatedLazyMessageList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedLazyMessageList());
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public int getRepeatedLazyMessageCount() {
-        return instance.getRepeatedLazyMessageCount();
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage getRepeatedLazyMessage(int index) {
-        return instance.getRepeatedLazyMessage(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder setRepeatedLazyMessage(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.setRepeatedLazyMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder setRepeatedLazyMessage(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedLazyMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder addRepeatedLazyMessage(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.addRepeatedLazyMessage(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder addRepeatedLazyMessage(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.addRepeatedLazyMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder addRepeatedLazyMessage(
-          protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedLazyMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder addRepeatedLazyMessage(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedLazyMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder addAllRepeatedLazyMessage(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage> values) {
-        copyOnWrite();
-        instance.addAllRepeatedLazyMessage(values);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder clearRepeatedLazyMessage() {
-        copyOnWrite();
-        instance.clearRepeatedLazyMessage();
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes.NestedMessage repeated_lazy_message = 57 [lazy = true];</code>
-       */
-      public Builder removeRepeatedLazyMessage(int index) {
-        copyOnWrite();
-        instance.removeRepeatedLazyMessage(index);
-        return this;
-      }
-
-      /**
-       * <pre>
-       * Singular with defaults
-       * </pre>
-       *
-       * <code>optional int32 default_int32 = 61 [default = 41];</code>
-       * @return Whether the defaultInt32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultInt32() {
-        return instance.hasDefaultInt32();
-      }
-      /**
-       * <pre>
-       * Singular with defaults
-       * </pre>
-       *
-       * <code>optional int32 default_int32 = 61 [default = 41];</code>
-       * @return The defaultInt32.
-       */
-      @java.lang.Override
-      public int getDefaultInt32() {
-        return instance.getDefaultInt32();
-      }
-      /**
-       * <pre>
-       * Singular with defaults
-       * </pre>
-       *
-       * <code>optional int32 default_int32 = 61 [default = 41];</code>
-       * @param value The defaultInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultInt32(int value) {
-        copyOnWrite();
-        instance.setDefaultInt32(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Singular with defaults
-       * </pre>
-       *
-       * <code>optional int32 default_int32 = 61 [default = 41];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultInt32() {
-        copyOnWrite();
-        instance.clearDefaultInt32();
-        return this;
-      }
-
-      /**
-       * <code>optional int64 default_int64 = 62 [default = 42];</code>
-       * @return Whether the defaultInt64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultInt64() {
-        return instance.hasDefaultInt64();
-      }
-      /**
-       * <code>optional int64 default_int64 = 62 [default = 42];</code>
-       * @return The defaultInt64.
-       */
-      @java.lang.Override
-      public long getDefaultInt64() {
-        return instance.getDefaultInt64();
-      }
-      /**
-       * <code>optional int64 default_int64 = 62 [default = 42];</code>
-       * @param value The defaultInt64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultInt64(long value) {
-        copyOnWrite();
-        instance.setDefaultInt64(value);
-        return this;
-      }
-      /**
-       * <code>optional int64 default_int64 = 62 [default = 42];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultInt64() {
-        copyOnWrite();
-        instance.clearDefaultInt64();
-        return this;
-      }
-
-      /**
-       * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-       * @return Whether the defaultUint32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultUint32() {
-        return instance.hasDefaultUint32();
-      }
-      /**
-       * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-       * @return The defaultUint32.
-       */
-      @java.lang.Override
-      public int getDefaultUint32() {
-        return instance.getDefaultUint32();
-      }
-      /**
-       * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-       * @param value The defaultUint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultUint32(int value) {
-        copyOnWrite();
-        instance.setDefaultUint32(value);
-        return this;
-      }
-      /**
-       * <code>optional uint32 default_uint32 = 63 [default = 43];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultUint32() {
-        copyOnWrite();
-        instance.clearDefaultUint32();
-        return this;
-      }
-
-      /**
-       * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-       * @return Whether the defaultUint64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultUint64() {
-        return instance.hasDefaultUint64();
-      }
-      /**
-       * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-       * @return The defaultUint64.
-       */
-      @java.lang.Override
-      public long getDefaultUint64() {
-        return instance.getDefaultUint64();
-      }
-      /**
-       * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-       * @param value The defaultUint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultUint64(long value) {
-        copyOnWrite();
-        instance.setDefaultUint64(value);
-        return this;
-      }
-      /**
-       * <code>optional uint64 default_uint64 = 64 [default = 44];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultUint64() {
-        copyOnWrite();
-        instance.clearDefaultUint64();
-        return this;
-      }
-
-      /**
-       * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-       * @return Whether the defaultSint32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultSint32() {
-        return instance.hasDefaultSint32();
-      }
-      /**
-       * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-       * @return The defaultSint32.
-       */
-      @java.lang.Override
-      public int getDefaultSint32() {
-        return instance.getDefaultSint32();
-      }
-      /**
-       * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-       * @param value The defaultSint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultSint32(int value) {
-        copyOnWrite();
-        instance.setDefaultSint32(value);
-        return this;
-      }
-      /**
-       * <code>optional sint32 default_sint32 = 65 [default = -45];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultSint32() {
-        copyOnWrite();
-        instance.clearDefaultSint32();
-        return this;
-      }
-
-      /**
-       * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-       * @return Whether the defaultSint64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultSint64() {
-        return instance.hasDefaultSint64();
-      }
-      /**
-       * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-       * @return The defaultSint64.
-       */
-      @java.lang.Override
-      public long getDefaultSint64() {
-        return instance.getDefaultSint64();
-      }
-      /**
-       * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-       * @param value The defaultSint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultSint64(long value) {
-        copyOnWrite();
-        instance.setDefaultSint64(value);
-        return this;
-      }
-      /**
-       * <code>optional sint64 default_sint64 = 66 [default = 46];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultSint64() {
-        copyOnWrite();
-        instance.clearDefaultSint64();
-        return this;
-      }
-
-      /**
-       * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-       * @return Whether the defaultFixed32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultFixed32() {
-        return instance.hasDefaultFixed32();
-      }
-      /**
-       * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-       * @return The defaultFixed32.
-       */
-      @java.lang.Override
-      public int getDefaultFixed32() {
-        return instance.getDefaultFixed32();
-      }
-      /**
-       * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-       * @param value The defaultFixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultFixed32(int value) {
-        copyOnWrite();
-        instance.setDefaultFixed32(value);
-        return this;
-      }
-      /**
-       * <code>optional fixed32 default_fixed32 = 67 [default = 47];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultFixed32() {
-        copyOnWrite();
-        instance.clearDefaultFixed32();
-        return this;
-      }
-
-      /**
-       * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-       * @return Whether the defaultFixed64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultFixed64() {
-        return instance.hasDefaultFixed64();
-      }
-      /**
-       * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-       * @return The defaultFixed64.
-       */
-      @java.lang.Override
-      public long getDefaultFixed64() {
-        return instance.getDefaultFixed64();
-      }
-      /**
-       * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-       * @param value The defaultFixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultFixed64(long value) {
-        copyOnWrite();
-        instance.setDefaultFixed64(value);
-        return this;
-      }
-      /**
-       * <code>optional fixed64 default_fixed64 = 68 [default = 48];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultFixed64() {
-        copyOnWrite();
-        instance.clearDefaultFixed64();
-        return this;
-      }
-
-      /**
-       * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-       * @return Whether the defaultSfixed32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultSfixed32() {
-        return instance.hasDefaultSfixed32();
-      }
-      /**
-       * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-       * @return The defaultSfixed32.
-       */
-      @java.lang.Override
-      public int getDefaultSfixed32() {
-        return instance.getDefaultSfixed32();
-      }
-      /**
-       * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-       * @param value The defaultSfixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultSfixed32(int value) {
-        copyOnWrite();
-        instance.setDefaultSfixed32(value);
-        return this;
-      }
-      /**
-       * <code>optional sfixed32 default_sfixed32 = 69 [default = 49];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultSfixed32() {
-        copyOnWrite();
-        instance.clearDefaultSfixed32();
-        return this;
-      }
-
-      /**
-       * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-       * @return Whether the defaultSfixed64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultSfixed64() {
-        return instance.hasDefaultSfixed64();
-      }
-      /**
-       * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-       * @return The defaultSfixed64.
-       */
-      @java.lang.Override
-      public long getDefaultSfixed64() {
-        return instance.getDefaultSfixed64();
-      }
-      /**
-       * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-       * @param value The defaultSfixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultSfixed64(long value) {
-        copyOnWrite();
-        instance.setDefaultSfixed64(value);
-        return this;
-      }
-      /**
-       * <code>optional sfixed64 default_sfixed64 = 70 [default = -50];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultSfixed64() {
-        copyOnWrite();
-        instance.clearDefaultSfixed64();
-        return this;
-      }
-
-      /**
-       * <code>optional float default_float = 71 [default = 51.5];</code>
-       * @return Whether the defaultFloat field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultFloat() {
-        return instance.hasDefaultFloat();
-      }
-      /**
-       * <code>optional float default_float = 71 [default = 51.5];</code>
-       * @return The defaultFloat.
-       */
-      @java.lang.Override
-      public float getDefaultFloat() {
-        return instance.getDefaultFloat();
-      }
-      /**
-       * <code>optional float default_float = 71 [default = 51.5];</code>
-       * @param value The defaultFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultFloat(float value) {
-        copyOnWrite();
-        instance.setDefaultFloat(value);
-        return this;
-      }
-      /**
-       * <code>optional float default_float = 71 [default = 51.5];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultFloat() {
-        copyOnWrite();
-        instance.clearDefaultFloat();
-        return this;
-      }
-
-      /**
-       * <code>optional double default_double = 72 [default = 52000];</code>
-       * @return Whether the defaultDouble field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultDouble() {
-        return instance.hasDefaultDouble();
-      }
-      /**
-       * <code>optional double default_double = 72 [default = 52000];</code>
-       * @return The defaultDouble.
-       */
-      @java.lang.Override
-      public double getDefaultDouble() {
-        return instance.getDefaultDouble();
-      }
-      /**
-       * <code>optional double default_double = 72 [default = 52000];</code>
-       * @param value The defaultDouble to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultDouble(double value) {
-        copyOnWrite();
-        instance.setDefaultDouble(value);
-        return this;
-      }
-      /**
-       * <code>optional double default_double = 72 [default = 52000];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultDouble() {
-        copyOnWrite();
-        instance.clearDefaultDouble();
-        return this;
-      }
-
-      /**
-       * <code>optional bool default_bool = 73 [default = true];</code>
-       * @return Whether the defaultBool field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultBool() {
-        return instance.hasDefaultBool();
-      }
-      /**
-       * <code>optional bool default_bool = 73 [default = true];</code>
-       * @return The defaultBool.
-       */
-      @java.lang.Override
-      public boolean getDefaultBool() {
-        return instance.getDefaultBool();
-      }
-      /**
-       * <code>optional bool default_bool = 73 [default = true];</code>
-       * @param value The defaultBool to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultBool(boolean value) {
-        copyOnWrite();
-        instance.setDefaultBool(value);
-        return this;
-      }
-      /**
-       * <code>optional bool default_bool = 73 [default = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultBool() {
-        copyOnWrite();
-        instance.clearDefaultBool();
-        return this;
-      }
-
-      /**
-       * <code>optional string default_string = 74 [default = "hello"];</code>
-       * @return Whether the defaultString field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultString() {
-        return instance.hasDefaultString();
-      }
-      /**
-       * <code>optional string default_string = 74 [default = "hello"];</code>
-       * @return The defaultString.
-       */
-      @java.lang.Override
-      public java.lang.String getDefaultString() {
-        return instance.getDefaultString();
-      }
-      /**
-       * <code>optional string default_string = 74 [default = "hello"];</code>
-       * @return The bytes for defaultString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getDefaultStringBytes() {
-        return instance.getDefaultStringBytes();
-      }
-      /**
-       * <code>optional string default_string = 74 [default = "hello"];</code>
-       * @param value The defaultString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setDefaultString(value);
-        return this;
-      }
-      /**
-       * <code>optional string default_string = 74 [default = "hello"];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultString() {
-        copyOnWrite();
-        instance.clearDefaultString();
-        return this;
-      }
-      /**
-       * <code>optional string default_string = 74 [default = "hello"];</code>
-       * @param value The bytes for defaultString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setDefaultStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-       * @return Whether the defaultBytes field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultBytes() {
-        return instance.hasDefaultBytes();
-      }
-      /**
-       * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-       * @return The defaultBytes.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getDefaultBytes() {
-        return instance.getDefaultBytes();
-      }
-      /**
-       * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-       * @param value The defaultBytes to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultBytes(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setDefaultBytes(value);
-        return this;
-      }
-      /**
-       * <code>optional bytes default_bytes = 75 [default = "world"];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultBytes() {
-        copyOnWrite();
-        instance.clearDefaultBytes();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-       * @return Whether the defaultNestedEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultNestedEnum() {
-        return instance.hasDefaultNestedEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-       * @return The defaultNestedEnum.
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum getDefaultNestedEnum() {
-        return instance.getDefaultNestedEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-       * @param value The enum numeric value on the wire for defaultNestedEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultNestedEnum(protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum value) {
-        copyOnWrite();
-        instance.setDefaultNestedEnum(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedEnum default_nested_enum = 81 [default = BAR];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultNestedEnum() {
-        copyOnWrite();
-        instance.clearDefaultNestedEnum();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR];</code>
-       * @return Whether the defaultForeignEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultForeignEnum() {
-        return instance.hasDefaultForeignEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR];</code>
-       * @return The defaultForeignEnum.
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.ForeignEnum getDefaultForeignEnum() {
-        return instance.getDefaultForeignEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR];</code>
-       * @param value The enum numeric value on the wire for defaultForeignEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultForeignEnum(protobuf_unittest.UnittestProto.ForeignEnum value) {
-        copyOnWrite();
-        instance.setDefaultForeignEnum(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultForeignEnum() {
-        copyOnWrite();
-        instance.clearDefaultForeignEnum();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest_import.ImportEnum default_import_enum = 83 [default = IMPORT_BAR];</code>
-       * @return Whether the defaultImportEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultImportEnum() {
-        return instance.hasDefaultImportEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportEnum default_import_enum = 83 [default = IMPORT_BAR];</code>
-       * @return The defaultImportEnum.
-       */
-      @java.lang.Override
-      public com.google.protobuf.test.UnittestImport.ImportEnum getDefaultImportEnum() {
-        return instance.getDefaultImportEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportEnum default_import_enum = 83 [default = IMPORT_BAR];</code>
-       * @param value The enum numeric value on the wire for defaultImportEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultImportEnum(com.google.protobuf.test.UnittestImport.ImportEnum value) {
-        copyOnWrite();
-        instance.setDefaultImportEnum(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest_import.ImportEnum default_import_enum = 83 [default = IMPORT_BAR];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultImportEnum() {
-        copyOnWrite();
-        instance.clearDefaultImportEnum();
-        return this;
-      }
-
-      /**
-       * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-       * @return Whether the defaultStringPiece field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultStringPiece() {
-        return instance.hasDefaultStringPiece();
-      }
-      /**
-       * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-       * @return The defaultStringPiece.
-       */
-      @java.lang.Override
-      public java.lang.String getDefaultStringPiece() {
-        return instance.getDefaultStringPiece();
-      }
-      /**
-       * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-       * @return The bytes for defaultStringPiece.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getDefaultStringPieceBytes() {
-        return instance.getDefaultStringPieceBytes();
-      }
-      /**
-       * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-       * @param value The defaultStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultStringPiece(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setDefaultStringPiece(value);
-        return this;
-      }
-      /**
-       * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultStringPiece() {
-        copyOnWrite();
-        instance.clearDefaultStringPiece();
-        return this;
-      }
-      /**
-       * <code>optional string default_string_piece = 84 [default = "abc", ctype = STRING_PIECE];</code>
-       * @param value The bytes for defaultStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultStringPieceBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setDefaultStringPieceBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-       * @return Whether the defaultCord field is set.
-       */
-      @java.lang.Override
-      public boolean hasDefaultCord() {
-        return instance.hasDefaultCord();
-      }
-      /**
-       * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-       * @return The defaultCord.
-       */
-      @java.lang.Override
-      public java.lang.String getDefaultCord() {
-        return instance.getDefaultCord();
-      }
-      /**
-       * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-       * @return The bytes for defaultCord.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getDefaultCordBytes() {
-        return instance.getDefaultCordBytes();
-      }
-      /**
-       * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-       * @param value The defaultCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultCord(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setDefaultCord(value);
-        return this;
-      }
-      /**
-       * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDefaultCord() {
-        copyOnWrite();
-        instance.clearDefaultCord();
-        return this;
-      }
-      /**
-       * <code>optional string default_cord = 85 [default = "123", ctype = CORD];</code>
-       * @param value The bytes for defaultCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDefaultCordBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setDefaultCordBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>uint32 oneof_uint32 = 111;</code>
-       * @return Whether the oneofUint32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofUint32() {
-        return instance.hasOneofUint32();
-      }
-      /**
-       * <code>uint32 oneof_uint32 = 111;</code>
-       * @return The oneofUint32.
-       */
-      @java.lang.Override
-      public int getOneofUint32() {
-        return instance.getOneofUint32();
-      }
-      /**
-       * <code>uint32 oneof_uint32 = 111;</code>
-       * @param value The oneofUint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofUint32(int value) {
-        copyOnWrite();
-        instance.setOneofUint32(value);
-        return this;
-      }
-      /**
-       * <code>uint32 oneof_uint32 = 111;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofUint32() {
-        copyOnWrite();
-        instance.clearOneofUint32();
-        return this;
-      }
-
-      /**
-       * <code>.protobuf_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-       */
-      @java.lang.Override
-      public boolean hasOneofNestedMessage() {
-        return instance.hasOneofNestedMessage();
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage getOneofNestedMessage() {
-        return instance.getOneofNestedMessage();
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-       */
-      public Builder setOneofNestedMessage(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.setOneofNestedMessage(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-       */
-      public Builder setOneofNestedMessage(
-          protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOneofNestedMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-       */
-      public Builder mergeOneofNestedMessage(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.mergeOneofNestedMessage(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypes.NestedMessage oneof_nested_message = 112;</code>
-       */
-      public Builder clearOneofNestedMessage() {
-        copyOnWrite();
-        instance.clearOneofNestedMessage();
-        return this;
-      }
-
-      /**
-       * <code>string oneof_string = 113;</code>
-       * @return Whether the oneofString field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofString() {
-        return instance.hasOneofString();
-      }
-      /**
-       * <code>string oneof_string = 113;</code>
-       * @return The oneofString.
-       */
-      @java.lang.Override
-      public java.lang.String getOneofString() {
-        return instance.getOneofString();
-      }
-      /**
-       * <code>string oneof_string = 113;</code>
-       * @return The bytes for oneofString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getOneofStringBytes() {
-        return instance.getOneofStringBytes();
-      }
-      /**
-       * <code>string oneof_string = 113;</code>
-       * @param value The oneofString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setOneofString(value);
-        return this;
-      }
-      /**
-       * <code>string oneof_string = 113;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofString() {
-        copyOnWrite();
-        instance.clearOneofString();
-        return this;
-      }
-      /**
-       * <code>string oneof_string = 113;</code>
-       * @param value The bytes for oneofString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOneofStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>bytes oneof_bytes = 114;</code>
-       * @return Whether the oneofBytes field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofBytes() {
-        return instance.hasOneofBytes();
-      }
-      /**
-       * <code>bytes oneof_bytes = 114;</code>
-       * @return The oneofBytes.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getOneofBytes() {
-        return instance.getOneofBytes();
-      }
-      /**
-       * <code>bytes oneof_bytes = 114;</code>
-       * @param value The oneofBytes to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofBytes(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOneofBytes(value);
-        return this;
-      }
-      /**
-       * <code>bytes oneof_bytes = 114;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofBytes() {
-        copyOnWrite();
-        instance.clearOneofBytes();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestAllTypes)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestAllTypes();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "oneofField_",
-              "oneofFieldCase_",
-              "bitField0_",
-              "bitField1_",
-              "optionalInt32_",
-              "optionalInt64_",
-              "optionalUint32_",
-              "optionalUint64_",
-              "optionalSint32_",
-              "optionalSint64_",
-              "optionalFixed32_",
-              "optionalFixed64_",
-              "optionalSfixed32_",
-              "optionalSfixed64_",
-              "optionalFloat_",
-              "optionalDouble_",
-              "optionalBool_",
-              "optionalString_",
-              "optionalBytes_",
-              "optionalGroup_",
-              "optionalNestedMessage_",
-              "optionalForeignMessage_",
-              "optionalImportMessage_",
-              "optionalNestedEnum_",
-              protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum.internalGetVerifier(),
-              "optionalForeignEnum_",
-              protobuf_unittest.UnittestProto.ForeignEnum.internalGetVerifier(),
-              "optionalImportEnum_",
-              com.google.protobuf.test.UnittestImport.ImportEnum.internalGetVerifier(),
-              "optionalStringPiece_",
-              "optionalCord_",
-              "optionalPublicImportMessage_",
-              "optionalLazyMessage_",
-              "repeatedInt32_",
-              "repeatedInt64_",
-              "repeatedUint32_",
-              "repeatedUint64_",
-              "repeatedSint32_",
-              "repeatedSint64_",
-              "repeatedFixed32_",
-              "repeatedFixed64_",
-              "repeatedSfixed32_",
-              "repeatedSfixed64_",
-              "repeatedFloat_",
-              "repeatedDouble_",
-              "repeatedBool_",
-              "repeatedString_",
-              "repeatedBytes_",
-              "repeatedGroup_",
-              protobuf_unittest.UnittestProto.TestAllTypes.RepeatedGroup.class,
-              "repeatedNestedMessage_",
-              protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.class,
-              "repeatedForeignMessage_",
-              protobuf_unittest.UnittestProto.ForeignMessage.class,
-              "repeatedImportMessage_",
-              com.google.protobuf.test.UnittestImport.ImportMessage.class,
-              "repeatedNestedEnum_",
-              protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum.internalGetVerifier(),
-              "repeatedForeignEnum_",
-              protobuf_unittest.UnittestProto.ForeignEnum.internalGetVerifier(),
-              "repeatedImportEnum_",
-              com.google.protobuf.test.UnittestImport.ImportEnum.internalGetVerifier(),
-              "repeatedStringPiece_",
-              "repeatedCord_",
-              "repeatedLazyMessage_",
-              protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.class,
-              "defaultInt32_",
-              "defaultInt64_",
-              "defaultUint32_",
-              "defaultUint64_",
-              "defaultSint32_",
-              "defaultSint64_",
-              "defaultFixed32_",
-              "defaultFixed64_",
-              "defaultSfixed32_",
-              "defaultSfixed64_",
-              "defaultFloat_",
-              "defaultDouble_",
-              "defaultBool_",
-              "defaultString_",
-              "defaultBytes_",
-              "defaultNestedEnum_",
-              protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum.internalGetVerifier(),
-              "defaultForeignEnum_",
-              protobuf_unittest.UnittestProto.ForeignEnum.internalGetVerifier(),
-              "defaultImportEnum_",
-              com.google.protobuf.test.UnittestImport.ImportEnum.internalGetVerifier(),
-              "defaultStringPiece_",
-              "defaultCord_",
-              protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.class,
-            };
-            java.lang.String info =
-                "\u0001K\u0001\u0002\u0001rK\u0000\u0019\u0000\u0001\u1004\u0000\u0002\u1002\u0001" +
-                "\u0003\u100b\u0002\u0004\u1003\u0003\u0005\u100f\u0004\u0006\u1010\u0005\u0007\u1006" +
-                "\u0006\b\u1005\u0007\t\u100d\b\n\u100e\t\u000b\u1001\n\f\u1000\u000b\r\u1007\f\u000e" +
-                "\u1008\r\u000f\u100a\u000e\u0010\u1011\u000f\u0012\u1009\u0010\u0013\u1009\u0011" +
-                "\u0014\u1009\u0012\u0015\u100c\u0013\u0016\u100c\u0014\u0017\u100c\u0015\u0018\u1008" +
-                "\u0016\u0019\u1008\u0017\u001a\u1009\u0018\u001b\u1009\u0019\u001f\u0016 \u0014!" +
-                "\u001d\"\u0015#!$\"%\u0018&\u0017\'\u001f( )\u0013*\u0012+\u0019,\u001a-\u001c.1" +
-                "0\u001b1\u001b2\u001b3\u001e4\u001e5\u001e6\u001a7\u001a9\u001b=\u1004\u001a>\u1002" +
-                "\u001b?\u100b\u001c@\u1003\u001dA\u100f\u001eB\u1010\u001fC\u1006 D\u1005!E\u100d" +
-                "\"F\u100e#G\u1001$H\u1000%I\u1007&J\u1008\'K\u100a(Q\u100c)R\u100c*S\u100c+T\u1008" +
-                ",U\u1008-o\u103e\u0000p\u103c\u0000q\u103b\u0000r\u103d\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestAllTypes> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestAllTypes.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestAllTypes>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestAllTypes)
-    private static final protobuf_unittest.UnittestProto.TestAllTypes DEFAULT_INSTANCE;
-    static {
-      TestAllTypes defaultInstance = new TestAllTypes();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestAllTypes.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestAllTypes getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestAllTypes> PARSER;
-
-    public static com.google.protobuf.Parser<TestAllTypes> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface NestedTestAllTypesOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.NestedTestAllTypes)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional .protobuf_unittest.NestedTestAllTypes child = 1;</code>
-     * @return Whether the child field is set.
-     */
-    boolean hasChild();
-    /**
-     * <code>optional .protobuf_unittest.NestedTestAllTypes child = 1;</code>
-     * @return The child.
-     */
-    protobuf_unittest.UnittestProto.NestedTestAllTypes getChild();
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes payload = 2;</code>
-     * @return Whether the payload field is set.
-     */
-    boolean hasPayload();
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes payload = 2;</code>
-     * @return The payload.
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes getPayload();
-
-    /**
-     * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-     */
-    java.util.List<protobuf_unittest.UnittestProto.NestedTestAllTypes> 
-        getRepeatedChildList();
-    /**
-     * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-     */
-    protobuf_unittest.UnittestProto.NestedTestAllTypes getRepeatedChild(int index);
-    /**
-     * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-     */
-    int getRepeatedChildCount();
-  }
-  /**
-   * <pre>
-   * This proto includes a recursively nested message.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.NestedTestAllTypes}
-   */
-  public  static final class NestedTestAllTypes extends
-      com.google.protobuf.GeneratedMessageLite<
-          NestedTestAllTypes, NestedTestAllTypes.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.NestedTestAllTypes)
-      NestedTestAllTypesOrBuilder {
-    private NestedTestAllTypes() {
-      repeatedChild_ = emptyProtobufList();
-    }
-    private int bitField0_;
-    public static final int CHILD_FIELD_NUMBER = 1;
-    private protobuf_unittest.UnittestProto.NestedTestAllTypes child_;
-    /**
-     * <code>optional .protobuf_unittest.NestedTestAllTypes child = 1;</code>
-     */
-    @java.lang.Override
-    public boolean hasChild() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.NestedTestAllTypes child = 1;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.NestedTestAllTypes getChild() {
-      return child_ == null ? protobuf_unittest.UnittestProto.NestedTestAllTypes.getDefaultInstance() : child_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.NestedTestAllTypes child = 1;</code>
-     */
-    private void setChild(protobuf_unittest.UnittestProto.NestedTestAllTypes value) {
-      value.getClass();
-  child_ = value;
-      bitField0_ |= 0x00000001;
-      }
-    /**
-     * <code>optional .protobuf_unittest.NestedTestAllTypes child = 1;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeChild(protobuf_unittest.UnittestProto.NestedTestAllTypes value) {
-      value.getClass();
-  if (child_ != null &&
-          child_ != protobuf_unittest.UnittestProto.NestedTestAllTypes.getDefaultInstance()) {
-        child_ =
-          protobuf_unittest.UnittestProto.NestedTestAllTypes.newBuilder(child_).mergeFrom(value).buildPartial();
-      } else {
-        child_ = value;
-      }
-      bitField0_ |= 0x00000001;
-    }
-    /**
-     * <code>optional .protobuf_unittest.NestedTestAllTypes child = 1;</code>
-     */
-    private void clearChild() {  child_ = null;
-      bitField0_ = (bitField0_ & ~0x00000001);
-    }
-
-    public static final int PAYLOAD_FIELD_NUMBER = 2;
-    private protobuf_unittest.UnittestProto.TestAllTypes payload_;
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes payload = 2;</code>
-     */
-    @java.lang.Override
-    public boolean hasPayload() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes payload = 2;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes getPayload() {
-      return payload_ == null ? protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance() : payload_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes payload = 2;</code>
-     */
-    private void setPayload(protobuf_unittest.UnittestProto.TestAllTypes value) {
-      value.getClass();
-  payload_ = value;
-      bitField0_ |= 0x00000002;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes payload = 2;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergePayload(protobuf_unittest.UnittestProto.TestAllTypes value) {
-      value.getClass();
-  if (payload_ != null &&
-          payload_ != protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance()) {
-        payload_ =
-          protobuf_unittest.UnittestProto.TestAllTypes.newBuilder(payload_).mergeFrom(value).buildPartial();
-      } else {
-        payload_ = value;
-      }
-      bitField0_ |= 0x00000002;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes payload = 2;</code>
-     */
-    private void clearPayload() {  payload_ = null;
-      bitField0_ = (bitField0_ & ~0x00000002);
-    }
-
-    public static final int REPEATED_CHILD_FIELD_NUMBER = 3;
-    private com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.NestedTestAllTypes> repeatedChild_;
-    /**
-     * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-     */
-    @java.lang.Override
-    public java.util.List<protobuf_unittest.UnittestProto.NestedTestAllTypes> getRepeatedChildList() {
-      return repeatedChild_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-     */
-    public java.util.List<? extends protobuf_unittest.UnittestProto.NestedTestAllTypesOrBuilder> 
-        getRepeatedChildOrBuilderList() {
-      return repeatedChild_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-     */
-    @java.lang.Override
-    public int getRepeatedChildCount() {
-      return repeatedChild_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.NestedTestAllTypes getRepeatedChild(int index) {
-      return repeatedChild_.get(index);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-     */
-    public protobuf_unittest.UnittestProto.NestedTestAllTypesOrBuilder getRepeatedChildOrBuilder(
-        int index) {
-      return repeatedChild_.get(index);
-    }
-    private void ensureRepeatedChildIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.NestedTestAllTypes> tmp = repeatedChild_;
-      if (!tmp.isModifiable()) {
-        repeatedChild_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-     */
-    private void setRepeatedChild(
-        int index, protobuf_unittest.UnittestProto.NestedTestAllTypes value) {
-      value.getClass();
-  ensureRepeatedChildIsMutable();
-      repeatedChild_.set(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-     */
-    private void addRepeatedChild(protobuf_unittest.UnittestProto.NestedTestAllTypes value) {
-      value.getClass();
-  ensureRepeatedChildIsMutable();
-      repeatedChild_.add(value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-     */
-    private void addRepeatedChild(
-        int index, protobuf_unittest.UnittestProto.NestedTestAllTypes value) {
-      value.getClass();
-  ensureRepeatedChildIsMutable();
-      repeatedChild_.add(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-     */
-    private void addAllRepeatedChild(
-        java.lang.Iterable<? extends protobuf_unittest.UnittestProto.NestedTestAllTypes> values) {
-      ensureRepeatedChildIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedChild_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-     */
-    private void clearRepeatedChild() {
-      repeatedChild_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-     */
-    private void removeRepeatedChild(int index) {
-      ensureRepeatedChildIsMutable();
-      repeatedChild_.remove(index);
-    }
-
-    public static protobuf_unittest.UnittestProto.NestedTestAllTypes parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.NestedTestAllTypes parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.NestedTestAllTypes parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.NestedTestAllTypes parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.NestedTestAllTypes parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.NestedTestAllTypes parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.NestedTestAllTypes parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.NestedTestAllTypes parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.NestedTestAllTypes parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.NestedTestAllTypes parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.NestedTestAllTypes parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.NestedTestAllTypes parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.NestedTestAllTypes prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * This proto includes a recursively nested message.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.NestedTestAllTypes}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.NestedTestAllTypes, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.NestedTestAllTypes)
-        protobuf_unittest.UnittestProto.NestedTestAllTypesOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.NestedTestAllTypes.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional .protobuf_unittest.NestedTestAllTypes child = 1;</code>
-       */
-      @java.lang.Override
-      public boolean hasChild() {
-        return instance.hasChild();
-      }
-      /**
-       * <code>optional .protobuf_unittest.NestedTestAllTypes child = 1;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.NestedTestAllTypes getChild() {
-        return instance.getChild();
-      }
-      /**
-       * <code>optional .protobuf_unittest.NestedTestAllTypes child = 1;</code>
-       */
-      public Builder setChild(protobuf_unittest.UnittestProto.NestedTestAllTypes value) {
-        copyOnWrite();
-        instance.setChild(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.NestedTestAllTypes child = 1;</code>
-       */
-      public Builder setChild(
-          protobuf_unittest.UnittestProto.NestedTestAllTypes.Builder builderForValue) {
-        copyOnWrite();
-        instance.setChild(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.NestedTestAllTypes child = 1;</code>
-       */
-      public Builder mergeChild(protobuf_unittest.UnittestProto.NestedTestAllTypes value) {
-        copyOnWrite();
-        instance.mergeChild(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.NestedTestAllTypes child = 1;</code>
-       */
-      public Builder clearChild() {  copyOnWrite();
-        instance.clearChild();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes payload = 2;</code>
-       */
-      @java.lang.Override
-      public boolean hasPayload() {
-        return instance.hasPayload();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes payload = 2;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes getPayload() {
-        return instance.getPayload();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes payload = 2;</code>
-       */
-      public Builder setPayload(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        copyOnWrite();
-        instance.setPayload(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes payload = 2;</code>
-       */
-      public Builder setPayload(
-          protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-        copyOnWrite();
-        instance.setPayload(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes payload = 2;</code>
-       */
-      public Builder mergePayload(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        copyOnWrite();
-        instance.mergePayload(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes payload = 2;</code>
-       */
-      public Builder clearPayload() {  copyOnWrite();
-        instance.clearPayload();
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.NestedTestAllTypes> getRepeatedChildList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedChildList());
-      }
-      /**
-       * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-       */
-      @java.lang.Override
-      public int getRepeatedChildCount() {
-        return instance.getRepeatedChildCount();
-      }/**
-       * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.NestedTestAllTypes getRepeatedChild(int index) {
-        return instance.getRepeatedChild(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-       */
-      public Builder setRepeatedChild(
-          int index, protobuf_unittest.UnittestProto.NestedTestAllTypes value) {
-        copyOnWrite();
-        instance.setRepeatedChild(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-       */
-      public Builder setRepeatedChild(
-          int index, protobuf_unittest.UnittestProto.NestedTestAllTypes.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedChild(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-       */
-      public Builder addRepeatedChild(protobuf_unittest.UnittestProto.NestedTestAllTypes value) {
-        copyOnWrite();
-        instance.addRepeatedChild(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-       */
-      public Builder addRepeatedChild(
-          int index, protobuf_unittest.UnittestProto.NestedTestAllTypes value) {
-        copyOnWrite();
-        instance.addRepeatedChild(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-       */
-      public Builder addRepeatedChild(
-          protobuf_unittest.UnittestProto.NestedTestAllTypes.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedChild(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-       */
-      public Builder addRepeatedChild(
-          int index, protobuf_unittest.UnittestProto.NestedTestAllTypes.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedChild(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-       */
-      public Builder addAllRepeatedChild(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.NestedTestAllTypes> values) {
-        copyOnWrite();
-        instance.addAllRepeatedChild(values);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-       */
-      public Builder clearRepeatedChild() {
-        copyOnWrite();
-        instance.clearRepeatedChild();
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.NestedTestAllTypes repeated_child = 3;</code>
-       */
-      public Builder removeRepeatedChild(int index) {
-        copyOnWrite();
-        instance.removeRepeatedChild(index);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.NestedTestAllTypes)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.NestedTestAllTypes();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "child_",
-              "payload_",
-              "repeatedChild_",
-              protobuf_unittest.UnittestProto.NestedTestAllTypes.class,
-            };
-            java.lang.String info =
-                "\u0001\u0003\u0000\u0001\u0001\u0003\u0003\u0000\u0001\u0000\u0001\u1009\u0000\u0002" +
-                "\u1009\u0001\u0003\u001b";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.NestedTestAllTypes> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.NestedTestAllTypes.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.NestedTestAllTypes>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.NestedTestAllTypes)
-    private static final protobuf_unittest.UnittestProto.NestedTestAllTypes DEFAULT_INSTANCE;
-    static {
-      NestedTestAllTypes defaultInstance = new NestedTestAllTypes();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        NestedTestAllTypes.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.NestedTestAllTypes getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<NestedTestAllTypes> PARSER;
-
-    public static com.google.protobuf.Parser<NestedTestAllTypes> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestDeprecatedFieldsOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestDeprecatedFields)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional int32 deprecated_int32 = 1 [deprecated = true];</code>
-     * @return Whether the deprecatedInt32 field is set.
-     */
-    @java.lang.Deprecated boolean hasDeprecatedInt32();
-    /**
-     * <code>optional int32 deprecated_int32 = 1 [deprecated = true];</code>
-     * @return The deprecatedInt32.
-     */
-    @java.lang.Deprecated int getDeprecatedInt32();
-
-    /**
-     * <code>int32 deprecated_int32_in_oneof = 2 [deprecated = true];</code>
-     * @return Whether the deprecatedInt32InOneof field is set.
-     */
-    @java.lang.Deprecated boolean hasDeprecatedInt32InOneof();
-    /**
-     * <code>int32 deprecated_int32_in_oneof = 2 [deprecated = true];</code>
-     * @return The deprecatedInt32InOneof.
-     */
-    @java.lang.Deprecated int getDeprecatedInt32InOneof();
-
-    public protobuf_unittest.UnittestProto.TestDeprecatedFields.OneofFieldsCase getOneofFieldsCase();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestDeprecatedFields}
-   */
-  public  static final class TestDeprecatedFields extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestDeprecatedFields, TestDeprecatedFields.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestDeprecatedFields)
-      TestDeprecatedFieldsOrBuilder {
-    private TestDeprecatedFields() {
-    }
-    private int bitField0_;
-    private int oneofFieldsCase_ = 0;
-    private java.lang.Object oneofFields_;
-    public enum OneofFieldsCase {
-      DEPRECATED_INT32_IN_ONEOF(2),
-      ONEOFFIELDS_NOT_SET(0);
-      private final int value;
-      private OneofFieldsCase(int value) {
-        this.value = value;
-      }
-      /**
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static OneofFieldsCase valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static OneofFieldsCase forNumber(int value) {
-        switch (value) {
-          case 2: return DEPRECATED_INT32_IN_ONEOF;
-          case 0: return ONEOFFIELDS_NOT_SET;
-          default: return null;
-        }
-      }
-      public int getNumber() {
-        return this.value;
-      }
-    };
-
-    @java.lang.Override
-    public OneofFieldsCase
-    getOneofFieldsCase() {
-      return OneofFieldsCase.forNumber(
-          oneofFieldsCase_);
-    }
-
-    private void clearOneofFields() {
-      oneofFieldsCase_ = 0;
-      oneofFields_ = null;
-    }
-
-    public static final int DEPRECATED_INT32_FIELD_NUMBER = 1;
-    private int deprecatedInt32_;
-    /**
-     * <code>optional int32 deprecated_int32 = 1 [deprecated = true];</code>
-     * @return Whether the deprecatedInt32 field is set.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated public boolean hasDeprecatedInt32() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 deprecated_int32 = 1 [deprecated = true];</code>
-     * @return The deprecatedInt32.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated public int getDeprecatedInt32() {
-      return deprecatedInt32_;
-    }
-    /**
-     * <code>optional int32 deprecated_int32 = 1 [deprecated = true];</code>
-     * @param value The deprecatedInt32 to set.
-     */
-    private void setDeprecatedInt32(int value) {
-      bitField0_ |= 0x00000001;
-      deprecatedInt32_ = value;
-    }
-    /**
-     * <code>optional int32 deprecated_int32 = 1 [deprecated = true];</code>
-     */
-    private void clearDeprecatedInt32() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      deprecatedInt32_ = 0;
-    }
-
-    public static final int DEPRECATED_INT32_IN_ONEOF_FIELD_NUMBER = 2;
-    /**
-     * <code>int32 deprecated_int32_in_oneof = 2 [deprecated = true];</code>
-     * @return Whether the deprecatedInt32InOneof field is set.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated public boolean hasDeprecatedInt32InOneof() {
-      return oneofFieldsCase_ == 2;
-    }
-    /**
-     * <code>int32 deprecated_int32_in_oneof = 2 [deprecated = true];</code>
-     * @return The deprecatedInt32InOneof.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated public int getDeprecatedInt32InOneof() {
-      if (oneofFieldsCase_ == 2) {
-        return (java.lang.Integer) oneofFields_;
-      }
-      return 0;
-    }
-    /**
-     * <code>int32 deprecated_int32_in_oneof = 2 [deprecated = true];</code>
-     * @param value The deprecatedInt32InOneof to set.
-     */
-    private void setDeprecatedInt32InOneof(int value) {
-      oneofFieldsCase_ = 2;
-      oneofFields_ = value;
-    }
-    /**
-     * <code>int32 deprecated_int32_in_oneof = 2 [deprecated = true];</code>
-     */
-    private void clearDeprecatedInt32InOneof() {
-      if (oneofFieldsCase_ == 2) {
-        oneofFieldsCase_ = 0;
-        oneofFields_ = null;
-      }
-    }
-
-    public static protobuf_unittest.UnittestProto.TestDeprecatedFields parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedFields parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedFields parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedFields parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedFields parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedFields parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedFields parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedFields parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedFields parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedFields parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedFields parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedFields parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestDeprecatedFields prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestDeprecatedFields}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestDeprecatedFields, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestDeprecatedFields)
-        protobuf_unittest.UnittestProto.TestDeprecatedFieldsOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestDeprecatedFields.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-      @java.lang.Override
-      public OneofFieldsCase
-          getOneofFieldsCase() {
-        return instance.getOneofFieldsCase();
-      }
-
-      public Builder clearOneofFields() {
-        copyOnWrite();
-        instance.clearOneofFields();
-        return this;
-      }
-
-
-      /**
-       * <code>optional int32 deprecated_int32 = 1 [deprecated = true];</code>
-       * @return Whether the deprecatedInt32 field is set.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated public boolean hasDeprecatedInt32() {
-        return instance.hasDeprecatedInt32();
-      }
-      /**
-       * <code>optional int32 deprecated_int32 = 1 [deprecated = true];</code>
-       * @return The deprecatedInt32.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated public int getDeprecatedInt32() {
-        return instance.getDeprecatedInt32();
-      }
-      /**
-       * <code>optional int32 deprecated_int32 = 1 [deprecated = true];</code>
-       * @param value The deprecatedInt32 to set.
-       * @return This builder for chaining.
-       */
-      @java.lang.Deprecated public Builder setDeprecatedInt32(int value) {
-        copyOnWrite();
-        instance.setDeprecatedInt32(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 deprecated_int32 = 1 [deprecated = true];</code>
-       * @return This builder for chaining.
-       */
-      @java.lang.Deprecated public Builder clearDeprecatedInt32() {
-        copyOnWrite();
-        instance.clearDeprecatedInt32();
-        return this;
-      }
-
-      /**
-       * <code>int32 deprecated_int32_in_oneof = 2 [deprecated = true];</code>
-       * @return Whether the deprecatedInt32InOneof field is set.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated public boolean hasDeprecatedInt32InOneof() {
-        return instance.hasDeprecatedInt32InOneof();
-      }
-      /**
-       * <code>int32 deprecated_int32_in_oneof = 2 [deprecated = true];</code>
-       * @return The deprecatedInt32InOneof.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated public int getDeprecatedInt32InOneof() {
-        return instance.getDeprecatedInt32InOneof();
-      }
-      /**
-       * <code>int32 deprecated_int32_in_oneof = 2 [deprecated = true];</code>
-       * @param value The deprecatedInt32InOneof to set.
-       * @return This builder for chaining.
-       */
-      @java.lang.Deprecated public Builder setDeprecatedInt32InOneof(int value) {
-        copyOnWrite();
-        instance.setDeprecatedInt32InOneof(value);
-        return this;
-      }
-      /**
-       * <code>int32 deprecated_int32_in_oneof = 2 [deprecated = true];</code>
-       * @return This builder for chaining.
-       */
-      @java.lang.Deprecated public Builder clearDeprecatedInt32InOneof() {
-        copyOnWrite();
-        instance.clearDeprecatedInt32InOneof();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestDeprecatedFields)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestDeprecatedFields();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "oneofFields_",
-              "oneofFieldsCase_",
-              "bitField0_",
-              "deprecatedInt32_",
-            };
-            java.lang.String info =
-                "\u0001\u0002\u0001\u0001\u0001\u0002\u0002\u0000\u0000\u0000\u0001\u1004\u0000\u0002" +
-                "\u1037\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestDeprecatedFields> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestDeprecatedFields.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestDeprecatedFields>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestDeprecatedFields)
-    private static final protobuf_unittest.UnittestProto.TestDeprecatedFields DEFAULT_INSTANCE;
-    static {
-      TestDeprecatedFields defaultInstance = new TestDeprecatedFields();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestDeprecatedFields.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestDeprecatedFields getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestDeprecatedFields> PARSER;
-
-    public static com.google.protobuf.Parser<TestDeprecatedFields> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  @java.lang.Deprecated public interface TestDeprecatedMessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestDeprecatedMessage)
-      com.google.protobuf.MessageLiteOrBuilder {
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestDeprecatedMessage}
-   */
-  @java.lang.Deprecated public  static final class TestDeprecatedMessage extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestDeprecatedMessage, TestDeprecatedMessage.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestDeprecatedMessage)
-      TestDeprecatedMessageOrBuilder {
-    private TestDeprecatedMessage() {
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedMessage parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedMessage parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedMessage parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedMessage parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedMessage parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedMessage parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedMessage parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedMessage parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedMessage parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedMessage parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedMessage parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestDeprecatedMessage parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestDeprecatedMessage prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestDeprecatedMessage}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestDeprecatedMessage, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestDeprecatedMessage)
-        protobuf_unittest.UnittestProto.TestDeprecatedMessageOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestDeprecatedMessage.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestDeprecatedMessage)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestDeprecatedMessage();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestDeprecatedMessage> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestDeprecatedMessage.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestDeprecatedMessage>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestDeprecatedMessage)
-    private static final protobuf_unittest.UnittestProto.TestDeprecatedMessage DEFAULT_INSTANCE;
-    static {
-      TestDeprecatedMessage defaultInstance = new TestDeprecatedMessage();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestDeprecatedMessage.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestDeprecatedMessage getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestDeprecatedMessage> PARSER;
-
-    public static com.google.protobuf.Parser<TestDeprecatedMessage> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface ForeignMessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.ForeignMessage)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional int32 c = 1;</code>
-     * @return Whether the c field is set.
-     */
-    boolean hasC();
-    /**
-     * <code>optional int32 c = 1;</code>
-     * @return The c.
-     */
-    int getC();
-
-    /**
-     * <code>optional int32 d = 2;</code>
-     * @return Whether the d field is set.
-     */
-    boolean hasD();
-    /**
-     * <code>optional int32 d = 2;</code>
-     * @return The d.
-     */
-    int getD();
-  }
-  /**
-   * <pre>
-   * Define these after TestAllTypes to make sure the compiler can handle
-   * that.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.ForeignMessage}
-   */
-  public  static final class ForeignMessage extends
-      com.google.protobuf.GeneratedMessageLite<
-          ForeignMessage, ForeignMessage.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.ForeignMessage)
-      ForeignMessageOrBuilder {
-    private ForeignMessage() {
-    }
-    private int bitField0_;
-    public static final int C_FIELD_NUMBER = 1;
-    private int c_;
-    /**
-     * <code>optional int32 c = 1;</code>
-     * @return Whether the c field is set.
-     */
-    @java.lang.Override
-    public boolean hasC() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 c = 1;</code>
-     * @return The c.
-     */
-    @java.lang.Override
-    public int getC() {
-      return c_;
-    }
-    /**
-     * <code>optional int32 c = 1;</code>
-     * @param value The c to set.
-     */
-    private void setC(int value) {
-      bitField0_ |= 0x00000001;
-      c_ = value;
-    }
-    /**
-     * <code>optional int32 c = 1;</code>
-     */
-    private void clearC() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      c_ = 0;
-    }
-
-    public static final int D_FIELD_NUMBER = 2;
-    private int d_;
-    /**
-     * <code>optional int32 d = 2;</code>
-     * @return Whether the d field is set.
-     */
-    @java.lang.Override
-    public boolean hasD() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional int32 d = 2;</code>
-     * @return The d.
-     */
-    @java.lang.Override
-    public int getD() {
-      return d_;
-    }
-    /**
-     * <code>optional int32 d = 2;</code>
-     * @param value The d to set.
-     */
-    private void setD(int value) {
-      bitField0_ |= 0x00000002;
-      d_ = value;
-    }
-    /**
-     * <code>optional int32 d = 2;</code>
-     */
-    private void clearD() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      d_ = 0;
-    }
-
-    public static protobuf_unittest.UnittestProto.ForeignMessage parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.ForeignMessage parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.ForeignMessage parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.ForeignMessage parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.ForeignMessage parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.ForeignMessage parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.ForeignMessage parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.ForeignMessage parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.ForeignMessage parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.ForeignMessage parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.ForeignMessage parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.ForeignMessage parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.ForeignMessage prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Define these after TestAllTypes to make sure the compiler can handle
-     * that.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.ForeignMessage}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.ForeignMessage, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.ForeignMessage)
-        protobuf_unittest.UnittestProto.ForeignMessageOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.ForeignMessage.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int32 c = 1;</code>
-       * @return Whether the c field is set.
-       */
-      @java.lang.Override
-      public boolean hasC() {
-        return instance.hasC();
-      }
-      /**
-       * <code>optional int32 c = 1;</code>
-       * @return The c.
-       */
-      @java.lang.Override
-      public int getC() {
-        return instance.getC();
-      }
-      /**
-       * <code>optional int32 c = 1;</code>
-       * @param value The c to set.
-       * @return This builder for chaining.
-       */
-      public Builder setC(int value) {
-        copyOnWrite();
-        instance.setC(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 c = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearC() {
-        copyOnWrite();
-        instance.clearC();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 d = 2;</code>
-       * @return Whether the d field is set.
-       */
-      @java.lang.Override
-      public boolean hasD() {
-        return instance.hasD();
-      }
-      /**
-       * <code>optional int32 d = 2;</code>
-       * @return The d.
-       */
-      @java.lang.Override
-      public int getD() {
-        return instance.getD();
-      }
-      /**
-       * <code>optional int32 d = 2;</code>
-       * @param value The d to set.
-       * @return This builder for chaining.
-       */
-      public Builder setD(int value) {
-        copyOnWrite();
-        instance.setD(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 d = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearD() {
-        copyOnWrite();
-        instance.clearD();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.ForeignMessage)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.ForeignMessage();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "c_",
-              "d_",
-            };
-            java.lang.String info =
-                "\u0001\u0002\u0000\u0001\u0001\u0002\u0002\u0000\u0000\u0000\u0001\u1004\u0000\u0002" +
-                "\u1004\u0001";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.ForeignMessage> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.ForeignMessage.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.ForeignMessage>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.ForeignMessage)
-    private static final protobuf_unittest.UnittestProto.ForeignMessage DEFAULT_INSTANCE;
-    static {
-      ForeignMessage defaultInstance = new ForeignMessage();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        ForeignMessage.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.ForeignMessage getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<ForeignMessage> PARSER;
-
-    public static com.google.protobuf.Parser<ForeignMessage> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestReservedFieldsOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestReservedFields)
-      com.google.protobuf.MessageLiteOrBuilder {
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestReservedFields}
-   */
-  public  static final class TestReservedFields extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestReservedFields, TestReservedFields.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestReservedFields)
-      TestReservedFieldsOrBuilder {
-    private TestReservedFields() {
-    }
-    public static protobuf_unittest.UnittestProto.TestReservedFields parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestReservedFields parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestReservedFields parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestReservedFields parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestReservedFields parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestReservedFields parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestReservedFields parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestReservedFields parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestReservedFields parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestReservedFields parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestReservedFields parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestReservedFields parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestReservedFields prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestReservedFields}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestReservedFields, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestReservedFields)
-        protobuf_unittest.UnittestProto.TestReservedFieldsOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestReservedFields.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestReservedFields)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestReservedFields();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestReservedFields> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestReservedFields.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestReservedFields>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestReservedFields)
-    private static final protobuf_unittest.UnittestProto.TestReservedFields DEFAULT_INSTANCE;
-    static {
-      TestReservedFields defaultInstance = new TestReservedFields();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestReservedFields.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestReservedFields getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestReservedFields> PARSER;
-
-    public static com.google.protobuf.Parser<TestReservedFields> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestAllExtensionsOrBuilder extends 
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestAllExtensions)
-       com.google.protobuf.GeneratedMessageLite.
-            ExtendableMessageOrBuilder<
-                TestAllExtensions, TestAllExtensions.Builder> {
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestAllExtensions}
-   */
-  public  static final class TestAllExtensions extends
-      com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
-        TestAllExtensions, TestAllExtensions.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestAllExtensions)
-      TestAllExtensionsOrBuilder {
-    private TestAllExtensions() {
-    }
-    public static protobuf_unittest.UnittestProto.TestAllExtensions parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllExtensions parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllExtensions parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllExtensions parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllExtensions parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllExtensions parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllExtensions parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllExtensions parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllExtensions parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllExtensions parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllExtensions parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestAllExtensions parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestAllExtensions prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestAllExtensions}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
-          protobuf_unittest.UnittestProto.TestAllExtensions, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestAllExtensions)
-        protobuf_unittest.UnittestProto.TestAllExtensionsOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestAllExtensions.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestAllExtensions)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestAllExtensions();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestAllExtensions> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestAllExtensions.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestAllExtensions>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestAllExtensions)
-    private static final protobuf_unittest.UnittestProto.TestAllExtensions DEFAULT_INSTANCE;
-    static {
-      TestAllExtensions defaultInstance = new TestAllExtensions();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestAllExtensions.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestAllExtensions getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestAllExtensions> PARSER;
-
-    public static com.google.protobuf.Parser<TestAllExtensions> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface OptionalGroup_extensionOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.OptionalGroup_extension)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional int32 a = 17;</code>
-     * @return Whether the a field is set.
-     */
-    boolean hasA();
-    /**
-     * <code>optional int32 a = 17;</code>
-     * @return The a.
-     */
-    int getA();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.OptionalGroup_extension}
-   */
-  public  static final class OptionalGroup_extension extends
-      com.google.protobuf.GeneratedMessageLite<
-          OptionalGroup_extension, OptionalGroup_extension.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.OptionalGroup_extension)
-      OptionalGroup_extensionOrBuilder {
-    private OptionalGroup_extension() {
-    }
-    private int bitField0_;
-    public static final int A_FIELD_NUMBER = 17;
-    private int a_;
-    /**
-     * <code>optional int32 a = 17;</code>
-     * @return Whether the a field is set.
-     */
-    @java.lang.Override
-    public boolean hasA() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 a = 17;</code>
-     * @return The a.
-     */
-    @java.lang.Override
-    public int getA() {
-      return a_;
-    }
-    /**
-     * <code>optional int32 a = 17;</code>
-     * @param value The a to set.
-     */
-    private void setA(int value) {
-      bitField0_ |= 0x00000001;
-      a_ = value;
-    }
-    /**
-     * <code>optional int32 a = 17;</code>
-     */
-    private void clearA() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      a_ = 0;
-    }
-
-    public static protobuf_unittest.UnittestProto.OptionalGroup_extension parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.OptionalGroup_extension parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.OptionalGroup_extension parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.OptionalGroup_extension parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.OptionalGroup_extension parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.OptionalGroup_extension parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.OptionalGroup_extension parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.OptionalGroup_extension parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.OptionalGroup_extension parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.OptionalGroup_extension parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.OptionalGroup_extension parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.OptionalGroup_extension parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.OptionalGroup_extension prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.OptionalGroup_extension}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.OptionalGroup_extension, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.OptionalGroup_extension)
-        protobuf_unittest.UnittestProto.OptionalGroup_extensionOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.OptionalGroup_extension.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return instance.hasA();
-      }
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public int getA() {
-        return instance.getA();
-      }
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @param value The a to set.
-       * @return This builder for chaining.
-       */
-      public Builder setA(int value) {
-        copyOnWrite();
-        instance.setA(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearA() {
-        copyOnWrite();
-        instance.clearA();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.OptionalGroup_extension)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.OptionalGroup_extension();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "a_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0011\u0011\u0001\u0000\u0000\u0000\u0011\u1004\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.OptionalGroup_extension> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.OptionalGroup_extension.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.OptionalGroup_extension>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.OptionalGroup_extension)
-    private static final protobuf_unittest.UnittestProto.OptionalGroup_extension DEFAULT_INSTANCE;
-    static {
-      OptionalGroup_extension defaultInstance = new OptionalGroup_extension();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        OptionalGroup_extension.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.OptionalGroup_extension getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<OptionalGroup_extension> PARSER;
-
-    public static com.google.protobuf.Parser<OptionalGroup_extension> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface RepeatedGroup_extensionOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.RepeatedGroup_extension)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional int32 a = 47;</code>
-     * @return Whether the a field is set.
-     */
-    boolean hasA();
-    /**
-     * <code>optional int32 a = 47;</code>
-     * @return The a.
-     */
-    int getA();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.RepeatedGroup_extension}
-   */
-  public  static final class RepeatedGroup_extension extends
-      com.google.protobuf.GeneratedMessageLite<
-          RepeatedGroup_extension, RepeatedGroup_extension.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.RepeatedGroup_extension)
-      RepeatedGroup_extensionOrBuilder {
-    private RepeatedGroup_extension() {
-    }
-    private int bitField0_;
-    public static final int A_FIELD_NUMBER = 47;
-    private int a_;
-    /**
-     * <code>optional int32 a = 47;</code>
-     * @return Whether the a field is set.
-     */
-    @java.lang.Override
-    public boolean hasA() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 a = 47;</code>
-     * @return The a.
-     */
-    @java.lang.Override
-    public int getA() {
-      return a_;
-    }
-    /**
-     * <code>optional int32 a = 47;</code>
-     * @param value The a to set.
-     */
-    private void setA(int value) {
-      bitField0_ |= 0x00000001;
-      a_ = value;
-    }
-    /**
-     * <code>optional int32 a = 47;</code>
-     */
-    private void clearA() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      a_ = 0;
-    }
-
-    public static protobuf_unittest.UnittestProto.RepeatedGroup_extension parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.RepeatedGroup_extension parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.RepeatedGroup_extension parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.RepeatedGroup_extension parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.RepeatedGroup_extension parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.RepeatedGroup_extension parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.RepeatedGroup_extension parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.RepeatedGroup_extension parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.RepeatedGroup_extension parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.RepeatedGroup_extension parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.RepeatedGroup_extension parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.RepeatedGroup_extension parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.RepeatedGroup_extension prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.RepeatedGroup_extension}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.RepeatedGroup_extension, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.RepeatedGroup_extension)
-        protobuf_unittest.UnittestProto.RepeatedGroup_extensionOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.RepeatedGroup_extension.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int32 a = 47;</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return instance.hasA();
-      }
-      /**
-       * <code>optional int32 a = 47;</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public int getA() {
-        return instance.getA();
-      }
-      /**
-       * <code>optional int32 a = 47;</code>
-       * @param value The a to set.
-       * @return This builder for chaining.
-       */
-      public Builder setA(int value) {
-        copyOnWrite();
-        instance.setA(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 a = 47;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearA() {
-        copyOnWrite();
-        instance.clearA();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.RepeatedGroup_extension)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.RepeatedGroup_extension();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "a_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001//\u0001\u0000\u0000\u0000/\u1004\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.RepeatedGroup_extension> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.RepeatedGroup_extension.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.RepeatedGroup_extension>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.RepeatedGroup_extension)
-    private static final protobuf_unittest.UnittestProto.RepeatedGroup_extension DEFAULT_INSTANCE;
-    static {
-      RepeatedGroup_extension defaultInstance = new RepeatedGroup_extension();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        RepeatedGroup_extension.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.RepeatedGroup_extension getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<RepeatedGroup_extension> PARSER;
-
-    public static com.google.protobuf.Parser<RepeatedGroup_extension> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestGroupOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestGroup)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     * @return Whether the optionalgroup field is set.
-     */
-    boolean hasOptionalGroup();
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     * @return The optionalgroup.
-     */
-    protobuf_unittest.UnittestProto.TestGroup.OptionalGroup getOptionalGroup();
-
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     * @return Whether the optionalForeignEnum field is set.
-     */
-    boolean hasOptionalForeignEnum();
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     * @return The optionalForeignEnum.
-     */
-    protobuf_unittest.UnittestProto.ForeignEnum getOptionalForeignEnum();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestGroup}
-   */
-  public  static final class TestGroup extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestGroup, TestGroup.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestGroup)
-      TestGroupOrBuilder {
-    private TestGroup() {
-      optionalForeignEnum_ = 4;
-    }
-    public interface OptionalGroupOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestGroup.OptionalGroup)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return Whether the a field is set.
-       */
-      boolean hasA();
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return The a.
-       */
-      int getA();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestGroup.OptionalGroup}
-     */
-    public  static final class OptionalGroup extends
-        com.google.protobuf.GeneratedMessageLite<
-            OptionalGroup, OptionalGroup.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestGroup.OptionalGroup)
-        OptionalGroupOrBuilder {
-      private OptionalGroup() {
-      }
-      private int bitField0_;
-      public static final int A_FIELD_NUMBER = 17;
-      private int a_;
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public int getA() {
-        return a_;
-      }
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @param value The a to set.
-       */
-      private void setA(int value) {
-        bitField0_ |= 0x00000001;
-        a_ = value;
-      }
-      /**
-       * <code>optional int32 a = 17;</code>
-       */
-      private void clearA() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        a_ = 0;
-      }
-
-      public static protobuf_unittest.UnittestProto.TestGroup.OptionalGroup parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestGroup.OptionalGroup parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestGroup.OptionalGroup parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestGroup.OptionalGroup parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestGroup.OptionalGroup parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestGroup.OptionalGroup parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestGroup.OptionalGroup parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestGroup.OptionalGroup parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestGroup.OptionalGroup parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestGroup.OptionalGroup parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestGroup.OptionalGroup parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestGroup.OptionalGroup parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestGroup.OptionalGroup prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestGroup.OptionalGroup}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestGroup.OptionalGroup, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestGroup.OptionalGroup)
-          protobuf_unittest.UnittestProto.TestGroup.OptionalGroupOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestGroup.OptionalGroup.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int32 a = 17;</code>
-         * @return Whether the a field is set.
-         */
-        @java.lang.Override
-        public boolean hasA() {
-          return instance.hasA();
-        }
-        /**
-         * <code>optional int32 a = 17;</code>
-         * @return The a.
-         */
-        @java.lang.Override
-        public int getA() {
-          return instance.getA();
-        }
-        /**
-         * <code>optional int32 a = 17;</code>
-         * @param value The a to set.
-         * @return This builder for chaining.
-         */
-        public Builder setA(int value) {
-          copyOnWrite();
-          instance.setA(value);
-          return this;
-        }
-        /**
-         * <code>optional int32 a = 17;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearA() {
-          copyOnWrite();
-          instance.clearA();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestGroup.OptionalGroup)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestGroup.OptionalGroup();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "a_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\u0011\u0011\u0001\u0000\u0000\u0000\u0011\u1004\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestGroup.OptionalGroup> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestGroup.OptionalGroup.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestGroup.OptionalGroup>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestGroup.OptionalGroup)
-      private static final protobuf_unittest.UnittestProto.TestGroup.OptionalGroup DEFAULT_INSTANCE;
-      static {
-        OptionalGroup defaultInstance = new OptionalGroup();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          OptionalGroup.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestGroup.OptionalGroup getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<OptionalGroup> PARSER;
-
-      public static com.google.protobuf.Parser<OptionalGroup> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int bitField0_;
-    public static final int OPTIONALGROUP_FIELD_NUMBER = 16;
-    private protobuf_unittest.UnittestProto.TestGroup.OptionalGroup optionalGroup_;
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalGroup() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestGroup.OptionalGroup getOptionalGroup() {
-      return optionalGroup_ == null ? protobuf_unittest.UnittestProto.TestGroup.OptionalGroup.getDefaultInstance() : optionalGroup_;
-    }
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     */
-    private void setOptionalGroup(protobuf_unittest.UnittestProto.TestGroup.OptionalGroup value) {
-      value.getClass();
-  optionalGroup_ = value;
-      bitField0_ |= 0x00000001;
-      }
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalGroup(protobuf_unittest.UnittestProto.TestGroup.OptionalGroup value) {
-      value.getClass();
-  if (optionalGroup_ != null &&
-          optionalGroup_ != protobuf_unittest.UnittestProto.TestGroup.OptionalGroup.getDefaultInstance()) {
-        optionalGroup_ =
-          protobuf_unittest.UnittestProto.TestGroup.OptionalGroup.newBuilder(optionalGroup_).mergeFrom(value).buildPartial();
-      } else {
-        optionalGroup_ = value;
-      }
-      bitField0_ |= 0x00000001;
-    }
-    /**
-     * <code>optional group OptionalGroup = 16 { ... }</code>
-     */
-    private void clearOptionalGroup() {  optionalGroup_ = null;
-      bitField0_ = (bitField0_ & ~0x00000001);
-    }
-
-    public static final int OPTIONAL_FOREIGN_ENUM_FIELD_NUMBER = 22;
-    private int optionalForeignEnum_;
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     * @return Whether the optionalForeignEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalForeignEnum() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     * @return The optionalForeignEnum.
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.ForeignEnum getOptionalForeignEnum() {
-      protobuf_unittest.UnittestProto.ForeignEnum result = protobuf_unittest.UnittestProto.ForeignEnum.forNumber(optionalForeignEnum_);
-      return result == null ? protobuf_unittest.UnittestProto.ForeignEnum.FOREIGN_FOO : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     * @param value The optionalForeignEnum to set.
-     */
-    private void setOptionalForeignEnum(protobuf_unittest.UnittestProto.ForeignEnum value) {
-      optionalForeignEnum_ = value.getNumber();
-      bitField0_ |= 0x00000002;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-     */
-    private void clearOptionalForeignEnum() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      optionalForeignEnum_ = 4;
-    }
-
-    public static protobuf_unittest.UnittestProto.TestGroup parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroup parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroup parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroup parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroup parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroup parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroup parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroup parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroup parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroup parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroup parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroup parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestGroup prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestGroup}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestGroup, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestGroup)
-        protobuf_unittest.UnittestProto.TestGroupOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestGroup.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional group OptionalGroup = 16 { ... }</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalGroup() {
-        return instance.hasOptionalGroup();
-      }
-      /**
-       * <code>optional group OptionalGroup = 16 { ... }</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestGroup.OptionalGroup getOptionalGroup() {
-        return instance.getOptionalGroup();
-      }
-      /**
-       * <code>optional group OptionalGroup = 16 { ... }</code>
-       */
-      public Builder setOptionalGroup(protobuf_unittest.UnittestProto.TestGroup.OptionalGroup value) {
-        copyOnWrite();
-        instance.setOptionalGroup(value);
-        return this;
-        }
-      /**
-       * <code>optional group OptionalGroup = 16 { ... }</code>
-       */
-      public Builder setOptionalGroup(
-          protobuf_unittest.UnittestProto.TestGroup.OptionalGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalGroup(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional group OptionalGroup = 16 { ... }</code>
-       */
-      public Builder mergeOptionalGroup(protobuf_unittest.UnittestProto.TestGroup.OptionalGroup value) {
-        copyOnWrite();
-        instance.mergeOptionalGroup(value);
-        return this;
-      }
-      /**
-       * <code>optional group OptionalGroup = 16 { ... }</code>
-       */
-      public Builder clearOptionalGroup() {  copyOnWrite();
-        instance.clearOptionalGroup();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-       * @return Whether the optionalForeignEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalForeignEnum() {
-        return instance.hasOptionalForeignEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-       * @return The optionalForeignEnum.
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.ForeignEnum getOptionalForeignEnum() {
-        return instance.getOptionalForeignEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-       * @param value The enum numeric value on the wire for optionalForeignEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalForeignEnum(protobuf_unittest.UnittestProto.ForeignEnum value) {
-        copyOnWrite();
-        instance.setOptionalForeignEnum(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum optional_foreign_enum = 22;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalForeignEnum() {
-        copyOnWrite();
-        instance.clearOptionalForeignEnum();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestGroup)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestGroup();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "optionalGroup_",
-              "optionalForeignEnum_",
-              protobuf_unittest.UnittestProto.ForeignEnum.internalGetVerifier(),
-            };
-            java.lang.String info =
-                "\u0001\u0002\u0000\u0001\u0010\u0016\u0002\u0000\u0000\u0000\u0010\u1011\u0000\u0016" +
-                "\u100c\u0001";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestGroup> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestGroup.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestGroup>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestGroup)
-    private static final protobuf_unittest.UnittestProto.TestGroup DEFAULT_INSTANCE;
-    static {
-      TestGroup defaultInstance = new TestGroup();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestGroup.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestGroup getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestGroup> PARSER;
-
-    public static com.google.protobuf.Parser<TestGroup> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestGroupExtensionOrBuilder extends 
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestGroupExtension)
-       com.google.protobuf.GeneratedMessageLite.
-            ExtendableMessageOrBuilder<
-                TestGroupExtension, TestGroupExtension.Builder> {
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestGroupExtension}
-   */
-  public  static final class TestGroupExtension extends
-      com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
-        TestGroupExtension, TestGroupExtension.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestGroupExtension)
-      TestGroupExtensionOrBuilder {
-    private TestGroupExtension() {
-    }
-    public static protobuf_unittest.UnittestProto.TestGroupExtension parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroupExtension parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroupExtension parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroupExtension parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroupExtension parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroupExtension parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroupExtension parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroupExtension parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroupExtension parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroupExtension parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroupExtension parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestGroupExtension parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestGroupExtension prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestGroupExtension}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
-          protobuf_unittest.UnittestProto.TestGroupExtension, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestGroupExtension)
-        protobuf_unittest.UnittestProto.TestGroupExtensionOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestGroupExtension.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestGroupExtension)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestGroupExtension();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestGroupExtension> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestGroupExtension.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestGroupExtension>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestGroupExtension)
-    private static final protobuf_unittest.UnittestProto.TestGroupExtension DEFAULT_INSTANCE;
-    static {
-      TestGroupExtension defaultInstance = new TestGroupExtension();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestGroupExtension.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestGroupExtension getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestGroupExtension> PARSER;
-
-    public static com.google.protobuf.Parser<TestGroupExtension> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestNestedExtensionOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestNestedExtension)
-      com.google.protobuf.MessageLiteOrBuilder {
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestNestedExtension}
-   */
-  public  static final class TestNestedExtension extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestNestedExtension, TestNestedExtension.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestNestedExtension)
-      TestNestedExtensionOrBuilder {
-    private TestNestedExtension() {
-    }
-    public interface OptionalGroup_extensionOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestNestedExtension.OptionalGroup_extension)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return Whether the a field is set.
-       */
-      boolean hasA();
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return The a.
-       */
-      int getA();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestNestedExtension.OptionalGroup_extension}
-     */
-    public  static final class OptionalGroup_extension extends
-        com.google.protobuf.GeneratedMessageLite<
-            OptionalGroup_extension, OptionalGroup_extension.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestNestedExtension.OptionalGroup_extension)
-        OptionalGroup_extensionOrBuilder {
-      private OptionalGroup_extension() {
-      }
-      private int bitField0_;
-      public static final int A_FIELD_NUMBER = 17;
-      private int a_;
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public int getA() {
-        return a_;
-      }
-      /**
-       * <code>optional int32 a = 17;</code>
-       * @param value The a to set.
-       */
-      private void setA(int value) {
-        bitField0_ |= 0x00000001;
-        a_ = value;
-      }
-      /**
-       * <code>optional int32 a = 17;</code>
-       */
-      private void clearA() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        a_ = 0;
-      }
-
-      public static protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestNestedExtension.OptionalGroup_extension}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestNestedExtension.OptionalGroup_extension)
-          protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extensionOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int32 a = 17;</code>
-         * @return Whether the a field is set.
-         */
-        @java.lang.Override
-        public boolean hasA() {
-          return instance.hasA();
-        }
-        /**
-         * <code>optional int32 a = 17;</code>
-         * @return The a.
-         */
-        @java.lang.Override
-        public int getA() {
-          return instance.getA();
-        }
-        /**
-         * <code>optional int32 a = 17;</code>
-         * @param value The a to set.
-         * @return This builder for chaining.
-         */
-        public Builder setA(int value) {
-          copyOnWrite();
-          instance.setA(value);
-          return this;
-        }
-        /**
-         * <code>optional int32 a = 17;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearA() {
-          copyOnWrite();
-          instance.clearA();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestNestedExtension.OptionalGroup_extension)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "a_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\u0011\u0011\u0001\u0000\u0000\u0000\u0011\u1004\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestNestedExtension.OptionalGroup_extension)
-      private static final protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension DEFAULT_INSTANCE;
-      static {
-        OptionalGroup_extension defaultInstance = new OptionalGroup_extension();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          OptionalGroup_extension.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<OptionalGroup_extension> PARSER;
-
-      public static com.google.protobuf.Parser<OptionalGroup_extension> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    public static protobuf_unittest.UnittestProto.TestNestedExtension parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedExtension parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedExtension parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedExtension parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedExtension parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedExtension parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedExtension parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedExtension parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedExtension parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedExtension parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedExtension parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedExtension parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestNestedExtension prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestNestedExtension}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestNestedExtension, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestNestedExtension)
-        protobuf_unittest.UnittestProto.TestNestedExtensionOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestNestedExtension.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestNestedExtension)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestNestedExtension();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestNestedExtension> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestNestedExtension.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestNestedExtension>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestNestedExtension)
-    private static final protobuf_unittest.UnittestProto.TestNestedExtension DEFAULT_INSTANCE;
-    static {
-      TestNestedExtension defaultInstance = new TestNestedExtension();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestNestedExtension.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestNestedExtension getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestNestedExtension> PARSER;
-
-    public static com.google.protobuf.Parser<TestNestedExtension> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-    public static final int TEST_FIELD_NUMBER = 1002;
-    /**
-     * <pre>
-     * Check for bug where string extensions declared in tested scope did not
-     * compile.
-     * </pre>
-     *
-     * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-     */
-    public static final
-      com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-        protobuf_unittest.UnittestProto.TestAllExtensions,
-        java.lang.String> test = com.google.protobuf.GeneratedMessageLite
-            .newSingularGeneratedExtension(
-          protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-          "test",
-          null,
-          null,
-          1002,
-          com.google.protobuf.WireFormat.FieldType.STRING,
-          java.lang.String.class);
-    public static final int NESTED_STRING_EXTENSION_FIELD_NUMBER = 1003;
-    /**
-     * <pre>
-     * Used to test if generated extension name is correct when there are
-     * underscores.
-     * </pre>
-     *
-     * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-     */
-    public static final
-      com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-        protobuf_unittest.UnittestProto.TestAllExtensions,
-        java.lang.String> nestedStringExtension = com.google.protobuf.GeneratedMessageLite
-            .newSingularGeneratedExtension(
-          protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-          "",
-          null,
-          null,
-          1003,
-          com.google.protobuf.WireFormat.FieldType.STRING,
-          java.lang.String.class);
-    public static final int OPTIONALGROUP_EXTENSION_FIELD_NUMBER = 16;
-    /**
-     * <code>extend .protobuf_unittest.TestGroupExtension { ... }</code>
-     */
-    public static final
-      com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-        protobuf_unittest.UnittestProto.TestGroupExtension,
-        protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension> optionalGroupExtension = com.google.protobuf.GeneratedMessageLite
-            .newSingularGeneratedExtension(
-          protobuf_unittest.UnittestProto.TestGroupExtension.getDefaultInstance(),
-          protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension.getDefaultInstance(),
-          protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension.getDefaultInstance(),
-          null,
-          16,
-          com.google.protobuf.WireFormat.FieldType.GROUP,
-          protobuf_unittest.UnittestProto.TestNestedExtension.OptionalGroup_extension.class);
-    public static final int OPTIONAL_FOREIGN_ENUM_EXTENSION_FIELD_NUMBER = 22;
-    /**
-     * <code>extend .protobuf_unittest.TestGroupExtension { ... }</code>
-     */
-    public static final
-      com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-        protobuf_unittest.UnittestProto.TestGroupExtension,
-        protobuf_unittest.UnittestProto.ForeignEnum> optionalForeignEnumExtension = com.google.protobuf.GeneratedMessageLite
-            .newSingularGeneratedExtension(
-          protobuf_unittest.UnittestProto.TestGroupExtension.getDefaultInstance(),
-          protobuf_unittest.UnittestProto.ForeignEnum.FOREIGN_FOO,
-          null,
-          protobuf_unittest.UnittestProto.ForeignEnum.internalGetValueMap(),
-          22,
-          com.google.protobuf.WireFormat.FieldType.ENUM,
-          protobuf_unittest.UnittestProto.ForeignEnum.class);
-  }
-
-  public interface TestRequiredOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestRequired)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>required int32 a = 1;</code>
-     * @return Whether the a field is set.
-     */
-    boolean hasA();
-    /**
-     * <code>required int32 a = 1;</code>
-     * @return The a.
-     */
-    int getA();
-
-    /**
-     * <code>optional int32 dummy2 = 2;</code>
-     * @return Whether the dummy2 field is set.
-     */
-    boolean hasDummy2();
-    /**
-     * <code>optional int32 dummy2 = 2;</code>
-     * @return The dummy2.
-     */
-    int getDummy2();
-
-    /**
-     * <code>required int32 b = 3;</code>
-     * @return Whether the b field is set.
-     */
-    boolean hasB();
-    /**
-     * <code>required int32 b = 3;</code>
-     * @return The b.
-     */
-    int getB();
-
-    /**
-     * <pre>
-     * Pad the field count to 32 so that we can test that IsInitialized()
-     * properly checks multiple elements of has_bits_.
-     * </pre>
-     *
-     * <code>optional int32 dummy4 = 4;</code>
-     * @return Whether the dummy4 field is set.
-     */
-    boolean hasDummy4();
-    /**
-     * <pre>
-     * Pad the field count to 32 so that we can test that IsInitialized()
-     * properly checks multiple elements of has_bits_.
-     * </pre>
-     *
-     * <code>optional int32 dummy4 = 4;</code>
-     * @return The dummy4.
-     */
-    int getDummy4();
-
-    /**
-     * <code>optional int32 dummy5 = 5;</code>
-     * @return Whether the dummy5 field is set.
-     */
-    boolean hasDummy5();
-    /**
-     * <code>optional int32 dummy5 = 5;</code>
-     * @return The dummy5.
-     */
-    int getDummy5();
-
-    /**
-     * <code>optional int32 dummy6 = 6;</code>
-     * @return Whether the dummy6 field is set.
-     */
-    boolean hasDummy6();
-    /**
-     * <code>optional int32 dummy6 = 6;</code>
-     * @return The dummy6.
-     */
-    int getDummy6();
-
-    /**
-     * <code>optional int32 dummy7 = 7;</code>
-     * @return Whether the dummy7 field is set.
-     */
-    boolean hasDummy7();
-    /**
-     * <code>optional int32 dummy7 = 7;</code>
-     * @return The dummy7.
-     */
-    int getDummy7();
-
-    /**
-     * <code>optional int32 dummy8 = 8;</code>
-     * @return Whether the dummy8 field is set.
-     */
-    boolean hasDummy8();
-    /**
-     * <code>optional int32 dummy8 = 8;</code>
-     * @return The dummy8.
-     */
-    int getDummy8();
-
-    /**
-     * <code>optional int32 dummy9 = 9;</code>
-     * @return Whether the dummy9 field is set.
-     */
-    boolean hasDummy9();
-    /**
-     * <code>optional int32 dummy9 = 9;</code>
-     * @return The dummy9.
-     */
-    int getDummy9();
-
-    /**
-     * <code>optional int32 dummy10 = 10;</code>
-     * @return Whether the dummy10 field is set.
-     */
-    boolean hasDummy10();
-    /**
-     * <code>optional int32 dummy10 = 10;</code>
-     * @return The dummy10.
-     */
-    int getDummy10();
-
-    /**
-     * <code>optional int32 dummy11 = 11;</code>
-     * @return Whether the dummy11 field is set.
-     */
-    boolean hasDummy11();
-    /**
-     * <code>optional int32 dummy11 = 11;</code>
-     * @return The dummy11.
-     */
-    int getDummy11();
-
-    /**
-     * <code>optional int32 dummy12 = 12;</code>
-     * @return Whether the dummy12 field is set.
-     */
-    boolean hasDummy12();
-    /**
-     * <code>optional int32 dummy12 = 12;</code>
-     * @return The dummy12.
-     */
-    int getDummy12();
-
-    /**
-     * <code>optional int32 dummy13 = 13;</code>
-     * @return Whether the dummy13 field is set.
-     */
-    boolean hasDummy13();
-    /**
-     * <code>optional int32 dummy13 = 13;</code>
-     * @return The dummy13.
-     */
-    int getDummy13();
-
-    /**
-     * <code>optional int32 dummy14 = 14;</code>
-     * @return Whether the dummy14 field is set.
-     */
-    boolean hasDummy14();
-    /**
-     * <code>optional int32 dummy14 = 14;</code>
-     * @return The dummy14.
-     */
-    int getDummy14();
-
-    /**
-     * <code>optional int32 dummy15 = 15;</code>
-     * @return Whether the dummy15 field is set.
-     */
-    boolean hasDummy15();
-    /**
-     * <code>optional int32 dummy15 = 15;</code>
-     * @return The dummy15.
-     */
-    int getDummy15();
-
-    /**
-     * <code>optional int32 dummy16 = 16;</code>
-     * @return Whether the dummy16 field is set.
-     */
-    boolean hasDummy16();
-    /**
-     * <code>optional int32 dummy16 = 16;</code>
-     * @return The dummy16.
-     */
-    int getDummy16();
-
-    /**
-     * <code>optional int32 dummy17 = 17;</code>
-     * @return Whether the dummy17 field is set.
-     */
-    boolean hasDummy17();
-    /**
-     * <code>optional int32 dummy17 = 17;</code>
-     * @return The dummy17.
-     */
-    int getDummy17();
-
-    /**
-     * <code>optional int32 dummy18 = 18;</code>
-     * @return Whether the dummy18 field is set.
-     */
-    boolean hasDummy18();
-    /**
-     * <code>optional int32 dummy18 = 18;</code>
-     * @return The dummy18.
-     */
-    int getDummy18();
-
-    /**
-     * <code>optional int32 dummy19 = 19;</code>
-     * @return Whether the dummy19 field is set.
-     */
-    boolean hasDummy19();
-    /**
-     * <code>optional int32 dummy19 = 19;</code>
-     * @return The dummy19.
-     */
-    int getDummy19();
-
-    /**
-     * <code>optional int32 dummy20 = 20;</code>
-     * @return Whether the dummy20 field is set.
-     */
-    boolean hasDummy20();
-    /**
-     * <code>optional int32 dummy20 = 20;</code>
-     * @return The dummy20.
-     */
-    int getDummy20();
-
-    /**
-     * <code>optional int32 dummy21 = 21;</code>
-     * @return Whether the dummy21 field is set.
-     */
-    boolean hasDummy21();
-    /**
-     * <code>optional int32 dummy21 = 21;</code>
-     * @return The dummy21.
-     */
-    int getDummy21();
-
-    /**
-     * <code>optional int32 dummy22 = 22;</code>
-     * @return Whether the dummy22 field is set.
-     */
-    boolean hasDummy22();
-    /**
-     * <code>optional int32 dummy22 = 22;</code>
-     * @return The dummy22.
-     */
-    int getDummy22();
-
-    /**
-     * <code>optional int32 dummy23 = 23;</code>
-     * @return Whether the dummy23 field is set.
-     */
-    boolean hasDummy23();
-    /**
-     * <code>optional int32 dummy23 = 23;</code>
-     * @return The dummy23.
-     */
-    int getDummy23();
-
-    /**
-     * <code>optional int32 dummy24 = 24;</code>
-     * @return Whether the dummy24 field is set.
-     */
-    boolean hasDummy24();
-    /**
-     * <code>optional int32 dummy24 = 24;</code>
-     * @return The dummy24.
-     */
-    int getDummy24();
-
-    /**
-     * <code>optional int32 dummy25 = 25;</code>
-     * @return Whether the dummy25 field is set.
-     */
-    boolean hasDummy25();
-    /**
-     * <code>optional int32 dummy25 = 25;</code>
-     * @return The dummy25.
-     */
-    int getDummy25();
-
-    /**
-     * <code>optional int32 dummy26 = 26;</code>
-     * @return Whether the dummy26 field is set.
-     */
-    boolean hasDummy26();
-    /**
-     * <code>optional int32 dummy26 = 26;</code>
-     * @return The dummy26.
-     */
-    int getDummy26();
-
-    /**
-     * <code>optional int32 dummy27 = 27;</code>
-     * @return Whether the dummy27 field is set.
-     */
-    boolean hasDummy27();
-    /**
-     * <code>optional int32 dummy27 = 27;</code>
-     * @return The dummy27.
-     */
-    int getDummy27();
-
-    /**
-     * <code>optional int32 dummy28 = 28;</code>
-     * @return Whether the dummy28 field is set.
-     */
-    boolean hasDummy28();
-    /**
-     * <code>optional int32 dummy28 = 28;</code>
-     * @return The dummy28.
-     */
-    int getDummy28();
-
-    /**
-     * <code>optional int32 dummy29 = 29;</code>
-     * @return Whether the dummy29 field is set.
-     */
-    boolean hasDummy29();
-    /**
-     * <code>optional int32 dummy29 = 29;</code>
-     * @return The dummy29.
-     */
-    int getDummy29();
-
-    /**
-     * <code>optional int32 dummy30 = 30;</code>
-     * @return Whether the dummy30 field is set.
-     */
-    boolean hasDummy30();
-    /**
-     * <code>optional int32 dummy30 = 30;</code>
-     * @return The dummy30.
-     */
-    int getDummy30();
-
-    /**
-     * <code>optional int32 dummy31 = 31;</code>
-     * @return Whether the dummy31 field is set.
-     */
-    boolean hasDummy31();
-    /**
-     * <code>optional int32 dummy31 = 31;</code>
-     * @return The dummy31.
-     */
-    int getDummy31();
-
-    /**
-     * <code>optional int32 dummy32 = 32;</code>
-     * @return Whether the dummy32 field is set.
-     */
-    boolean hasDummy32();
-    /**
-     * <code>optional int32 dummy32 = 32;</code>
-     * @return The dummy32.
-     */
-    int getDummy32();
-
-    /**
-     * <code>required int32 c = 33;</code>
-     * @return Whether the c field is set.
-     */
-    boolean hasC();
-    /**
-     * <code>required int32 c = 33;</code>
-     * @return The c.
-     */
-    int getC();
-  }
-  /**
-   * <pre>
-   * We have separate messages for testing required fields because it's
-   * annoying to have to fill in required fields in TestProto in order to
-   * do anything with it.  Note that we don't need to test every type of
-   * required filed because the code output is basically identical to
-   * optional fields for all types.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestRequired}
-   */
-  public  static final class TestRequired extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestRequired, TestRequired.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestRequired)
-      TestRequiredOrBuilder {
-    private TestRequired() {
-    }
-    private int bitField0_;
-    private int bitField1_;
-    public static final int A_FIELD_NUMBER = 1;
-    private int a_;
-    /**
-     * <code>required int32 a = 1;</code>
-     * @return Whether the a field is set.
-     */
-    @java.lang.Override
-    public boolean hasA() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>required int32 a = 1;</code>
-     * @return The a.
-     */
-    @java.lang.Override
-    public int getA() {
-      return a_;
-    }
-    /**
-     * <code>required int32 a = 1;</code>
-     * @param value The a to set.
-     */
-    private void setA(int value) {
-      bitField0_ |= 0x00000001;
-      a_ = value;
-    }
-    /**
-     * <code>required int32 a = 1;</code>
-     */
-    private void clearA() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      a_ = 0;
-    }
-
-    public static final int DUMMY2_FIELD_NUMBER = 2;
-    private int dummy2_;
-    /**
-     * <code>optional int32 dummy2 = 2;</code>
-     * @return Whether the dummy2 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy2() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional int32 dummy2 = 2;</code>
-     * @return The dummy2.
-     */
-    @java.lang.Override
-    public int getDummy2() {
-      return dummy2_;
-    }
-    /**
-     * <code>optional int32 dummy2 = 2;</code>
-     * @param value The dummy2 to set.
-     */
-    private void setDummy2(int value) {
-      bitField0_ |= 0x00000002;
-      dummy2_ = value;
-    }
-    /**
-     * <code>optional int32 dummy2 = 2;</code>
-     */
-    private void clearDummy2() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      dummy2_ = 0;
-    }
-
-    public static final int B_FIELD_NUMBER = 3;
-    private int b_;
-    /**
-     * <code>required int32 b = 3;</code>
-     * @return Whether the b field is set.
-     */
-    @java.lang.Override
-    public boolean hasB() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>required int32 b = 3;</code>
-     * @return The b.
-     */
-    @java.lang.Override
-    public int getB() {
-      return b_;
-    }
-    /**
-     * <code>required int32 b = 3;</code>
-     * @param value The b to set.
-     */
-    private void setB(int value) {
-      bitField0_ |= 0x00000004;
-      b_ = value;
-    }
-    /**
-     * <code>required int32 b = 3;</code>
-     */
-    private void clearB() {
-      bitField0_ = (bitField0_ & ~0x00000004);
-      b_ = 0;
-    }
-
-    public static final int DUMMY4_FIELD_NUMBER = 4;
-    private int dummy4_;
-    /**
-     * <pre>
-     * Pad the field count to 32 so that we can test that IsInitialized()
-     * properly checks multiple elements of has_bits_.
-     * </pre>
-     *
-     * <code>optional int32 dummy4 = 4;</code>
-     * @return Whether the dummy4 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy4() {
-      return ((bitField0_ & 0x00000008) != 0);
-    }
-    /**
-     * <pre>
-     * Pad the field count to 32 so that we can test that IsInitialized()
-     * properly checks multiple elements of has_bits_.
-     * </pre>
-     *
-     * <code>optional int32 dummy4 = 4;</code>
-     * @return The dummy4.
-     */
-    @java.lang.Override
-    public int getDummy4() {
-      return dummy4_;
-    }
-    /**
-     * <pre>
-     * Pad the field count to 32 so that we can test that IsInitialized()
-     * properly checks multiple elements of has_bits_.
-     * </pre>
-     *
-     * <code>optional int32 dummy4 = 4;</code>
-     * @param value The dummy4 to set.
-     */
-    private void setDummy4(int value) {
-      bitField0_ |= 0x00000008;
-      dummy4_ = value;
-    }
-    /**
-     * <pre>
-     * Pad the field count to 32 so that we can test that IsInitialized()
-     * properly checks multiple elements of has_bits_.
-     * </pre>
-     *
-     * <code>optional int32 dummy4 = 4;</code>
-     */
-    private void clearDummy4() {
-      bitField0_ = (bitField0_ & ~0x00000008);
-      dummy4_ = 0;
-    }
-
-    public static final int DUMMY5_FIELD_NUMBER = 5;
-    private int dummy5_;
-    /**
-     * <code>optional int32 dummy5 = 5;</code>
-     * @return Whether the dummy5 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy5() {
-      return ((bitField0_ & 0x00000010) != 0);
-    }
-    /**
-     * <code>optional int32 dummy5 = 5;</code>
-     * @return The dummy5.
-     */
-    @java.lang.Override
-    public int getDummy5() {
-      return dummy5_;
-    }
-    /**
-     * <code>optional int32 dummy5 = 5;</code>
-     * @param value The dummy5 to set.
-     */
-    private void setDummy5(int value) {
-      bitField0_ |= 0x00000010;
-      dummy5_ = value;
-    }
-    /**
-     * <code>optional int32 dummy5 = 5;</code>
-     */
-    private void clearDummy5() {
-      bitField0_ = (bitField0_ & ~0x00000010);
-      dummy5_ = 0;
-    }
-
-    public static final int DUMMY6_FIELD_NUMBER = 6;
-    private int dummy6_;
-    /**
-     * <code>optional int32 dummy6 = 6;</code>
-     * @return Whether the dummy6 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy6() {
-      return ((bitField0_ & 0x00000020) != 0);
-    }
-    /**
-     * <code>optional int32 dummy6 = 6;</code>
-     * @return The dummy6.
-     */
-    @java.lang.Override
-    public int getDummy6() {
-      return dummy6_;
-    }
-    /**
-     * <code>optional int32 dummy6 = 6;</code>
-     * @param value The dummy6 to set.
-     */
-    private void setDummy6(int value) {
-      bitField0_ |= 0x00000020;
-      dummy6_ = value;
-    }
-    /**
-     * <code>optional int32 dummy6 = 6;</code>
-     */
-    private void clearDummy6() {
-      bitField0_ = (bitField0_ & ~0x00000020);
-      dummy6_ = 0;
-    }
-
-    public static final int DUMMY7_FIELD_NUMBER = 7;
-    private int dummy7_;
-    /**
-     * <code>optional int32 dummy7 = 7;</code>
-     * @return Whether the dummy7 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy7() {
-      return ((bitField0_ & 0x00000040) != 0);
-    }
-    /**
-     * <code>optional int32 dummy7 = 7;</code>
-     * @return The dummy7.
-     */
-    @java.lang.Override
-    public int getDummy7() {
-      return dummy7_;
-    }
-    /**
-     * <code>optional int32 dummy7 = 7;</code>
-     * @param value The dummy7 to set.
-     */
-    private void setDummy7(int value) {
-      bitField0_ |= 0x00000040;
-      dummy7_ = value;
-    }
-    /**
-     * <code>optional int32 dummy7 = 7;</code>
-     */
-    private void clearDummy7() {
-      bitField0_ = (bitField0_ & ~0x00000040);
-      dummy7_ = 0;
-    }
-
-    public static final int DUMMY8_FIELD_NUMBER = 8;
-    private int dummy8_;
-    /**
-     * <code>optional int32 dummy8 = 8;</code>
-     * @return Whether the dummy8 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy8() {
-      return ((bitField0_ & 0x00000080) != 0);
-    }
-    /**
-     * <code>optional int32 dummy8 = 8;</code>
-     * @return The dummy8.
-     */
-    @java.lang.Override
-    public int getDummy8() {
-      return dummy8_;
-    }
-    /**
-     * <code>optional int32 dummy8 = 8;</code>
-     * @param value The dummy8 to set.
-     */
-    private void setDummy8(int value) {
-      bitField0_ |= 0x00000080;
-      dummy8_ = value;
-    }
-    /**
-     * <code>optional int32 dummy8 = 8;</code>
-     */
-    private void clearDummy8() {
-      bitField0_ = (bitField0_ & ~0x00000080);
-      dummy8_ = 0;
-    }
-
-    public static final int DUMMY9_FIELD_NUMBER = 9;
-    private int dummy9_;
-    /**
-     * <code>optional int32 dummy9 = 9;</code>
-     * @return Whether the dummy9 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy9() {
-      return ((bitField0_ & 0x00000100) != 0);
-    }
-    /**
-     * <code>optional int32 dummy9 = 9;</code>
-     * @return The dummy9.
-     */
-    @java.lang.Override
-    public int getDummy9() {
-      return dummy9_;
-    }
-    /**
-     * <code>optional int32 dummy9 = 9;</code>
-     * @param value The dummy9 to set.
-     */
-    private void setDummy9(int value) {
-      bitField0_ |= 0x00000100;
-      dummy9_ = value;
-    }
-    /**
-     * <code>optional int32 dummy9 = 9;</code>
-     */
-    private void clearDummy9() {
-      bitField0_ = (bitField0_ & ~0x00000100);
-      dummy9_ = 0;
-    }
-
-    public static final int DUMMY10_FIELD_NUMBER = 10;
-    private int dummy10_;
-    /**
-     * <code>optional int32 dummy10 = 10;</code>
-     * @return Whether the dummy10 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy10() {
-      return ((bitField0_ & 0x00000200) != 0);
-    }
-    /**
-     * <code>optional int32 dummy10 = 10;</code>
-     * @return The dummy10.
-     */
-    @java.lang.Override
-    public int getDummy10() {
-      return dummy10_;
-    }
-    /**
-     * <code>optional int32 dummy10 = 10;</code>
-     * @param value The dummy10 to set.
-     */
-    private void setDummy10(int value) {
-      bitField0_ |= 0x00000200;
-      dummy10_ = value;
-    }
-    /**
-     * <code>optional int32 dummy10 = 10;</code>
-     */
-    private void clearDummy10() {
-      bitField0_ = (bitField0_ & ~0x00000200);
-      dummy10_ = 0;
-    }
-
-    public static final int DUMMY11_FIELD_NUMBER = 11;
-    private int dummy11_;
-    /**
-     * <code>optional int32 dummy11 = 11;</code>
-     * @return Whether the dummy11 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy11() {
-      return ((bitField0_ & 0x00000400) != 0);
-    }
-    /**
-     * <code>optional int32 dummy11 = 11;</code>
-     * @return The dummy11.
-     */
-    @java.lang.Override
-    public int getDummy11() {
-      return dummy11_;
-    }
-    /**
-     * <code>optional int32 dummy11 = 11;</code>
-     * @param value The dummy11 to set.
-     */
-    private void setDummy11(int value) {
-      bitField0_ |= 0x00000400;
-      dummy11_ = value;
-    }
-    /**
-     * <code>optional int32 dummy11 = 11;</code>
-     */
-    private void clearDummy11() {
-      bitField0_ = (bitField0_ & ~0x00000400);
-      dummy11_ = 0;
-    }
-
-    public static final int DUMMY12_FIELD_NUMBER = 12;
-    private int dummy12_;
-    /**
-     * <code>optional int32 dummy12 = 12;</code>
-     * @return Whether the dummy12 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy12() {
-      return ((bitField0_ & 0x00000800) != 0);
-    }
-    /**
-     * <code>optional int32 dummy12 = 12;</code>
-     * @return The dummy12.
-     */
-    @java.lang.Override
-    public int getDummy12() {
-      return dummy12_;
-    }
-    /**
-     * <code>optional int32 dummy12 = 12;</code>
-     * @param value The dummy12 to set.
-     */
-    private void setDummy12(int value) {
-      bitField0_ |= 0x00000800;
-      dummy12_ = value;
-    }
-    /**
-     * <code>optional int32 dummy12 = 12;</code>
-     */
-    private void clearDummy12() {
-      bitField0_ = (bitField0_ & ~0x00000800);
-      dummy12_ = 0;
-    }
-
-    public static final int DUMMY13_FIELD_NUMBER = 13;
-    private int dummy13_;
-    /**
-     * <code>optional int32 dummy13 = 13;</code>
-     * @return Whether the dummy13 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy13() {
-      return ((bitField0_ & 0x00001000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy13 = 13;</code>
-     * @return The dummy13.
-     */
-    @java.lang.Override
-    public int getDummy13() {
-      return dummy13_;
-    }
-    /**
-     * <code>optional int32 dummy13 = 13;</code>
-     * @param value The dummy13 to set.
-     */
-    private void setDummy13(int value) {
-      bitField0_ |= 0x00001000;
-      dummy13_ = value;
-    }
-    /**
-     * <code>optional int32 dummy13 = 13;</code>
-     */
-    private void clearDummy13() {
-      bitField0_ = (bitField0_ & ~0x00001000);
-      dummy13_ = 0;
-    }
-
-    public static final int DUMMY14_FIELD_NUMBER = 14;
-    private int dummy14_;
-    /**
-     * <code>optional int32 dummy14 = 14;</code>
-     * @return Whether the dummy14 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy14() {
-      return ((bitField0_ & 0x00002000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy14 = 14;</code>
-     * @return The dummy14.
-     */
-    @java.lang.Override
-    public int getDummy14() {
-      return dummy14_;
-    }
-    /**
-     * <code>optional int32 dummy14 = 14;</code>
-     * @param value The dummy14 to set.
-     */
-    private void setDummy14(int value) {
-      bitField0_ |= 0x00002000;
-      dummy14_ = value;
-    }
-    /**
-     * <code>optional int32 dummy14 = 14;</code>
-     */
-    private void clearDummy14() {
-      bitField0_ = (bitField0_ & ~0x00002000);
-      dummy14_ = 0;
-    }
-
-    public static final int DUMMY15_FIELD_NUMBER = 15;
-    private int dummy15_;
-    /**
-     * <code>optional int32 dummy15 = 15;</code>
-     * @return Whether the dummy15 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy15() {
-      return ((bitField0_ & 0x00004000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy15 = 15;</code>
-     * @return The dummy15.
-     */
-    @java.lang.Override
-    public int getDummy15() {
-      return dummy15_;
-    }
-    /**
-     * <code>optional int32 dummy15 = 15;</code>
-     * @param value The dummy15 to set.
-     */
-    private void setDummy15(int value) {
-      bitField0_ |= 0x00004000;
-      dummy15_ = value;
-    }
-    /**
-     * <code>optional int32 dummy15 = 15;</code>
-     */
-    private void clearDummy15() {
-      bitField0_ = (bitField0_ & ~0x00004000);
-      dummy15_ = 0;
-    }
-
-    public static final int DUMMY16_FIELD_NUMBER = 16;
-    private int dummy16_;
-    /**
-     * <code>optional int32 dummy16 = 16;</code>
-     * @return Whether the dummy16 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy16() {
-      return ((bitField0_ & 0x00008000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy16 = 16;</code>
-     * @return The dummy16.
-     */
-    @java.lang.Override
-    public int getDummy16() {
-      return dummy16_;
-    }
-    /**
-     * <code>optional int32 dummy16 = 16;</code>
-     * @param value The dummy16 to set.
-     */
-    private void setDummy16(int value) {
-      bitField0_ |= 0x00008000;
-      dummy16_ = value;
-    }
-    /**
-     * <code>optional int32 dummy16 = 16;</code>
-     */
-    private void clearDummy16() {
-      bitField0_ = (bitField0_ & ~0x00008000);
-      dummy16_ = 0;
-    }
-
-    public static final int DUMMY17_FIELD_NUMBER = 17;
-    private int dummy17_;
-    /**
-     * <code>optional int32 dummy17 = 17;</code>
-     * @return Whether the dummy17 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy17() {
-      return ((bitField0_ & 0x00010000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy17 = 17;</code>
-     * @return The dummy17.
-     */
-    @java.lang.Override
-    public int getDummy17() {
-      return dummy17_;
-    }
-    /**
-     * <code>optional int32 dummy17 = 17;</code>
-     * @param value The dummy17 to set.
-     */
-    private void setDummy17(int value) {
-      bitField0_ |= 0x00010000;
-      dummy17_ = value;
-    }
-    /**
-     * <code>optional int32 dummy17 = 17;</code>
-     */
-    private void clearDummy17() {
-      bitField0_ = (bitField0_ & ~0x00010000);
-      dummy17_ = 0;
-    }
-
-    public static final int DUMMY18_FIELD_NUMBER = 18;
-    private int dummy18_;
-    /**
-     * <code>optional int32 dummy18 = 18;</code>
-     * @return Whether the dummy18 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy18() {
-      return ((bitField0_ & 0x00020000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy18 = 18;</code>
-     * @return The dummy18.
-     */
-    @java.lang.Override
-    public int getDummy18() {
-      return dummy18_;
-    }
-    /**
-     * <code>optional int32 dummy18 = 18;</code>
-     * @param value The dummy18 to set.
-     */
-    private void setDummy18(int value) {
-      bitField0_ |= 0x00020000;
-      dummy18_ = value;
-    }
-    /**
-     * <code>optional int32 dummy18 = 18;</code>
-     */
-    private void clearDummy18() {
-      bitField0_ = (bitField0_ & ~0x00020000);
-      dummy18_ = 0;
-    }
-
-    public static final int DUMMY19_FIELD_NUMBER = 19;
-    private int dummy19_;
-    /**
-     * <code>optional int32 dummy19 = 19;</code>
-     * @return Whether the dummy19 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy19() {
-      return ((bitField0_ & 0x00040000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy19 = 19;</code>
-     * @return The dummy19.
-     */
-    @java.lang.Override
-    public int getDummy19() {
-      return dummy19_;
-    }
-    /**
-     * <code>optional int32 dummy19 = 19;</code>
-     * @param value The dummy19 to set.
-     */
-    private void setDummy19(int value) {
-      bitField0_ |= 0x00040000;
-      dummy19_ = value;
-    }
-    /**
-     * <code>optional int32 dummy19 = 19;</code>
-     */
-    private void clearDummy19() {
-      bitField0_ = (bitField0_ & ~0x00040000);
-      dummy19_ = 0;
-    }
-
-    public static final int DUMMY20_FIELD_NUMBER = 20;
-    private int dummy20_;
-    /**
-     * <code>optional int32 dummy20 = 20;</code>
-     * @return Whether the dummy20 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy20() {
-      return ((bitField0_ & 0x00080000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy20 = 20;</code>
-     * @return The dummy20.
-     */
-    @java.lang.Override
-    public int getDummy20() {
-      return dummy20_;
-    }
-    /**
-     * <code>optional int32 dummy20 = 20;</code>
-     * @param value The dummy20 to set.
-     */
-    private void setDummy20(int value) {
-      bitField0_ |= 0x00080000;
-      dummy20_ = value;
-    }
-    /**
-     * <code>optional int32 dummy20 = 20;</code>
-     */
-    private void clearDummy20() {
-      bitField0_ = (bitField0_ & ~0x00080000);
-      dummy20_ = 0;
-    }
-
-    public static final int DUMMY21_FIELD_NUMBER = 21;
-    private int dummy21_;
-    /**
-     * <code>optional int32 dummy21 = 21;</code>
-     * @return Whether the dummy21 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy21() {
-      return ((bitField0_ & 0x00100000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy21 = 21;</code>
-     * @return The dummy21.
-     */
-    @java.lang.Override
-    public int getDummy21() {
-      return dummy21_;
-    }
-    /**
-     * <code>optional int32 dummy21 = 21;</code>
-     * @param value The dummy21 to set.
-     */
-    private void setDummy21(int value) {
-      bitField0_ |= 0x00100000;
-      dummy21_ = value;
-    }
-    /**
-     * <code>optional int32 dummy21 = 21;</code>
-     */
-    private void clearDummy21() {
-      bitField0_ = (bitField0_ & ~0x00100000);
-      dummy21_ = 0;
-    }
-
-    public static final int DUMMY22_FIELD_NUMBER = 22;
-    private int dummy22_;
-    /**
-     * <code>optional int32 dummy22 = 22;</code>
-     * @return Whether the dummy22 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy22() {
-      return ((bitField0_ & 0x00200000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy22 = 22;</code>
-     * @return The dummy22.
-     */
-    @java.lang.Override
-    public int getDummy22() {
-      return dummy22_;
-    }
-    /**
-     * <code>optional int32 dummy22 = 22;</code>
-     * @param value The dummy22 to set.
-     */
-    private void setDummy22(int value) {
-      bitField0_ |= 0x00200000;
-      dummy22_ = value;
-    }
-    /**
-     * <code>optional int32 dummy22 = 22;</code>
-     */
-    private void clearDummy22() {
-      bitField0_ = (bitField0_ & ~0x00200000);
-      dummy22_ = 0;
-    }
-
-    public static final int DUMMY23_FIELD_NUMBER = 23;
-    private int dummy23_;
-    /**
-     * <code>optional int32 dummy23 = 23;</code>
-     * @return Whether the dummy23 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy23() {
-      return ((bitField0_ & 0x00400000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy23 = 23;</code>
-     * @return The dummy23.
-     */
-    @java.lang.Override
-    public int getDummy23() {
-      return dummy23_;
-    }
-    /**
-     * <code>optional int32 dummy23 = 23;</code>
-     * @param value The dummy23 to set.
-     */
-    private void setDummy23(int value) {
-      bitField0_ |= 0x00400000;
-      dummy23_ = value;
-    }
-    /**
-     * <code>optional int32 dummy23 = 23;</code>
-     */
-    private void clearDummy23() {
-      bitField0_ = (bitField0_ & ~0x00400000);
-      dummy23_ = 0;
-    }
-
-    public static final int DUMMY24_FIELD_NUMBER = 24;
-    private int dummy24_;
-    /**
-     * <code>optional int32 dummy24 = 24;</code>
-     * @return Whether the dummy24 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy24() {
-      return ((bitField0_ & 0x00800000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy24 = 24;</code>
-     * @return The dummy24.
-     */
-    @java.lang.Override
-    public int getDummy24() {
-      return dummy24_;
-    }
-    /**
-     * <code>optional int32 dummy24 = 24;</code>
-     * @param value The dummy24 to set.
-     */
-    private void setDummy24(int value) {
-      bitField0_ |= 0x00800000;
-      dummy24_ = value;
-    }
-    /**
-     * <code>optional int32 dummy24 = 24;</code>
-     */
-    private void clearDummy24() {
-      bitField0_ = (bitField0_ & ~0x00800000);
-      dummy24_ = 0;
-    }
-
-    public static final int DUMMY25_FIELD_NUMBER = 25;
-    private int dummy25_;
-    /**
-     * <code>optional int32 dummy25 = 25;</code>
-     * @return Whether the dummy25 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy25() {
-      return ((bitField0_ & 0x01000000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy25 = 25;</code>
-     * @return The dummy25.
-     */
-    @java.lang.Override
-    public int getDummy25() {
-      return dummy25_;
-    }
-    /**
-     * <code>optional int32 dummy25 = 25;</code>
-     * @param value The dummy25 to set.
-     */
-    private void setDummy25(int value) {
-      bitField0_ |= 0x01000000;
-      dummy25_ = value;
-    }
-    /**
-     * <code>optional int32 dummy25 = 25;</code>
-     */
-    private void clearDummy25() {
-      bitField0_ = (bitField0_ & ~0x01000000);
-      dummy25_ = 0;
-    }
-
-    public static final int DUMMY26_FIELD_NUMBER = 26;
-    private int dummy26_;
-    /**
-     * <code>optional int32 dummy26 = 26;</code>
-     * @return Whether the dummy26 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy26() {
-      return ((bitField0_ & 0x02000000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy26 = 26;</code>
-     * @return The dummy26.
-     */
-    @java.lang.Override
-    public int getDummy26() {
-      return dummy26_;
-    }
-    /**
-     * <code>optional int32 dummy26 = 26;</code>
-     * @param value The dummy26 to set.
-     */
-    private void setDummy26(int value) {
-      bitField0_ |= 0x02000000;
-      dummy26_ = value;
-    }
-    /**
-     * <code>optional int32 dummy26 = 26;</code>
-     */
-    private void clearDummy26() {
-      bitField0_ = (bitField0_ & ~0x02000000);
-      dummy26_ = 0;
-    }
-
-    public static final int DUMMY27_FIELD_NUMBER = 27;
-    private int dummy27_;
-    /**
-     * <code>optional int32 dummy27 = 27;</code>
-     * @return Whether the dummy27 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy27() {
-      return ((bitField0_ & 0x04000000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy27 = 27;</code>
-     * @return The dummy27.
-     */
-    @java.lang.Override
-    public int getDummy27() {
-      return dummy27_;
-    }
-    /**
-     * <code>optional int32 dummy27 = 27;</code>
-     * @param value The dummy27 to set.
-     */
-    private void setDummy27(int value) {
-      bitField0_ |= 0x04000000;
-      dummy27_ = value;
-    }
-    /**
-     * <code>optional int32 dummy27 = 27;</code>
-     */
-    private void clearDummy27() {
-      bitField0_ = (bitField0_ & ~0x04000000);
-      dummy27_ = 0;
-    }
-
-    public static final int DUMMY28_FIELD_NUMBER = 28;
-    private int dummy28_;
-    /**
-     * <code>optional int32 dummy28 = 28;</code>
-     * @return Whether the dummy28 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy28() {
-      return ((bitField0_ & 0x08000000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy28 = 28;</code>
-     * @return The dummy28.
-     */
-    @java.lang.Override
-    public int getDummy28() {
-      return dummy28_;
-    }
-    /**
-     * <code>optional int32 dummy28 = 28;</code>
-     * @param value The dummy28 to set.
-     */
-    private void setDummy28(int value) {
-      bitField0_ |= 0x08000000;
-      dummy28_ = value;
-    }
-    /**
-     * <code>optional int32 dummy28 = 28;</code>
-     */
-    private void clearDummy28() {
-      bitField0_ = (bitField0_ & ~0x08000000);
-      dummy28_ = 0;
-    }
-
-    public static final int DUMMY29_FIELD_NUMBER = 29;
-    private int dummy29_;
-    /**
-     * <code>optional int32 dummy29 = 29;</code>
-     * @return Whether the dummy29 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy29() {
-      return ((bitField0_ & 0x10000000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy29 = 29;</code>
-     * @return The dummy29.
-     */
-    @java.lang.Override
-    public int getDummy29() {
-      return dummy29_;
-    }
-    /**
-     * <code>optional int32 dummy29 = 29;</code>
-     * @param value The dummy29 to set.
-     */
-    private void setDummy29(int value) {
-      bitField0_ |= 0x10000000;
-      dummy29_ = value;
-    }
-    /**
-     * <code>optional int32 dummy29 = 29;</code>
-     */
-    private void clearDummy29() {
-      bitField0_ = (bitField0_ & ~0x10000000);
-      dummy29_ = 0;
-    }
-
-    public static final int DUMMY30_FIELD_NUMBER = 30;
-    private int dummy30_;
-    /**
-     * <code>optional int32 dummy30 = 30;</code>
-     * @return Whether the dummy30 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy30() {
-      return ((bitField0_ & 0x20000000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy30 = 30;</code>
-     * @return The dummy30.
-     */
-    @java.lang.Override
-    public int getDummy30() {
-      return dummy30_;
-    }
-    /**
-     * <code>optional int32 dummy30 = 30;</code>
-     * @param value The dummy30 to set.
-     */
-    private void setDummy30(int value) {
-      bitField0_ |= 0x20000000;
-      dummy30_ = value;
-    }
-    /**
-     * <code>optional int32 dummy30 = 30;</code>
-     */
-    private void clearDummy30() {
-      bitField0_ = (bitField0_ & ~0x20000000);
-      dummy30_ = 0;
-    }
-
-    public static final int DUMMY31_FIELD_NUMBER = 31;
-    private int dummy31_;
-    /**
-     * <code>optional int32 dummy31 = 31;</code>
-     * @return Whether the dummy31 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy31() {
-      return ((bitField0_ & 0x40000000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy31 = 31;</code>
-     * @return The dummy31.
-     */
-    @java.lang.Override
-    public int getDummy31() {
-      return dummy31_;
-    }
-    /**
-     * <code>optional int32 dummy31 = 31;</code>
-     * @param value The dummy31 to set.
-     */
-    private void setDummy31(int value) {
-      bitField0_ |= 0x40000000;
-      dummy31_ = value;
-    }
-    /**
-     * <code>optional int32 dummy31 = 31;</code>
-     */
-    private void clearDummy31() {
-      bitField0_ = (bitField0_ & ~0x40000000);
-      dummy31_ = 0;
-    }
-
-    public static final int DUMMY32_FIELD_NUMBER = 32;
-    private int dummy32_;
-    /**
-     * <code>optional int32 dummy32 = 32;</code>
-     * @return Whether the dummy32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy32() {
-      return ((bitField0_ & 0x80000000) != 0);
-    }
-    /**
-     * <code>optional int32 dummy32 = 32;</code>
-     * @return The dummy32.
-     */
-    @java.lang.Override
-    public int getDummy32() {
-      return dummy32_;
-    }
-    /**
-     * <code>optional int32 dummy32 = 32;</code>
-     * @param value The dummy32 to set.
-     */
-    private void setDummy32(int value) {
-      bitField0_ |= 0x80000000;
-      dummy32_ = value;
-    }
-    /**
-     * <code>optional int32 dummy32 = 32;</code>
-     */
-    private void clearDummy32() {
-      bitField0_ = (bitField0_ & ~0x80000000);
-      dummy32_ = 0;
-    }
-
-    public static final int C_FIELD_NUMBER = 33;
-    private int c_;
-    /**
-     * <code>required int32 c = 33;</code>
-     * @return Whether the c field is set.
-     */
-    @java.lang.Override
-    public boolean hasC() {
-      return ((bitField1_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>required int32 c = 33;</code>
-     * @return The c.
-     */
-    @java.lang.Override
-    public int getC() {
-      return c_;
-    }
-    /**
-     * <code>required int32 c = 33;</code>
-     * @param value The c to set.
-     */
-    private void setC(int value) {
-      bitField1_ |= 0x00000001;
-      c_ = value;
-    }
-    /**
-     * <code>required int32 c = 33;</code>
-     */
-    private void clearC() {
-      bitField1_ = (bitField1_ & ~0x00000001);
-      c_ = 0;
-    }
-
-    public static protobuf_unittest.UnittestProto.TestRequired parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequired parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequired parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequired parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequired parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequired parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequired parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequired parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequired parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequired parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequired parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequired parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestRequired prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * We have separate messages for testing required fields because it's
-     * annoying to have to fill in required fields in TestProto in order to
-     * do anything with it.  Note that we don't need to test every type of
-     * required filed because the code output is basically identical to
-     * optional fields for all types.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestRequired}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestRequired, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestRequired)
-        protobuf_unittest.UnittestProto.TestRequiredOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestRequired.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>required int32 a = 1;</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return instance.hasA();
-      }
-      /**
-       * <code>required int32 a = 1;</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public int getA() {
-        return instance.getA();
-      }
-      /**
-       * <code>required int32 a = 1;</code>
-       * @param value The a to set.
-       * @return This builder for chaining.
-       */
-      public Builder setA(int value) {
-        copyOnWrite();
-        instance.setA(value);
-        return this;
-      }
-      /**
-       * <code>required int32 a = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearA() {
-        copyOnWrite();
-        instance.clearA();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy2 = 2;</code>
-       * @return Whether the dummy2 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy2() {
-        return instance.hasDummy2();
-      }
-      /**
-       * <code>optional int32 dummy2 = 2;</code>
-       * @return The dummy2.
-       */
-      @java.lang.Override
-      public int getDummy2() {
-        return instance.getDummy2();
-      }
-      /**
-       * <code>optional int32 dummy2 = 2;</code>
-       * @param value The dummy2 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy2(int value) {
-        copyOnWrite();
-        instance.setDummy2(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy2 = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy2() {
-        copyOnWrite();
-        instance.clearDummy2();
-        return this;
-      }
-
-      /**
-       * <code>required int32 b = 3;</code>
-       * @return Whether the b field is set.
-       */
-      @java.lang.Override
-      public boolean hasB() {
-        return instance.hasB();
-      }
-      /**
-       * <code>required int32 b = 3;</code>
-       * @return The b.
-       */
-      @java.lang.Override
-      public int getB() {
-        return instance.getB();
-      }
-      /**
-       * <code>required int32 b = 3;</code>
-       * @param value The b to set.
-       * @return This builder for chaining.
-       */
-      public Builder setB(int value) {
-        copyOnWrite();
-        instance.setB(value);
-        return this;
-      }
-      /**
-       * <code>required int32 b = 3;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearB() {
-        copyOnWrite();
-        instance.clearB();
-        return this;
-      }
-
-      /**
-       * <pre>
-       * Pad the field count to 32 so that we can test that IsInitialized()
-       * properly checks multiple elements of has_bits_.
-       * </pre>
-       *
-       * <code>optional int32 dummy4 = 4;</code>
-       * @return Whether the dummy4 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy4() {
-        return instance.hasDummy4();
-      }
-      /**
-       * <pre>
-       * Pad the field count to 32 so that we can test that IsInitialized()
-       * properly checks multiple elements of has_bits_.
-       * </pre>
-       *
-       * <code>optional int32 dummy4 = 4;</code>
-       * @return The dummy4.
-       */
-      @java.lang.Override
-      public int getDummy4() {
-        return instance.getDummy4();
-      }
-      /**
-       * <pre>
-       * Pad the field count to 32 so that we can test that IsInitialized()
-       * properly checks multiple elements of has_bits_.
-       * </pre>
-       *
-       * <code>optional int32 dummy4 = 4;</code>
-       * @param value The dummy4 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy4(int value) {
-        copyOnWrite();
-        instance.setDummy4(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Pad the field count to 32 so that we can test that IsInitialized()
-       * properly checks multiple elements of has_bits_.
-       * </pre>
-       *
-       * <code>optional int32 dummy4 = 4;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy4() {
-        copyOnWrite();
-        instance.clearDummy4();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy5 = 5;</code>
-       * @return Whether the dummy5 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy5() {
-        return instance.hasDummy5();
-      }
-      /**
-       * <code>optional int32 dummy5 = 5;</code>
-       * @return The dummy5.
-       */
-      @java.lang.Override
-      public int getDummy5() {
-        return instance.getDummy5();
-      }
-      /**
-       * <code>optional int32 dummy5 = 5;</code>
-       * @param value The dummy5 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy5(int value) {
-        copyOnWrite();
-        instance.setDummy5(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy5 = 5;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy5() {
-        copyOnWrite();
-        instance.clearDummy5();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy6 = 6;</code>
-       * @return Whether the dummy6 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy6() {
-        return instance.hasDummy6();
-      }
-      /**
-       * <code>optional int32 dummy6 = 6;</code>
-       * @return The dummy6.
-       */
-      @java.lang.Override
-      public int getDummy6() {
-        return instance.getDummy6();
-      }
-      /**
-       * <code>optional int32 dummy6 = 6;</code>
-       * @param value The dummy6 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy6(int value) {
-        copyOnWrite();
-        instance.setDummy6(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy6 = 6;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy6() {
-        copyOnWrite();
-        instance.clearDummy6();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy7 = 7;</code>
-       * @return Whether the dummy7 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy7() {
-        return instance.hasDummy7();
-      }
-      /**
-       * <code>optional int32 dummy7 = 7;</code>
-       * @return The dummy7.
-       */
-      @java.lang.Override
-      public int getDummy7() {
-        return instance.getDummy7();
-      }
-      /**
-       * <code>optional int32 dummy7 = 7;</code>
-       * @param value The dummy7 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy7(int value) {
-        copyOnWrite();
-        instance.setDummy7(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy7 = 7;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy7() {
-        copyOnWrite();
-        instance.clearDummy7();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy8 = 8;</code>
-       * @return Whether the dummy8 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy8() {
-        return instance.hasDummy8();
-      }
-      /**
-       * <code>optional int32 dummy8 = 8;</code>
-       * @return The dummy8.
-       */
-      @java.lang.Override
-      public int getDummy8() {
-        return instance.getDummy8();
-      }
-      /**
-       * <code>optional int32 dummy8 = 8;</code>
-       * @param value The dummy8 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy8(int value) {
-        copyOnWrite();
-        instance.setDummy8(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy8 = 8;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy8() {
-        copyOnWrite();
-        instance.clearDummy8();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy9 = 9;</code>
-       * @return Whether the dummy9 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy9() {
-        return instance.hasDummy9();
-      }
-      /**
-       * <code>optional int32 dummy9 = 9;</code>
-       * @return The dummy9.
-       */
-      @java.lang.Override
-      public int getDummy9() {
-        return instance.getDummy9();
-      }
-      /**
-       * <code>optional int32 dummy9 = 9;</code>
-       * @param value The dummy9 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy9(int value) {
-        copyOnWrite();
-        instance.setDummy9(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy9 = 9;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy9() {
-        copyOnWrite();
-        instance.clearDummy9();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy10 = 10;</code>
-       * @return Whether the dummy10 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy10() {
-        return instance.hasDummy10();
-      }
-      /**
-       * <code>optional int32 dummy10 = 10;</code>
-       * @return The dummy10.
-       */
-      @java.lang.Override
-      public int getDummy10() {
-        return instance.getDummy10();
-      }
-      /**
-       * <code>optional int32 dummy10 = 10;</code>
-       * @param value The dummy10 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy10(int value) {
-        copyOnWrite();
-        instance.setDummy10(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy10 = 10;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy10() {
-        copyOnWrite();
-        instance.clearDummy10();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy11 = 11;</code>
-       * @return Whether the dummy11 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy11() {
-        return instance.hasDummy11();
-      }
-      /**
-       * <code>optional int32 dummy11 = 11;</code>
-       * @return The dummy11.
-       */
-      @java.lang.Override
-      public int getDummy11() {
-        return instance.getDummy11();
-      }
-      /**
-       * <code>optional int32 dummy11 = 11;</code>
-       * @param value The dummy11 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy11(int value) {
-        copyOnWrite();
-        instance.setDummy11(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy11 = 11;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy11() {
-        copyOnWrite();
-        instance.clearDummy11();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy12 = 12;</code>
-       * @return Whether the dummy12 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy12() {
-        return instance.hasDummy12();
-      }
-      /**
-       * <code>optional int32 dummy12 = 12;</code>
-       * @return The dummy12.
-       */
-      @java.lang.Override
-      public int getDummy12() {
-        return instance.getDummy12();
-      }
-      /**
-       * <code>optional int32 dummy12 = 12;</code>
-       * @param value The dummy12 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy12(int value) {
-        copyOnWrite();
-        instance.setDummy12(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy12 = 12;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy12() {
-        copyOnWrite();
-        instance.clearDummy12();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy13 = 13;</code>
-       * @return Whether the dummy13 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy13() {
-        return instance.hasDummy13();
-      }
-      /**
-       * <code>optional int32 dummy13 = 13;</code>
-       * @return The dummy13.
-       */
-      @java.lang.Override
-      public int getDummy13() {
-        return instance.getDummy13();
-      }
-      /**
-       * <code>optional int32 dummy13 = 13;</code>
-       * @param value The dummy13 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy13(int value) {
-        copyOnWrite();
-        instance.setDummy13(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy13 = 13;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy13() {
-        copyOnWrite();
-        instance.clearDummy13();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy14 = 14;</code>
-       * @return Whether the dummy14 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy14() {
-        return instance.hasDummy14();
-      }
-      /**
-       * <code>optional int32 dummy14 = 14;</code>
-       * @return The dummy14.
-       */
-      @java.lang.Override
-      public int getDummy14() {
-        return instance.getDummy14();
-      }
-      /**
-       * <code>optional int32 dummy14 = 14;</code>
-       * @param value The dummy14 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy14(int value) {
-        copyOnWrite();
-        instance.setDummy14(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy14 = 14;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy14() {
-        copyOnWrite();
-        instance.clearDummy14();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy15 = 15;</code>
-       * @return Whether the dummy15 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy15() {
-        return instance.hasDummy15();
-      }
-      /**
-       * <code>optional int32 dummy15 = 15;</code>
-       * @return The dummy15.
-       */
-      @java.lang.Override
-      public int getDummy15() {
-        return instance.getDummy15();
-      }
-      /**
-       * <code>optional int32 dummy15 = 15;</code>
-       * @param value The dummy15 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy15(int value) {
-        copyOnWrite();
-        instance.setDummy15(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy15 = 15;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy15() {
-        copyOnWrite();
-        instance.clearDummy15();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy16 = 16;</code>
-       * @return Whether the dummy16 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy16() {
-        return instance.hasDummy16();
-      }
-      /**
-       * <code>optional int32 dummy16 = 16;</code>
-       * @return The dummy16.
-       */
-      @java.lang.Override
-      public int getDummy16() {
-        return instance.getDummy16();
-      }
-      /**
-       * <code>optional int32 dummy16 = 16;</code>
-       * @param value The dummy16 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy16(int value) {
-        copyOnWrite();
-        instance.setDummy16(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy16 = 16;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy16() {
-        copyOnWrite();
-        instance.clearDummy16();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy17 = 17;</code>
-       * @return Whether the dummy17 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy17() {
-        return instance.hasDummy17();
-      }
-      /**
-       * <code>optional int32 dummy17 = 17;</code>
-       * @return The dummy17.
-       */
-      @java.lang.Override
-      public int getDummy17() {
-        return instance.getDummy17();
-      }
-      /**
-       * <code>optional int32 dummy17 = 17;</code>
-       * @param value The dummy17 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy17(int value) {
-        copyOnWrite();
-        instance.setDummy17(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy17 = 17;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy17() {
-        copyOnWrite();
-        instance.clearDummy17();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy18 = 18;</code>
-       * @return Whether the dummy18 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy18() {
-        return instance.hasDummy18();
-      }
-      /**
-       * <code>optional int32 dummy18 = 18;</code>
-       * @return The dummy18.
-       */
-      @java.lang.Override
-      public int getDummy18() {
-        return instance.getDummy18();
-      }
-      /**
-       * <code>optional int32 dummy18 = 18;</code>
-       * @param value The dummy18 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy18(int value) {
-        copyOnWrite();
-        instance.setDummy18(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy18 = 18;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy18() {
-        copyOnWrite();
-        instance.clearDummy18();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy19 = 19;</code>
-       * @return Whether the dummy19 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy19() {
-        return instance.hasDummy19();
-      }
-      /**
-       * <code>optional int32 dummy19 = 19;</code>
-       * @return The dummy19.
-       */
-      @java.lang.Override
-      public int getDummy19() {
-        return instance.getDummy19();
-      }
-      /**
-       * <code>optional int32 dummy19 = 19;</code>
-       * @param value The dummy19 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy19(int value) {
-        copyOnWrite();
-        instance.setDummy19(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy19 = 19;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy19() {
-        copyOnWrite();
-        instance.clearDummy19();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy20 = 20;</code>
-       * @return Whether the dummy20 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy20() {
-        return instance.hasDummy20();
-      }
-      /**
-       * <code>optional int32 dummy20 = 20;</code>
-       * @return The dummy20.
-       */
-      @java.lang.Override
-      public int getDummy20() {
-        return instance.getDummy20();
-      }
-      /**
-       * <code>optional int32 dummy20 = 20;</code>
-       * @param value The dummy20 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy20(int value) {
-        copyOnWrite();
-        instance.setDummy20(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy20 = 20;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy20() {
-        copyOnWrite();
-        instance.clearDummy20();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy21 = 21;</code>
-       * @return Whether the dummy21 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy21() {
-        return instance.hasDummy21();
-      }
-      /**
-       * <code>optional int32 dummy21 = 21;</code>
-       * @return The dummy21.
-       */
-      @java.lang.Override
-      public int getDummy21() {
-        return instance.getDummy21();
-      }
-      /**
-       * <code>optional int32 dummy21 = 21;</code>
-       * @param value The dummy21 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy21(int value) {
-        copyOnWrite();
-        instance.setDummy21(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy21 = 21;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy21() {
-        copyOnWrite();
-        instance.clearDummy21();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy22 = 22;</code>
-       * @return Whether the dummy22 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy22() {
-        return instance.hasDummy22();
-      }
-      /**
-       * <code>optional int32 dummy22 = 22;</code>
-       * @return The dummy22.
-       */
-      @java.lang.Override
-      public int getDummy22() {
-        return instance.getDummy22();
-      }
-      /**
-       * <code>optional int32 dummy22 = 22;</code>
-       * @param value The dummy22 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy22(int value) {
-        copyOnWrite();
-        instance.setDummy22(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy22 = 22;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy22() {
-        copyOnWrite();
-        instance.clearDummy22();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy23 = 23;</code>
-       * @return Whether the dummy23 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy23() {
-        return instance.hasDummy23();
-      }
-      /**
-       * <code>optional int32 dummy23 = 23;</code>
-       * @return The dummy23.
-       */
-      @java.lang.Override
-      public int getDummy23() {
-        return instance.getDummy23();
-      }
-      /**
-       * <code>optional int32 dummy23 = 23;</code>
-       * @param value The dummy23 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy23(int value) {
-        copyOnWrite();
-        instance.setDummy23(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy23 = 23;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy23() {
-        copyOnWrite();
-        instance.clearDummy23();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy24 = 24;</code>
-       * @return Whether the dummy24 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy24() {
-        return instance.hasDummy24();
-      }
-      /**
-       * <code>optional int32 dummy24 = 24;</code>
-       * @return The dummy24.
-       */
-      @java.lang.Override
-      public int getDummy24() {
-        return instance.getDummy24();
-      }
-      /**
-       * <code>optional int32 dummy24 = 24;</code>
-       * @param value The dummy24 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy24(int value) {
-        copyOnWrite();
-        instance.setDummy24(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy24 = 24;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy24() {
-        copyOnWrite();
-        instance.clearDummy24();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy25 = 25;</code>
-       * @return Whether the dummy25 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy25() {
-        return instance.hasDummy25();
-      }
-      /**
-       * <code>optional int32 dummy25 = 25;</code>
-       * @return The dummy25.
-       */
-      @java.lang.Override
-      public int getDummy25() {
-        return instance.getDummy25();
-      }
-      /**
-       * <code>optional int32 dummy25 = 25;</code>
-       * @param value The dummy25 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy25(int value) {
-        copyOnWrite();
-        instance.setDummy25(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy25 = 25;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy25() {
-        copyOnWrite();
-        instance.clearDummy25();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy26 = 26;</code>
-       * @return Whether the dummy26 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy26() {
-        return instance.hasDummy26();
-      }
-      /**
-       * <code>optional int32 dummy26 = 26;</code>
-       * @return The dummy26.
-       */
-      @java.lang.Override
-      public int getDummy26() {
-        return instance.getDummy26();
-      }
-      /**
-       * <code>optional int32 dummy26 = 26;</code>
-       * @param value The dummy26 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy26(int value) {
-        copyOnWrite();
-        instance.setDummy26(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy26 = 26;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy26() {
-        copyOnWrite();
-        instance.clearDummy26();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy27 = 27;</code>
-       * @return Whether the dummy27 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy27() {
-        return instance.hasDummy27();
-      }
-      /**
-       * <code>optional int32 dummy27 = 27;</code>
-       * @return The dummy27.
-       */
-      @java.lang.Override
-      public int getDummy27() {
-        return instance.getDummy27();
-      }
-      /**
-       * <code>optional int32 dummy27 = 27;</code>
-       * @param value The dummy27 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy27(int value) {
-        copyOnWrite();
-        instance.setDummy27(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy27 = 27;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy27() {
-        copyOnWrite();
-        instance.clearDummy27();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy28 = 28;</code>
-       * @return Whether the dummy28 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy28() {
-        return instance.hasDummy28();
-      }
-      /**
-       * <code>optional int32 dummy28 = 28;</code>
-       * @return The dummy28.
-       */
-      @java.lang.Override
-      public int getDummy28() {
-        return instance.getDummy28();
-      }
-      /**
-       * <code>optional int32 dummy28 = 28;</code>
-       * @param value The dummy28 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy28(int value) {
-        copyOnWrite();
-        instance.setDummy28(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy28 = 28;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy28() {
-        copyOnWrite();
-        instance.clearDummy28();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy29 = 29;</code>
-       * @return Whether the dummy29 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy29() {
-        return instance.hasDummy29();
-      }
-      /**
-       * <code>optional int32 dummy29 = 29;</code>
-       * @return The dummy29.
-       */
-      @java.lang.Override
-      public int getDummy29() {
-        return instance.getDummy29();
-      }
-      /**
-       * <code>optional int32 dummy29 = 29;</code>
-       * @param value The dummy29 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy29(int value) {
-        copyOnWrite();
-        instance.setDummy29(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy29 = 29;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy29() {
-        copyOnWrite();
-        instance.clearDummy29();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy30 = 30;</code>
-       * @return Whether the dummy30 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy30() {
-        return instance.hasDummy30();
-      }
-      /**
-       * <code>optional int32 dummy30 = 30;</code>
-       * @return The dummy30.
-       */
-      @java.lang.Override
-      public int getDummy30() {
-        return instance.getDummy30();
-      }
-      /**
-       * <code>optional int32 dummy30 = 30;</code>
-       * @param value The dummy30 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy30(int value) {
-        copyOnWrite();
-        instance.setDummy30(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy30 = 30;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy30() {
-        copyOnWrite();
-        instance.clearDummy30();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy31 = 31;</code>
-       * @return Whether the dummy31 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy31() {
-        return instance.hasDummy31();
-      }
-      /**
-       * <code>optional int32 dummy31 = 31;</code>
-       * @return The dummy31.
-       */
-      @java.lang.Override
-      public int getDummy31() {
-        return instance.getDummy31();
-      }
-      /**
-       * <code>optional int32 dummy31 = 31;</code>
-       * @param value The dummy31 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy31(int value) {
-        copyOnWrite();
-        instance.setDummy31(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy31 = 31;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy31() {
-        copyOnWrite();
-        instance.clearDummy31();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy32 = 32;</code>
-       * @return Whether the dummy32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy32() {
-        return instance.hasDummy32();
-      }
-      /**
-       * <code>optional int32 dummy32 = 32;</code>
-       * @return The dummy32.
-       */
-      @java.lang.Override
-      public int getDummy32() {
-        return instance.getDummy32();
-      }
-      /**
-       * <code>optional int32 dummy32 = 32;</code>
-       * @param value The dummy32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy32(int value) {
-        copyOnWrite();
-        instance.setDummy32(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy32 = 32;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy32() {
-        copyOnWrite();
-        instance.clearDummy32();
-        return this;
-      }
-
-      /**
-       * <code>required int32 c = 33;</code>
-       * @return Whether the c field is set.
-       */
-      @java.lang.Override
-      public boolean hasC() {
-        return instance.hasC();
-      }
-      /**
-       * <code>required int32 c = 33;</code>
-       * @return The c.
-       */
-      @java.lang.Override
-      public int getC() {
-        return instance.getC();
-      }
-      /**
-       * <code>required int32 c = 33;</code>
-       * @param value The c to set.
-       * @return This builder for chaining.
-       */
-      public Builder setC(int value) {
-        copyOnWrite();
-        instance.setC(value);
-        return this;
-      }
-      /**
-       * <code>required int32 c = 33;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearC() {
-        copyOnWrite();
-        instance.clearC();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestRequired)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestRequired();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "bitField1_",
-              "a_",
-              "dummy2_",
-              "b_",
-              "dummy4_",
-              "dummy5_",
-              "dummy6_",
-              "dummy7_",
-              "dummy8_",
-              "dummy9_",
-              "dummy10_",
-              "dummy11_",
-              "dummy12_",
-              "dummy13_",
-              "dummy14_",
-              "dummy15_",
-              "dummy16_",
-              "dummy17_",
-              "dummy18_",
-              "dummy19_",
-              "dummy20_",
-              "dummy21_",
-              "dummy22_",
-              "dummy23_",
-              "dummy24_",
-              "dummy25_",
-              "dummy26_",
-              "dummy27_",
-              "dummy28_",
-              "dummy29_",
-              "dummy30_",
-              "dummy31_",
-              "dummy32_",
-              "c_",
-            };
-            java.lang.String info =
-                "\u0001!\u0000\u0002\u0001!!\u0000\u0000\u0003\u0001\u1504\u0000\u0002\u1004\u0001" +
-                "\u0003\u1504\u0002\u0004\u1004\u0003\u0005\u1004\u0004\u0006\u1004\u0005\u0007\u1004" +
-                "\u0006\b\u1004\u0007\t\u1004\b\n\u1004\t\u000b\u1004\n\f\u1004\u000b\r\u1004\f\u000e" +
-                "\u1004\r\u000f\u1004\u000e\u0010\u1004\u000f\u0011\u1004\u0010\u0012\u1004\u0011" +
-                "\u0013\u1004\u0012\u0014\u1004\u0013\u0015\u1004\u0014\u0016\u1004\u0015\u0017\u1004" +
-                "\u0016\u0018\u1004\u0017\u0019\u1004\u0018\u001a\u1004\u0019\u001b\u1004\u001a\u001c" +
-                "\u1004\u001b\u001d\u1004\u001c\u001e\u1004\u001d\u001f\u1004\u001e \u1004\u001f!" +
-                "\u1504 ";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestRequired> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestRequired.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestRequired>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestRequired)
-    private static final protobuf_unittest.UnittestProto.TestRequired DEFAULT_INSTANCE;
-    static {
-      TestRequired defaultInstance = new TestRequired();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestRequired.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestRequired getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestRequired> PARSER;
-
-    public static com.google.protobuf.Parser<TestRequired> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-    public static final int SINGLE_FIELD_NUMBER = 1000;
-    /**
-     * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-     */
-    public static final
-      com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-        protobuf_unittest.UnittestProto.TestAllExtensions,
-        protobuf_unittest.UnittestProto.TestRequired> single = com.google.protobuf.GeneratedMessageLite
-            .newSingularGeneratedExtension(
-          protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-          protobuf_unittest.UnittestProto.TestRequired.getDefaultInstance(),
-          protobuf_unittest.UnittestProto.TestRequired.getDefaultInstance(),
-          null,
-          1000,
-          com.google.protobuf.WireFormat.FieldType.MESSAGE,
-          protobuf_unittest.UnittestProto.TestRequired.class);
-    public static final int MULTI_FIELD_NUMBER = 1001;
-    /**
-     * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-     */
-    public static final
-      com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-        protobuf_unittest.UnittestProto.TestAllExtensions,
-        java.util.List<protobuf_unittest.UnittestProto.TestRequired>> multi = com.google.protobuf.GeneratedMessageLite
-            .newRepeatedGeneratedExtension(
-          protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-          protobuf_unittest.UnittestProto.TestRequired.getDefaultInstance(),
-          null,
-          1001,
-          com.google.protobuf.WireFormat.FieldType.MESSAGE,
-          false,
-          protobuf_unittest.UnittestProto.TestRequired.class);
-  }
-
-  public interface TestRequiredForeignOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestRequiredForeign)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-     * @return Whether the optionalMessage field is set.
-     */
-    boolean hasOptionalMessage();
-    /**
-     * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-     * @return The optionalMessage.
-     */
-    protobuf_unittest.UnittestProto.TestRequired getOptionalMessage();
-
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    java.util.List<protobuf_unittest.UnittestProto.TestRequired> 
-        getRepeatedMessageList();
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    protobuf_unittest.UnittestProto.TestRequired getRepeatedMessage(int index);
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    int getRepeatedMessageCount();
-
-    /**
-     * <code>optional int32 dummy = 3;</code>
-     * @return Whether the dummy field is set.
-     */
-    boolean hasDummy();
-    /**
-     * <code>optional int32 dummy = 3;</code>
-     * @return The dummy.
-     */
-    int getDummy();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestRequiredForeign}
-   */
-  public  static final class TestRequiredForeign extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestRequiredForeign, TestRequiredForeign.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestRequiredForeign)
-      TestRequiredForeignOrBuilder {
-    private TestRequiredForeign() {
-      repeatedMessage_ = emptyProtobufList();
-    }
-    private int bitField0_;
-    public static final int OPTIONAL_MESSAGE_FIELD_NUMBER = 1;
-    private protobuf_unittest.UnittestProto.TestRequired optionalMessage_;
-    /**
-     * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalMessage() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestRequired getOptionalMessage() {
-      return optionalMessage_ == null ? protobuf_unittest.UnittestProto.TestRequired.getDefaultInstance() : optionalMessage_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-     */
-    private void setOptionalMessage(protobuf_unittest.UnittestProto.TestRequired value) {
-      value.getClass();
-  optionalMessage_ = value;
-      bitField0_ |= 0x00000001;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalMessage(protobuf_unittest.UnittestProto.TestRequired value) {
-      value.getClass();
-  if (optionalMessage_ != null &&
-          optionalMessage_ != protobuf_unittest.UnittestProto.TestRequired.getDefaultInstance()) {
-        optionalMessage_ =
-          protobuf_unittest.UnittestProto.TestRequired.newBuilder(optionalMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalMessage_ = value;
-      }
-      bitField0_ |= 0x00000001;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-     */
-    private void clearOptionalMessage() {  optionalMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x00000001);
-    }
-
-    public static final int REPEATED_MESSAGE_FIELD_NUMBER = 2;
-    private com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestRequired> repeatedMessage_;
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    @java.lang.Override
-    public java.util.List<protobuf_unittest.UnittestProto.TestRequired> getRepeatedMessageList() {
-      return repeatedMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    public java.util.List<? extends protobuf_unittest.UnittestProto.TestRequiredOrBuilder> 
-        getRepeatedMessageOrBuilderList() {
-      return repeatedMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    @java.lang.Override
-    public int getRepeatedMessageCount() {
-      return repeatedMessage_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestRequired getRepeatedMessage(int index) {
-      return repeatedMessage_.get(index);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    public protobuf_unittest.UnittestProto.TestRequiredOrBuilder getRepeatedMessageOrBuilder(
-        int index) {
-      return repeatedMessage_.get(index);
-    }
-    private void ensureRepeatedMessageIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestRequired> tmp = repeatedMessage_;
-      if (!tmp.isModifiable()) {
-        repeatedMessage_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    private void setRepeatedMessage(
-        int index, protobuf_unittest.UnittestProto.TestRequired value) {
-      value.getClass();
-  ensureRepeatedMessageIsMutable();
-      repeatedMessage_.set(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    private void addRepeatedMessage(protobuf_unittest.UnittestProto.TestRequired value) {
-      value.getClass();
-  ensureRepeatedMessageIsMutable();
-      repeatedMessage_.add(value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    private void addRepeatedMessage(
-        int index, protobuf_unittest.UnittestProto.TestRequired value) {
-      value.getClass();
-  ensureRepeatedMessageIsMutable();
-      repeatedMessage_.add(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    private void addAllRepeatedMessage(
-        java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestRequired> values) {
-      ensureRepeatedMessageIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedMessage_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    private void clearRepeatedMessage() {
-      repeatedMessage_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    private void removeRepeatedMessage(int index) {
-      ensureRepeatedMessageIsMutable();
-      repeatedMessage_.remove(index);
-    }
-
-    public static final int DUMMY_FIELD_NUMBER = 3;
-    private int dummy_;
-    /**
-     * <code>optional int32 dummy = 3;</code>
-     * @return Whether the dummy field is set.
-     */
-    @java.lang.Override
-    public boolean hasDummy() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional int32 dummy = 3;</code>
-     * @return The dummy.
-     */
-    @java.lang.Override
-    public int getDummy() {
-      return dummy_;
-    }
-    /**
-     * <code>optional int32 dummy = 3;</code>
-     * @param value The dummy to set.
-     */
-    private void setDummy(int value) {
-      bitField0_ |= 0x00000002;
-      dummy_ = value;
-    }
-    /**
-     * <code>optional int32 dummy = 3;</code>
-     */
-    private void clearDummy() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      dummy_ = 0;
-    }
-
-    public static protobuf_unittest.UnittestProto.TestRequiredForeign parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredForeign parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredForeign parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredForeign parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredForeign parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredForeign parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredForeign parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredForeign parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredForeign parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredForeign parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredForeign parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredForeign parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestRequiredForeign prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestRequiredForeign}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestRequiredForeign, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestRequiredForeign)
-        protobuf_unittest.UnittestProto.TestRequiredForeignOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestRequiredForeign.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalMessage() {
-        return instance.hasOptionalMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestRequired getOptionalMessage() {
-        return instance.getOptionalMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-       */
-      public Builder setOptionalMessage(protobuf_unittest.UnittestProto.TestRequired value) {
-        copyOnWrite();
-        instance.setOptionalMessage(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-       */
-      public Builder setOptionalMessage(
-          protobuf_unittest.UnittestProto.TestRequired.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-       */
-      public Builder mergeOptionalMessage(protobuf_unittest.UnittestProto.TestRequired value) {
-        copyOnWrite();
-        instance.mergeOptionalMessage(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-       */
-      public Builder clearOptionalMessage() {  copyOnWrite();
-        instance.clearOptionalMessage();
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.TestRequired> getRepeatedMessageList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedMessageList());
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      @java.lang.Override
-      public int getRepeatedMessageCount() {
-        return instance.getRepeatedMessageCount();
-      }/**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestRequired getRepeatedMessage(int index) {
-        return instance.getRepeatedMessage(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      public Builder setRepeatedMessage(
-          int index, protobuf_unittest.UnittestProto.TestRequired value) {
-        copyOnWrite();
-        instance.setRepeatedMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      public Builder setRepeatedMessage(
-          int index, protobuf_unittest.UnittestProto.TestRequired.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      public Builder addRepeatedMessage(protobuf_unittest.UnittestProto.TestRequired value) {
-        copyOnWrite();
-        instance.addRepeatedMessage(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      public Builder addRepeatedMessage(
-          int index, protobuf_unittest.UnittestProto.TestRequired value) {
-        copyOnWrite();
-        instance.addRepeatedMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      public Builder addRepeatedMessage(
-          protobuf_unittest.UnittestProto.TestRequired.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      public Builder addRepeatedMessage(
-          int index, protobuf_unittest.UnittestProto.TestRequired.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      public Builder addAllRepeatedMessage(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestRequired> values) {
-        copyOnWrite();
-        instance.addAllRepeatedMessage(values);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      public Builder clearRepeatedMessage() {
-        copyOnWrite();
-        instance.clearRepeatedMessage();
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      public Builder removeRepeatedMessage(int index) {
-        copyOnWrite();
-        instance.removeRepeatedMessage(index);
-        return this;
-      }
-
-      /**
-       * <code>optional int32 dummy = 3;</code>
-       * @return Whether the dummy field is set.
-       */
-      @java.lang.Override
-      public boolean hasDummy() {
-        return instance.hasDummy();
-      }
-      /**
-       * <code>optional int32 dummy = 3;</code>
-       * @return The dummy.
-       */
-      @java.lang.Override
-      public int getDummy() {
-        return instance.getDummy();
-      }
-      /**
-       * <code>optional int32 dummy = 3;</code>
-       * @param value The dummy to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDummy(int value) {
-        copyOnWrite();
-        instance.setDummy(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 dummy = 3;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDummy() {
-        copyOnWrite();
-        instance.clearDummy();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestRequiredForeign)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestRequiredForeign();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "optionalMessage_",
-              "repeatedMessage_",
-              protobuf_unittest.UnittestProto.TestRequired.class,
-              "dummy_",
-            };
-            java.lang.String info =
-                "\u0001\u0003\u0000\u0001\u0001\u0003\u0003\u0000\u0001\u0002\u0001\u1409\u0000\u0002" +
-                "\u041b\u0003\u1004\u0001";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestRequiredForeign> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestRequiredForeign.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestRequiredForeign>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestRequiredForeign)
-    private static final protobuf_unittest.UnittestProto.TestRequiredForeign DEFAULT_INSTANCE;
-    static {
-      TestRequiredForeign defaultInstance = new TestRequiredForeign();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestRequiredForeign.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestRequiredForeign getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestRequiredForeign> PARSER;
-
-    public static com.google.protobuf.Parser<TestRequiredForeign> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestRequiredMessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestRequiredMessage)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-     * @return Whether the optionalMessage field is set.
-     */
-    boolean hasOptionalMessage();
-    /**
-     * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-     * @return The optionalMessage.
-     */
-    protobuf_unittest.UnittestProto.TestRequired getOptionalMessage();
-
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    java.util.List<protobuf_unittest.UnittestProto.TestRequired> 
-        getRepeatedMessageList();
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    protobuf_unittest.UnittestProto.TestRequired getRepeatedMessage(int index);
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    int getRepeatedMessageCount();
-
-    /**
-     * <code>required .protobuf_unittest.TestRequired required_message = 3;</code>
-     * @return Whether the requiredMessage field is set.
-     */
-    boolean hasRequiredMessage();
-    /**
-     * <code>required .protobuf_unittest.TestRequired required_message = 3;</code>
-     * @return The requiredMessage.
-     */
-    protobuf_unittest.UnittestProto.TestRequired getRequiredMessage();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestRequiredMessage}
-   */
-  public  static final class TestRequiredMessage extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestRequiredMessage, TestRequiredMessage.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestRequiredMessage)
-      TestRequiredMessageOrBuilder {
-    private TestRequiredMessage() {
-      repeatedMessage_ = emptyProtobufList();
-    }
-    private int bitField0_;
-    public static final int OPTIONAL_MESSAGE_FIELD_NUMBER = 1;
-    private protobuf_unittest.UnittestProto.TestRequired optionalMessage_;
-    /**
-     * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalMessage() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestRequired getOptionalMessage() {
-      return optionalMessage_ == null ? protobuf_unittest.UnittestProto.TestRequired.getDefaultInstance() : optionalMessage_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-     */
-    private void setOptionalMessage(protobuf_unittest.UnittestProto.TestRequired value) {
-      value.getClass();
-  optionalMessage_ = value;
-      bitField0_ |= 0x00000001;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalMessage(protobuf_unittest.UnittestProto.TestRequired value) {
-      value.getClass();
-  if (optionalMessage_ != null &&
-          optionalMessage_ != protobuf_unittest.UnittestProto.TestRequired.getDefaultInstance()) {
-        optionalMessage_ =
-          protobuf_unittest.UnittestProto.TestRequired.newBuilder(optionalMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalMessage_ = value;
-      }
-      bitField0_ |= 0x00000001;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-     */
-    private void clearOptionalMessage() {  optionalMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x00000001);
-    }
-
-    public static final int REPEATED_MESSAGE_FIELD_NUMBER = 2;
-    private com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestRequired> repeatedMessage_;
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    @java.lang.Override
-    public java.util.List<protobuf_unittest.UnittestProto.TestRequired> getRepeatedMessageList() {
-      return repeatedMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    public java.util.List<? extends protobuf_unittest.UnittestProto.TestRequiredOrBuilder> 
-        getRepeatedMessageOrBuilderList() {
-      return repeatedMessage_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    @java.lang.Override
-    public int getRepeatedMessageCount() {
-      return repeatedMessage_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestRequired getRepeatedMessage(int index) {
-      return repeatedMessage_.get(index);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    public protobuf_unittest.UnittestProto.TestRequiredOrBuilder getRepeatedMessageOrBuilder(
-        int index) {
-      return repeatedMessage_.get(index);
-    }
-    private void ensureRepeatedMessageIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestRequired> tmp = repeatedMessage_;
-      if (!tmp.isModifiable()) {
-        repeatedMessage_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    private void setRepeatedMessage(
-        int index, protobuf_unittest.UnittestProto.TestRequired value) {
-      value.getClass();
-  ensureRepeatedMessageIsMutable();
-      repeatedMessage_.set(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    private void addRepeatedMessage(protobuf_unittest.UnittestProto.TestRequired value) {
-      value.getClass();
-  ensureRepeatedMessageIsMutable();
-      repeatedMessage_.add(value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    private void addRepeatedMessage(
-        int index, protobuf_unittest.UnittestProto.TestRequired value) {
-      value.getClass();
-  ensureRepeatedMessageIsMutable();
-      repeatedMessage_.add(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    private void addAllRepeatedMessage(
-        java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestRequired> values) {
-      ensureRepeatedMessageIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedMessage_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    private void clearRepeatedMessage() {
-      repeatedMessage_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-     */
-    private void removeRepeatedMessage(int index) {
-      ensureRepeatedMessageIsMutable();
-      repeatedMessage_.remove(index);
-    }
-
-    public static final int REQUIRED_MESSAGE_FIELD_NUMBER = 3;
-    private protobuf_unittest.UnittestProto.TestRequired requiredMessage_;
-    /**
-     * <code>required .protobuf_unittest.TestRequired required_message = 3;</code>
-     */
-    @java.lang.Override
-    public boolean hasRequiredMessage() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>required .protobuf_unittest.TestRequired required_message = 3;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestRequired getRequiredMessage() {
-      return requiredMessage_ == null ? protobuf_unittest.UnittestProto.TestRequired.getDefaultInstance() : requiredMessage_;
-    }
-    /**
-     * <code>required .protobuf_unittest.TestRequired required_message = 3;</code>
-     */
-    private void setRequiredMessage(protobuf_unittest.UnittestProto.TestRequired value) {
-      value.getClass();
-  requiredMessage_ = value;
-      bitField0_ |= 0x00000002;
-      }
-    /**
-     * <code>required .protobuf_unittest.TestRequired required_message = 3;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeRequiredMessage(protobuf_unittest.UnittestProto.TestRequired value) {
-      value.getClass();
-  if (requiredMessage_ != null &&
-          requiredMessage_ != protobuf_unittest.UnittestProto.TestRequired.getDefaultInstance()) {
-        requiredMessage_ =
-          protobuf_unittest.UnittestProto.TestRequired.newBuilder(requiredMessage_).mergeFrom(value).buildPartial();
-      } else {
-        requiredMessage_ = value;
-      }
-      bitField0_ |= 0x00000002;
-    }
-    /**
-     * <code>required .protobuf_unittest.TestRequired required_message = 3;</code>
-     */
-    private void clearRequiredMessage() {  requiredMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x00000002);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestRequiredMessage parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredMessage parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredMessage parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredMessage parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredMessage parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredMessage parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredMessage parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredMessage parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredMessage parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredMessage parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredMessage parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredMessage parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestRequiredMessage prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestRequiredMessage}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestRequiredMessage, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestRequiredMessage)
-        protobuf_unittest.UnittestProto.TestRequiredMessageOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestRequiredMessage.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalMessage() {
-        return instance.hasOptionalMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestRequired getOptionalMessage() {
-        return instance.getOptionalMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-       */
-      public Builder setOptionalMessage(protobuf_unittest.UnittestProto.TestRequired value) {
-        copyOnWrite();
-        instance.setOptionalMessage(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-       */
-      public Builder setOptionalMessage(
-          protobuf_unittest.UnittestProto.TestRequired.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-       */
-      public Builder mergeOptionalMessage(protobuf_unittest.UnittestProto.TestRequired value) {
-        copyOnWrite();
-        instance.mergeOptionalMessage(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestRequired optional_message = 1;</code>
-       */
-      public Builder clearOptionalMessage() {  copyOnWrite();
-        instance.clearOptionalMessage();
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.TestRequired> getRepeatedMessageList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedMessageList());
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      @java.lang.Override
-      public int getRepeatedMessageCount() {
-        return instance.getRepeatedMessageCount();
-      }/**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestRequired getRepeatedMessage(int index) {
-        return instance.getRepeatedMessage(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      public Builder setRepeatedMessage(
-          int index, protobuf_unittest.UnittestProto.TestRequired value) {
-        copyOnWrite();
-        instance.setRepeatedMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      public Builder setRepeatedMessage(
-          int index, protobuf_unittest.UnittestProto.TestRequired.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      public Builder addRepeatedMessage(protobuf_unittest.UnittestProto.TestRequired value) {
-        copyOnWrite();
-        instance.addRepeatedMessage(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      public Builder addRepeatedMessage(
-          int index, protobuf_unittest.UnittestProto.TestRequired value) {
-        copyOnWrite();
-        instance.addRepeatedMessage(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      public Builder addRepeatedMessage(
-          protobuf_unittest.UnittestProto.TestRequired.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      public Builder addRepeatedMessage(
-          int index, protobuf_unittest.UnittestProto.TestRequired.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedMessage(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      public Builder addAllRepeatedMessage(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestRequired> values) {
-        copyOnWrite();
-        instance.addAllRepeatedMessage(values);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      public Builder clearRepeatedMessage() {
-        copyOnWrite();
-        instance.clearRepeatedMessage();
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestRequired repeated_message = 2;</code>
-       */
-      public Builder removeRepeatedMessage(int index) {
-        copyOnWrite();
-        instance.removeRepeatedMessage(index);
-        return this;
-      }
-
-      /**
-       * <code>required .protobuf_unittest.TestRequired required_message = 3;</code>
-       */
-      @java.lang.Override
-      public boolean hasRequiredMessage() {
-        return instance.hasRequiredMessage();
-      }
-      /**
-       * <code>required .protobuf_unittest.TestRequired required_message = 3;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestRequired getRequiredMessage() {
-        return instance.getRequiredMessage();
-      }
-      /**
-       * <code>required .protobuf_unittest.TestRequired required_message = 3;</code>
-       */
-      public Builder setRequiredMessage(protobuf_unittest.UnittestProto.TestRequired value) {
-        copyOnWrite();
-        instance.setRequiredMessage(value);
-        return this;
-        }
-      /**
-       * <code>required .protobuf_unittest.TestRequired required_message = 3;</code>
-       */
-      public Builder setRequiredMessage(
-          protobuf_unittest.UnittestProto.TestRequired.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRequiredMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>required .protobuf_unittest.TestRequired required_message = 3;</code>
-       */
-      public Builder mergeRequiredMessage(protobuf_unittest.UnittestProto.TestRequired value) {
-        copyOnWrite();
-        instance.mergeRequiredMessage(value);
-        return this;
-      }
-      /**
-       * <code>required .protobuf_unittest.TestRequired required_message = 3;</code>
-       */
-      public Builder clearRequiredMessage() {  copyOnWrite();
-        instance.clearRequiredMessage();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestRequiredMessage)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestRequiredMessage();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "optionalMessage_",
-              "repeatedMessage_",
-              protobuf_unittest.UnittestProto.TestRequired.class,
-              "requiredMessage_",
-            };
-            java.lang.String info =
-                "\u0001\u0003\u0000\u0001\u0001\u0003\u0003\u0000\u0001\u0003\u0001\u1409\u0000\u0002" +
-                "\u041b\u0003\u1509\u0001";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestRequiredMessage> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestRequiredMessage.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestRequiredMessage>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestRequiredMessage)
-    private static final protobuf_unittest.UnittestProto.TestRequiredMessage DEFAULT_INSTANCE;
-    static {
-      TestRequiredMessage defaultInstance = new TestRequiredMessage();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestRequiredMessage.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestRequiredMessage getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestRequiredMessage> PARSER;
-
-    public static com.google.protobuf.Parser<TestRequiredMessage> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestForeignNestedOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestForeignNested)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage foreign_nested = 1;</code>
-     * @return Whether the foreignNested field is set.
-     */
-    boolean hasForeignNested();
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage foreign_nested = 1;</code>
-     * @return The foreignNested.
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage getForeignNested();
-  }
-  /**
-   * <pre>
-   * Test that we can use NestedMessage from outside TestAllTypes.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestForeignNested}
-   */
-  public  static final class TestForeignNested extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestForeignNested, TestForeignNested.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestForeignNested)
-      TestForeignNestedOrBuilder {
-    private TestForeignNested() {
-    }
-    private int bitField0_;
-    public static final int FOREIGN_NESTED_FIELD_NUMBER = 1;
-    private protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage foreignNested_;
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage foreign_nested = 1;</code>
-     */
-    @java.lang.Override
-    public boolean hasForeignNested() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage foreign_nested = 1;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage getForeignNested() {
-      return foreignNested_ == null ? protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.getDefaultInstance() : foreignNested_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage foreign_nested = 1;</code>
-     */
-    private void setForeignNested(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  foreignNested_ = value;
-      bitField0_ |= 0x00000001;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage foreign_nested = 1;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeForeignNested(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-      value.getClass();
-  if (foreignNested_ != null &&
-          foreignNested_ != protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.getDefaultInstance()) {
-        foreignNested_ =
-          protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.newBuilder(foreignNested_).mergeFrom(value).buildPartial();
-      } else {
-        foreignNested_ = value;
-      }
-      bitField0_ |= 0x00000001;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage foreign_nested = 1;</code>
-     */
-    private void clearForeignNested() {  foreignNested_ = null;
-      bitField0_ = (bitField0_ & ~0x00000001);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestForeignNested parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestForeignNested parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestForeignNested parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestForeignNested parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestForeignNested parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestForeignNested parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestForeignNested parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestForeignNested parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestForeignNested parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestForeignNested parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestForeignNested parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestForeignNested parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestForeignNested prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Test that we can use NestedMessage from outside TestAllTypes.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestForeignNested}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestForeignNested, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestForeignNested)
-        protobuf_unittest.UnittestProto.TestForeignNestedOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestForeignNested.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage foreign_nested = 1;</code>
-       */
-      @java.lang.Override
-      public boolean hasForeignNested() {
-        return instance.hasForeignNested();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage foreign_nested = 1;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage getForeignNested() {
-        return instance.getForeignNested();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage foreign_nested = 1;</code>
-       */
-      public Builder setForeignNested(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.setForeignNested(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage foreign_nested = 1;</code>
-       */
-      public Builder setForeignNested(
-          protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setForeignNested(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage foreign_nested = 1;</code>
-       */
-      public Builder mergeForeignNested(protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage value) {
-        copyOnWrite();
-        instance.mergeForeignNested(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes.NestedMessage foreign_nested = 1;</code>
-       */
-      public Builder clearForeignNested() {  copyOnWrite();
-        instance.clearForeignNested();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestForeignNested)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestForeignNested();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "foreignNested_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1009\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestForeignNested> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestForeignNested.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestForeignNested>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestForeignNested)
-    private static final protobuf_unittest.UnittestProto.TestForeignNested DEFAULT_INSTANCE;
-    static {
-      TestForeignNested defaultInstance = new TestForeignNested();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestForeignNested.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestForeignNested getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestForeignNested> PARSER;
-
-    public static com.google.protobuf.Parser<TestForeignNested> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestEmptyMessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestEmptyMessage)
-      com.google.protobuf.MessageLiteOrBuilder {
-  }
-  /**
-   * <pre>
-   * TestEmptyMessage is used to test unknown field support.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestEmptyMessage}
-   */
-  public  static final class TestEmptyMessage extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestEmptyMessage, TestEmptyMessage.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestEmptyMessage)
-      TestEmptyMessageOrBuilder {
-    private TestEmptyMessage() {
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessage parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessage parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessage parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessage parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessage parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessage parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessage parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessage parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessage parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessage parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessage parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessage parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestEmptyMessage prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * TestEmptyMessage is used to test unknown field support.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestEmptyMessage}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestEmptyMessage, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestEmptyMessage)
-        protobuf_unittest.UnittestProto.TestEmptyMessageOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestEmptyMessage.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestEmptyMessage)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestEmptyMessage();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestEmptyMessage> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestEmptyMessage.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestEmptyMessage>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestEmptyMessage)
-    private static final protobuf_unittest.UnittestProto.TestEmptyMessage DEFAULT_INSTANCE;
-    static {
-      TestEmptyMessage defaultInstance = new TestEmptyMessage();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestEmptyMessage.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestEmptyMessage getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestEmptyMessage> PARSER;
-
-    public static com.google.protobuf.Parser<TestEmptyMessage> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestEmptyMessageWithExtensionsOrBuilder extends 
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestEmptyMessageWithExtensions)
-       com.google.protobuf.GeneratedMessageLite.
-            ExtendableMessageOrBuilder<
-                TestEmptyMessageWithExtensions, TestEmptyMessageWithExtensions.Builder> {
-  }
-  /**
-   * <pre>
-   * Like above, but declare all field numbers as potential extensions.  No
-   * actual extensions should ever be defined for this type.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestEmptyMessageWithExtensions}
-   */
-  public  static final class TestEmptyMessageWithExtensions extends
-      com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
-        TestEmptyMessageWithExtensions, TestEmptyMessageWithExtensions.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestEmptyMessageWithExtensions)
-      TestEmptyMessageWithExtensionsOrBuilder {
-    private TestEmptyMessageWithExtensions() {
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Like above, but declare all field numbers as potential extensions.  No
-     * actual extensions should ever be defined for this type.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestEmptyMessageWithExtensions}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
-          protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestEmptyMessageWithExtensions)
-        protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensionsOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestEmptyMessageWithExtensions)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestEmptyMessageWithExtensions)
-    private static final protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions DEFAULT_INSTANCE;
-    static {
-      TestEmptyMessageWithExtensions defaultInstance = new TestEmptyMessageWithExtensions();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestEmptyMessageWithExtensions.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestEmptyMessageWithExtensions> PARSER;
-
-    public static com.google.protobuf.Parser<TestEmptyMessageWithExtensions> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestPickleNestedMessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestPickleNestedMessage)
-      com.google.protobuf.MessageLiteOrBuilder {
-  }
-  /**
-   * <pre>
-   * Needed for a Python test.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestPickleNestedMessage}
-   */
-  public  static final class TestPickleNestedMessage extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestPickleNestedMessage, TestPickleNestedMessage.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestPickleNestedMessage)
-      TestPickleNestedMessageOrBuilder {
-    private TestPickleNestedMessage() {
-    }
-    public interface NestedMessageOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestPickleNestedMessage.NestedMessage)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int32 bb = 1;</code>
-       * @return Whether the bb field is set.
-       */
-      boolean hasBb();
-      /**
-       * <code>optional int32 bb = 1;</code>
-       * @return The bb.
-       */
-      int getBb();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestPickleNestedMessage.NestedMessage}
-     */
-    public  static final class NestedMessage extends
-        com.google.protobuf.GeneratedMessageLite<
-            NestedMessage, NestedMessage.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestPickleNestedMessage.NestedMessage)
-        NestedMessageOrBuilder {
-      private NestedMessage() {
-      }
-      public interface NestedNestedMessageOrBuilder extends
-          // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestPickleNestedMessage.NestedMessage.NestedNestedMessage)
-          com.google.protobuf.MessageLiteOrBuilder {
-
-        /**
-         * <code>optional int32 cc = 1;</code>
-         * @return Whether the cc field is set.
-         */
-        boolean hasCc();
-        /**
-         * <code>optional int32 cc = 1;</code>
-         * @return The cc.
-         */
-        int getCc();
-      }
-      /**
-       * Protobuf type {@code protobuf_unittest.TestPickleNestedMessage.NestedMessage.NestedNestedMessage}
-       */
-      public  static final class NestedNestedMessage extends
-          com.google.protobuf.GeneratedMessageLite<
-              NestedNestedMessage, NestedNestedMessage.Builder> implements
-          // @@protoc_insertion_point(message_implements:protobuf_unittest.TestPickleNestedMessage.NestedMessage.NestedNestedMessage)
-          NestedNestedMessageOrBuilder {
-        private NestedNestedMessage() {
-        }
-        private int bitField0_;
-        public static final int CC_FIELD_NUMBER = 1;
-        private int cc_;
-        /**
-         * <code>optional int32 cc = 1;</code>
-         * @return Whether the cc field is set.
-         */
-        @java.lang.Override
-        public boolean hasCc() {
-          return ((bitField0_ & 0x00000001) != 0);
-        }
-        /**
-         * <code>optional int32 cc = 1;</code>
-         * @return The cc.
-         */
-        @java.lang.Override
-        public int getCc() {
-          return cc_;
-        }
-        /**
-         * <code>optional int32 cc = 1;</code>
-         * @param value The cc to set.
-         */
-        private void setCc(int value) {
-          bitField0_ |= 0x00000001;
-          cc_ = value;
-        }
-        /**
-         * <code>optional int32 cc = 1;</code>
-         */
-        private void clearCc() {
-          bitField0_ = (bitField0_ & ~0x00000001);
-          cc_ = 0;
-        }
-
-        public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage parseFrom(
-            java.nio.ByteBuffer data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data);
-        }
-        public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage parseFrom(
-            java.nio.ByteBuffer data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage parseFrom(
-            com.google.protobuf.ByteString data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data);
-        }
-        public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage parseFrom(
-            com.google.protobuf.ByteString data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage parseFrom(byte[] data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data);
-        }
-        public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage parseFrom(
-            byte[] data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage parseFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input);
-        }
-        public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage parseFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage parseDelimitedFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-        }
-        public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage parseDelimitedFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage parseFrom(
-            com.google.protobuf.CodedInputStream input)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input);
-        }
-        public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage parseFrom(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input, extensionRegistry);
-        }
-
-        public static Builder newBuilder() {
-          return (Builder) DEFAULT_INSTANCE.createBuilder();
-        }
-        public static Builder newBuilder(protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage prototype) {
-          return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-        }
-
-        /**
-         * Protobuf type {@code protobuf_unittest.TestPickleNestedMessage.NestedMessage.NestedNestedMessage}
-         */
-        public static final class Builder extends
-            com.google.protobuf.GeneratedMessageLite.Builder<
-              protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage, Builder> implements
-            // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestPickleNestedMessage.NestedMessage.NestedNestedMessage)
-            protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessageOrBuilder {
-          // Construct using protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage.newBuilder()
-          private Builder() {
-            super(DEFAULT_INSTANCE);
-          }
-
-
-          /**
-           * <code>optional int32 cc = 1;</code>
-           * @return Whether the cc field is set.
-           */
-          @java.lang.Override
-          public boolean hasCc() {
-            return instance.hasCc();
-          }
-          /**
-           * <code>optional int32 cc = 1;</code>
-           * @return The cc.
-           */
-          @java.lang.Override
-          public int getCc() {
-            return instance.getCc();
-          }
-          /**
-           * <code>optional int32 cc = 1;</code>
-           * @param value The cc to set.
-           * @return This builder for chaining.
-           */
-          public Builder setCc(int value) {
-            copyOnWrite();
-            instance.setCc(value);
-            return this;
-          }
-          /**
-           * <code>optional int32 cc = 1;</code>
-           * @return This builder for chaining.
-           */
-          public Builder clearCc() {
-            copyOnWrite();
-            instance.clearCc();
-            return this;
-          }
-
-          // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestPickleNestedMessage.NestedMessage.NestedNestedMessage)
-        }
-        @java.lang.Override
-        @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-        protected final java.lang.Object dynamicMethod(
-            com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-            java.lang.Object arg0, java.lang.Object arg1) {
-          switch (method) {
-            case NEW_MUTABLE_INSTANCE: {
-              return new protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage();
-            }
-            case NEW_BUILDER: {
-              return new Builder();
-            }
-            case BUILD_MESSAGE_INFO: {
-                java.lang.Object[] objects = new java.lang.Object[] {
-                  "bitField0_",
-                  "cc_",
-                };
-                java.lang.String info =
-                    "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1004\u0000";
-                return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-            }
-            // fall through
-            case GET_DEFAULT_INSTANCE: {
-              return DEFAULT_INSTANCE;
-            }
-            case GET_PARSER: {
-              com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage> parser = PARSER;
-              if (parser == null) {
-                synchronized (protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage.class) {
-                  parser = PARSER;
-                  if (parser == null) {
-                    parser =
-                        new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage>(
-                            DEFAULT_INSTANCE);
-                    PARSER = parser;
-                  }
-                }
-              }
-              return parser;
-          }
-          case GET_MEMOIZED_IS_INITIALIZED: {
-            return (byte) 1;
-          }
-          case SET_MEMOIZED_IS_INITIALIZED: {
-            return null;
-          }
-          }
-          throw new UnsupportedOperationException();
-        }
-
-
-        // @@protoc_insertion_point(class_scope:protobuf_unittest.TestPickleNestedMessage.NestedMessage.NestedNestedMessage)
-        private static final protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage DEFAULT_INSTANCE;
-        static {
-          NestedNestedMessage defaultInstance = new NestedNestedMessage();
-          // New instances are implicitly immutable so no need to make
-          // immutable.
-          DEFAULT_INSTANCE = defaultInstance;
-          com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-            NestedNestedMessage.class, defaultInstance);
-        }
-
-        public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.NestedNestedMessage getDefaultInstance() {
-          return DEFAULT_INSTANCE;
-        }
-
-        private static volatile com.google.protobuf.Parser<NestedNestedMessage> PARSER;
-
-        public static com.google.protobuf.Parser<NestedNestedMessage> parser() {
-          return DEFAULT_INSTANCE.getParserForType();
-        }
-      }
-
-      private int bitField0_;
-      public static final int BB_FIELD_NUMBER = 1;
-      private int bb_;
-      /**
-       * <code>optional int32 bb = 1;</code>
-       * @return Whether the bb field is set.
-       */
-      @java.lang.Override
-      public boolean hasBb() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int32 bb = 1;</code>
-       * @return The bb.
-       */
-      @java.lang.Override
-      public int getBb() {
-        return bb_;
-      }
-      /**
-       * <code>optional int32 bb = 1;</code>
-       * @param value The bb to set.
-       */
-      private void setBb(int value) {
-        bitField0_ |= 0x00000001;
-        bb_ = value;
-      }
-      /**
-       * <code>optional int32 bb = 1;</code>
-       */
-      private void clearBb() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        bb_ = 0;
-      }
-
-      public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestPickleNestedMessage.NestedMessage}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestPickleNestedMessage.NestedMessage)
-          protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessageOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int32 bb = 1;</code>
-         * @return Whether the bb field is set.
-         */
-        @java.lang.Override
-        public boolean hasBb() {
-          return instance.hasBb();
-        }
-        /**
-         * <code>optional int32 bb = 1;</code>
-         * @return The bb.
-         */
-        @java.lang.Override
-        public int getBb() {
-          return instance.getBb();
-        }
-        /**
-         * <code>optional int32 bb = 1;</code>
-         * @param value The bb to set.
-         * @return This builder for chaining.
-         */
-        public Builder setBb(int value) {
-          copyOnWrite();
-          instance.setBb(value);
-          return this;
-        }
-        /**
-         * <code>optional int32 bb = 1;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearBb() {
-          copyOnWrite();
-          instance.clearBb();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestPickleNestedMessage.NestedMessage)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "bb_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1004\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestPickleNestedMessage.NestedMessage)
-      private static final protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage DEFAULT_INSTANCE;
-      static {
-        NestedMessage defaultInstance = new NestedMessage();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          NestedMessage.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestPickleNestedMessage.NestedMessage getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<NestedMessage> PARSER;
-
-      public static com.google.protobuf.Parser<NestedMessage> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    public static protobuf_unittest.UnittestProto.TestPickleNestedMessage parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestPickleNestedMessage parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestPickleNestedMessage parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestPickleNestedMessage parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestPickleNestedMessage parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestPickleNestedMessage parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestPickleNestedMessage parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestPickleNestedMessage parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestPickleNestedMessage parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestPickleNestedMessage parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestPickleNestedMessage parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestPickleNestedMessage parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestPickleNestedMessage prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Needed for a Python test.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestPickleNestedMessage}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestPickleNestedMessage, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestPickleNestedMessage)
-        protobuf_unittest.UnittestProto.TestPickleNestedMessageOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestPickleNestedMessage.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestPickleNestedMessage)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestPickleNestedMessage();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestPickleNestedMessage> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestPickleNestedMessage.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestPickleNestedMessage>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestPickleNestedMessage)
-    private static final protobuf_unittest.UnittestProto.TestPickleNestedMessage DEFAULT_INSTANCE;
-    static {
-      TestPickleNestedMessage defaultInstance = new TestPickleNestedMessage();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestPickleNestedMessage.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestPickleNestedMessage getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestPickleNestedMessage> PARSER;
-
-    public static com.google.protobuf.Parser<TestPickleNestedMessage> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestMultipleExtensionRangesOrBuilder extends 
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestMultipleExtensionRanges)
-       com.google.protobuf.GeneratedMessageLite.
-            ExtendableMessageOrBuilder<
-                TestMultipleExtensionRanges, TestMultipleExtensionRanges.Builder> {
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestMultipleExtensionRanges}
-   */
-  public  static final class TestMultipleExtensionRanges extends
-      com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
-        TestMultipleExtensionRanges, TestMultipleExtensionRanges.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestMultipleExtensionRanges)
-      TestMultipleExtensionRangesOrBuilder {
-    private TestMultipleExtensionRanges() {
-    }
-    public static protobuf_unittest.UnittestProto.TestMultipleExtensionRanges parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestMultipleExtensionRanges parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestMultipleExtensionRanges parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestMultipleExtensionRanges parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestMultipleExtensionRanges parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestMultipleExtensionRanges parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestMultipleExtensionRanges parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestMultipleExtensionRanges parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestMultipleExtensionRanges parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestMultipleExtensionRanges parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestMultipleExtensionRanges parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestMultipleExtensionRanges parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestMultipleExtensionRanges prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestMultipleExtensionRanges}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
-          protobuf_unittest.UnittestProto.TestMultipleExtensionRanges, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestMultipleExtensionRanges)
-        protobuf_unittest.UnittestProto.TestMultipleExtensionRangesOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestMultipleExtensionRanges.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestMultipleExtensionRanges)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestMultipleExtensionRanges();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestMultipleExtensionRanges> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestMultipleExtensionRanges.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestMultipleExtensionRanges>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestMultipleExtensionRanges)
-    private static final protobuf_unittest.UnittestProto.TestMultipleExtensionRanges DEFAULT_INSTANCE;
-    static {
-      TestMultipleExtensionRanges defaultInstance = new TestMultipleExtensionRanges();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestMultipleExtensionRanges.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestMultipleExtensionRanges getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestMultipleExtensionRanges> PARSER;
-
-    public static com.google.protobuf.Parser<TestMultipleExtensionRanges> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestReallyLargeTagNumberOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestReallyLargeTagNumber)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <pre>
-     * The largest possible tag number is 2^28 - 1, since the wire format uses
-     * three bits to communicate wire type.
-     * </pre>
-     *
-     * <code>optional int32 a = 1;</code>
-     * @return Whether the a field is set.
-     */
-    boolean hasA();
-    /**
-     * <pre>
-     * The largest possible tag number is 2^28 - 1, since the wire format uses
-     * three bits to communicate wire type.
-     * </pre>
-     *
-     * <code>optional int32 a = 1;</code>
-     * @return The a.
-     */
-    int getA();
-
-    /**
-     * <code>optional int32 bb = 268435455;</code>
-     * @return Whether the bb field is set.
-     */
-    boolean hasBb();
-    /**
-     * <code>optional int32 bb = 268435455;</code>
-     * @return The bb.
-     */
-    int getBb();
-  }
-  /**
-   * <pre>
-   * Test that really large tag numbers don't break anything.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestReallyLargeTagNumber}
-   */
-  public  static final class TestReallyLargeTagNumber extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestReallyLargeTagNumber, TestReallyLargeTagNumber.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestReallyLargeTagNumber)
-      TestReallyLargeTagNumberOrBuilder {
-    private TestReallyLargeTagNumber() {
-    }
-    private int bitField0_;
-    public static final int A_FIELD_NUMBER = 1;
-    private int a_;
-    /**
-     * <pre>
-     * The largest possible tag number is 2^28 - 1, since the wire format uses
-     * three bits to communicate wire type.
-     * </pre>
-     *
-     * <code>optional int32 a = 1;</code>
-     * @return Whether the a field is set.
-     */
-    @java.lang.Override
-    public boolean hasA() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <pre>
-     * The largest possible tag number is 2^28 - 1, since the wire format uses
-     * three bits to communicate wire type.
-     * </pre>
-     *
-     * <code>optional int32 a = 1;</code>
-     * @return The a.
-     */
-    @java.lang.Override
-    public int getA() {
-      return a_;
-    }
-    /**
-     * <pre>
-     * The largest possible tag number is 2^28 - 1, since the wire format uses
-     * three bits to communicate wire type.
-     * </pre>
-     *
-     * <code>optional int32 a = 1;</code>
-     * @param value The a to set.
-     */
-    private void setA(int value) {
-      bitField0_ |= 0x00000001;
-      a_ = value;
-    }
-    /**
-     * <pre>
-     * The largest possible tag number is 2^28 - 1, since the wire format uses
-     * three bits to communicate wire type.
-     * </pre>
-     *
-     * <code>optional int32 a = 1;</code>
-     */
-    private void clearA() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      a_ = 0;
-    }
-
-    public static final int BB_FIELD_NUMBER = 268435455;
-    private int bb_;
-    /**
-     * <code>optional int32 bb = 268435455;</code>
-     * @return Whether the bb field is set.
-     */
-    @java.lang.Override
-    public boolean hasBb() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional int32 bb = 268435455;</code>
-     * @return The bb.
-     */
-    @java.lang.Override
-    public int getBb() {
-      return bb_;
-    }
-    /**
-     * <code>optional int32 bb = 268435455;</code>
-     * @param value The bb to set.
-     */
-    private void setBb(int value) {
-      bitField0_ |= 0x00000002;
-      bb_ = value;
-    }
-    /**
-     * <code>optional int32 bb = 268435455;</code>
-     */
-    private void clearBb() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      bb_ = 0;
-    }
-
-    public static protobuf_unittest.UnittestProto.TestReallyLargeTagNumber parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestReallyLargeTagNumber parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestReallyLargeTagNumber parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestReallyLargeTagNumber parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestReallyLargeTagNumber parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestReallyLargeTagNumber parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestReallyLargeTagNumber parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestReallyLargeTagNumber parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestReallyLargeTagNumber parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestReallyLargeTagNumber parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestReallyLargeTagNumber parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestReallyLargeTagNumber parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestReallyLargeTagNumber prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Test that really large tag numbers don't break anything.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestReallyLargeTagNumber}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestReallyLargeTagNumber, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestReallyLargeTagNumber)
-        protobuf_unittest.UnittestProto.TestReallyLargeTagNumberOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestReallyLargeTagNumber.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <pre>
-       * The largest possible tag number is 2^28 - 1, since the wire format uses
-       * three bits to communicate wire type.
-       * </pre>
-       *
-       * <code>optional int32 a = 1;</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return instance.hasA();
-      }
-      /**
-       * <pre>
-       * The largest possible tag number is 2^28 - 1, since the wire format uses
-       * three bits to communicate wire type.
-       * </pre>
-       *
-       * <code>optional int32 a = 1;</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public int getA() {
-        return instance.getA();
-      }
-      /**
-       * <pre>
-       * The largest possible tag number is 2^28 - 1, since the wire format uses
-       * three bits to communicate wire type.
-       * </pre>
-       *
-       * <code>optional int32 a = 1;</code>
-       * @param value The a to set.
-       * @return This builder for chaining.
-       */
-      public Builder setA(int value) {
-        copyOnWrite();
-        instance.setA(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * The largest possible tag number is 2^28 - 1, since the wire format uses
-       * three bits to communicate wire type.
-       * </pre>
-       *
-       * <code>optional int32 a = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearA() {
-        copyOnWrite();
-        instance.clearA();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 bb = 268435455;</code>
-       * @return Whether the bb field is set.
-       */
-      @java.lang.Override
-      public boolean hasBb() {
-        return instance.hasBb();
-      }
-      /**
-       * <code>optional int32 bb = 268435455;</code>
-       * @return The bb.
-       */
-      @java.lang.Override
-      public int getBb() {
-        return instance.getBb();
-      }
-      /**
-       * <code>optional int32 bb = 268435455;</code>
-       * @param value The bb to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBb(int value) {
-        copyOnWrite();
-        instance.setBb(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 bb = 268435455;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearBb() {
-        copyOnWrite();
-        instance.clearBb();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestReallyLargeTagNumber)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestReallyLargeTagNumber();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "a_",
-              "bb_",
-            };
-            java.lang.String info =
-                "\u0001\u0002\u0000\u0001\u0001\uffff\u7fff\u0002\u0000\u0000\u0000\u0001\u1004\u0000" +
-                "\uffff\u7fff\u1004\u0001";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestReallyLargeTagNumber> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestReallyLargeTagNumber.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestReallyLargeTagNumber>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestReallyLargeTagNumber)
-    private static final protobuf_unittest.UnittestProto.TestReallyLargeTagNumber DEFAULT_INSTANCE;
-    static {
-      TestReallyLargeTagNumber defaultInstance = new TestReallyLargeTagNumber();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestReallyLargeTagNumber.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestReallyLargeTagNumber getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestReallyLargeTagNumber> PARSER;
-
-    public static com.google.protobuf.Parser<TestReallyLargeTagNumber> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestRecursiveMessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestRecursiveMessage)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional .protobuf_unittest.TestRecursiveMessage a = 1;</code>
-     * @return Whether the a field is set.
-     */
-    boolean hasA();
-    /**
-     * <code>optional .protobuf_unittest.TestRecursiveMessage a = 1;</code>
-     * @return The a.
-     */
-    protobuf_unittest.UnittestProto.TestRecursiveMessage getA();
-
-    /**
-     * <code>optional int32 i = 2;</code>
-     * @return Whether the i field is set.
-     */
-    boolean hasI();
-    /**
-     * <code>optional int32 i = 2;</code>
-     * @return The i.
-     */
-    int getI();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestRecursiveMessage}
-   */
-  public  static final class TestRecursiveMessage extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestRecursiveMessage, TestRecursiveMessage.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestRecursiveMessage)
-      TestRecursiveMessageOrBuilder {
-    private TestRecursiveMessage() {
-    }
-    private int bitField0_;
-    public static final int A_FIELD_NUMBER = 1;
-    private protobuf_unittest.UnittestProto.TestRecursiveMessage a_;
-    /**
-     * <code>optional .protobuf_unittest.TestRecursiveMessage a = 1;</code>
-     */
-    @java.lang.Override
-    public boolean hasA() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestRecursiveMessage a = 1;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestRecursiveMessage getA() {
-      return a_ == null ? protobuf_unittest.UnittestProto.TestRecursiveMessage.getDefaultInstance() : a_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestRecursiveMessage a = 1;</code>
-     */
-    private void setA(protobuf_unittest.UnittestProto.TestRecursiveMessage value) {
-      value.getClass();
-  a_ = value;
-      bitField0_ |= 0x00000001;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestRecursiveMessage a = 1;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeA(protobuf_unittest.UnittestProto.TestRecursiveMessage value) {
-      value.getClass();
-  if (a_ != null &&
-          a_ != protobuf_unittest.UnittestProto.TestRecursiveMessage.getDefaultInstance()) {
-        a_ =
-          protobuf_unittest.UnittestProto.TestRecursiveMessage.newBuilder(a_).mergeFrom(value).buildPartial();
-      } else {
-        a_ = value;
-      }
-      bitField0_ |= 0x00000001;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestRecursiveMessage a = 1;</code>
-     */
-    private void clearA() {  a_ = null;
-      bitField0_ = (bitField0_ & ~0x00000001);
-    }
-
-    public static final int I_FIELD_NUMBER = 2;
-    private int i_;
-    /**
-     * <code>optional int32 i = 2;</code>
-     * @return Whether the i field is set.
-     */
-    @java.lang.Override
-    public boolean hasI() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional int32 i = 2;</code>
-     * @return The i.
-     */
-    @java.lang.Override
-    public int getI() {
-      return i_;
-    }
-    /**
-     * <code>optional int32 i = 2;</code>
-     * @param value The i to set.
-     */
-    private void setI(int value) {
-      bitField0_ |= 0x00000002;
-      i_ = value;
-    }
-    /**
-     * <code>optional int32 i = 2;</code>
-     */
-    private void clearI() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      i_ = 0;
-    }
-
-    public static protobuf_unittest.UnittestProto.TestRecursiveMessage parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestRecursiveMessage parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRecursiveMessage parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestRecursiveMessage parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRecursiveMessage parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestRecursiveMessage parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRecursiveMessage parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestRecursiveMessage parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRecursiveMessage parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestRecursiveMessage parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRecursiveMessage parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestRecursiveMessage parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestRecursiveMessage prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestRecursiveMessage}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestRecursiveMessage, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestRecursiveMessage)
-        protobuf_unittest.UnittestProto.TestRecursiveMessageOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestRecursiveMessage.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional .protobuf_unittest.TestRecursiveMessage a = 1;</code>
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return instance.hasA();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestRecursiveMessage a = 1;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestRecursiveMessage getA() {
-        return instance.getA();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestRecursiveMessage a = 1;</code>
-       */
-      public Builder setA(protobuf_unittest.UnittestProto.TestRecursiveMessage value) {
-        copyOnWrite();
-        instance.setA(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestRecursiveMessage a = 1;</code>
-       */
-      public Builder setA(
-          protobuf_unittest.UnittestProto.TestRecursiveMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setA(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestRecursiveMessage a = 1;</code>
-       */
-      public Builder mergeA(protobuf_unittest.UnittestProto.TestRecursiveMessage value) {
-        copyOnWrite();
-        instance.mergeA(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestRecursiveMessage a = 1;</code>
-       */
-      public Builder clearA() {  copyOnWrite();
-        instance.clearA();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 i = 2;</code>
-       * @return Whether the i field is set.
-       */
-      @java.lang.Override
-      public boolean hasI() {
-        return instance.hasI();
-      }
-      /**
-       * <code>optional int32 i = 2;</code>
-       * @return The i.
-       */
-      @java.lang.Override
-      public int getI() {
-        return instance.getI();
-      }
-      /**
-       * <code>optional int32 i = 2;</code>
-       * @param value The i to set.
-       * @return This builder for chaining.
-       */
-      public Builder setI(int value) {
-        copyOnWrite();
-        instance.setI(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 i = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearI() {
-        copyOnWrite();
-        instance.clearI();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestRecursiveMessage)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestRecursiveMessage();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "a_",
-              "i_",
-            };
-            java.lang.String info =
-                "\u0001\u0002\u0000\u0001\u0001\u0002\u0002\u0000\u0000\u0000\u0001\u1009\u0000\u0002" +
-                "\u1004\u0001";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestRecursiveMessage> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestRecursiveMessage.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestRecursiveMessage>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestRecursiveMessage)
-    private static final protobuf_unittest.UnittestProto.TestRecursiveMessage DEFAULT_INSTANCE;
-    static {
-      TestRecursiveMessage defaultInstance = new TestRecursiveMessage();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestRecursiveMessage.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestRecursiveMessage getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestRecursiveMessage> PARSER;
-
-    public static com.google.protobuf.Parser<TestRecursiveMessage> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestMutualRecursionAOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestMutualRecursionA)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional .protobuf_unittest.TestMutualRecursionB bb = 1;</code>
-     * @return Whether the bb field is set.
-     */
-    boolean hasBb();
-    /**
-     * <code>optional .protobuf_unittest.TestMutualRecursionB bb = 1;</code>
-     * @return The bb.
-     */
-    protobuf_unittest.UnittestProto.TestMutualRecursionB getBb();
-
-    /**
-     * <code>optional group SubGroup = 2 { ... }</code>
-     * @return Whether the subgroup field is set.
-     */
-    boolean hasSubGroup();
-    /**
-     * <code>optional group SubGroup = 2 { ... }</code>
-     * @return The subgroup.
-     */
-    protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup getSubGroup();
-  }
-  /**
-   * <pre>
-   * Test that mutual recursion works.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestMutualRecursionA}
-   */
-  public  static final class TestMutualRecursionA extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestMutualRecursionA, TestMutualRecursionA.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestMutualRecursionA)
-      TestMutualRecursionAOrBuilder {
-    private TestMutualRecursionA() {
-    }
-    public interface SubMessageOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestMutualRecursionA.SubMessage)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional .protobuf_unittest.TestMutualRecursionB b = 1;</code>
-       * @return Whether the b field is set.
-       */
-      boolean hasB();
-      /**
-       * <code>optional .protobuf_unittest.TestMutualRecursionB b = 1;</code>
-       * @return The b.
-       */
-      protobuf_unittest.UnittestProto.TestMutualRecursionB getB();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestMutualRecursionA.SubMessage}
-     */
-    public  static final class SubMessage extends
-        com.google.protobuf.GeneratedMessageLite<
-            SubMessage, SubMessage.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestMutualRecursionA.SubMessage)
-        SubMessageOrBuilder {
-      private SubMessage() {
-      }
-      private int bitField0_;
-      public static final int B_FIELD_NUMBER = 1;
-      private protobuf_unittest.UnittestProto.TestMutualRecursionB b_;
-      /**
-       * <code>optional .protobuf_unittest.TestMutualRecursionB b = 1;</code>
-       */
-      @java.lang.Override
-      public boolean hasB() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestMutualRecursionB b = 1;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestMutualRecursionB getB() {
-        return b_ == null ? protobuf_unittest.UnittestProto.TestMutualRecursionB.getDefaultInstance() : b_;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestMutualRecursionB b = 1;</code>
-       */
-      private void setB(protobuf_unittest.UnittestProto.TestMutualRecursionB value) {
-        value.getClass();
-  b_ = value;
-        bitField0_ |= 0x00000001;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestMutualRecursionB b = 1;</code>
-       */
-      @java.lang.SuppressWarnings({"ReferenceEquality"})
-      private void mergeB(protobuf_unittest.UnittestProto.TestMutualRecursionB value) {
-        value.getClass();
-  if (b_ != null &&
-            b_ != protobuf_unittest.UnittestProto.TestMutualRecursionB.getDefaultInstance()) {
-          b_ =
-            protobuf_unittest.UnittestProto.TestMutualRecursionB.newBuilder(b_).mergeFrom(value).buildPartial();
-        } else {
-          b_ = value;
-        }
-        bitField0_ |= 0x00000001;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestMutualRecursionB b = 1;</code>
-       */
-      private void clearB() {  b_ = null;
-        bitField0_ = (bitField0_ & ~0x00000001);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestMutualRecursionA.SubMessage}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestMutualRecursionA.SubMessage)
-          protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessageOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional .protobuf_unittest.TestMutualRecursionB b = 1;</code>
-         */
-        @java.lang.Override
-        public boolean hasB() {
-          return instance.hasB();
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestMutualRecursionB b = 1;</code>
-         */
-        @java.lang.Override
-        public protobuf_unittest.UnittestProto.TestMutualRecursionB getB() {
-          return instance.getB();
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestMutualRecursionB b = 1;</code>
-         */
-        public Builder setB(protobuf_unittest.UnittestProto.TestMutualRecursionB value) {
-          copyOnWrite();
-          instance.setB(value);
-          return this;
-          }
-        /**
-         * <code>optional .protobuf_unittest.TestMutualRecursionB b = 1;</code>
-         */
-        public Builder setB(
-            protobuf_unittest.UnittestProto.TestMutualRecursionB.Builder builderForValue) {
-          copyOnWrite();
-          instance.setB(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestMutualRecursionB b = 1;</code>
-         */
-        public Builder mergeB(protobuf_unittest.UnittestProto.TestMutualRecursionB value) {
-          copyOnWrite();
-          instance.mergeB(value);
-          return this;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestMutualRecursionB b = 1;</code>
-         */
-        public Builder clearB() {  copyOnWrite();
-          instance.clearB();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestMutualRecursionA.SubMessage)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "b_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1009\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestMutualRecursionA.SubMessage)
-      private static final protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage DEFAULT_INSTANCE;
-      static {
-        SubMessage defaultInstance = new SubMessage();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          SubMessage.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<SubMessage> PARSER;
-
-      public static com.google.protobuf.Parser<SubMessage> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    public interface SubGroupOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestMutualRecursionA.SubGroup)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <pre>
-       * Needed because of bug in javatest
-       * </pre>
-       *
-       * <code>optional .protobuf_unittest.TestMutualRecursionA.SubMessage sub_message = 3;</code>
-       * @return Whether the subMessage field is set.
-       */
-      boolean hasSubMessage();
-      /**
-       * <pre>
-       * Needed because of bug in javatest
-       * </pre>
-       *
-       * <code>optional .protobuf_unittest.TestMutualRecursionA.SubMessage sub_message = 3;</code>
-       * @return The subMessage.
-       */
-      protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage getSubMessage();
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes not_in_this_scc = 4;</code>
-       * @return Whether the notInThisScc field is set.
-       */
-      boolean hasNotInThisScc();
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes not_in_this_scc = 4;</code>
-       * @return The notInThisScc.
-       */
-      protobuf_unittest.UnittestProto.TestAllTypes getNotInThisScc();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestMutualRecursionA.SubGroup}
-     */
-    public  static final class SubGroup extends
-        com.google.protobuf.GeneratedMessageLite<
-            SubGroup, SubGroup.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestMutualRecursionA.SubGroup)
-        SubGroupOrBuilder {
-      private SubGroup() {
-      }
-      private int bitField0_;
-      public static final int SUB_MESSAGE_FIELD_NUMBER = 3;
-      private protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage subMessage_;
-      /**
-       * <pre>
-       * Needed because of bug in javatest
-       * </pre>
-       *
-       * <code>optional .protobuf_unittest.TestMutualRecursionA.SubMessage sub_message = 3;</code>
-       */
-      @java.lang.Override
-      public boolean hasSubMessage() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <pre>
-       * Needed because of bug in javatest
-       * </pre>
-       *
-       * <code>optional .protobuf_unittest.TestMutualRecursionA.SubMessage sub_message = 3;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage getSubMessage() {
-        return subMessage_ == null ? protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage.getDefaultInstance() : subMessage_;
-      }
-      /**
-       * <pre>
-       * Needed because of bug in javatest
-       * </pre>
-       *
-       * <code>optional .protobuf_unittest.TestMutualRecursionA.SubMessage sub_message = 3;</code>
-       */
-      private void setSubMessage(protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage value) {
-        value.getClass();
-  subMessage_ = value;
-        bitField0_ |= 0x00000001;
-        }
-      /**
-       * <pre>
-       * Needed because of bug in javatest
-       * </pre>
-       *
-       * <code>optional .protobuf_unittest.TestMutualRecursionA.SubMessage sub_message = 3;</code>
-       */
-      @java.lang.SuppressWarnings({"ReferenceEquality"})
-      private void mergeSubMessage(protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage value) {
-        value.getClass();
-  if (subMessage_ != null &&
-            subMessage_ != protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage.getDefaultInstance()) {
-          subMessage_ =
-            protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage.newBuilder(subMessage_).mergeFrom(value).buildPartial();
-        } else {
-          subMessage_ = value;
-        }
-        bitField0_ |= 0x00000001;
-      }
-      /**
-       * <pre>
-       * Needed because of bug in javatest
-       * </pre>
-       *
-       * <code>optional .protobuf_unittest.TestMutualRecursionA.SubMessage sub_message = 3;</code>
-       */
-      private void clearSubMessage() {  subMessage_ = null;
-        bitField0_ = (bitField0_ & ~0x00000001);
-      }
-
-      public static final int NOT_IN_THIS_SCC_FIELD_NUMBER = 4;
-      private protobuf_unittest.UnittestProto.TestAllTypes notInThisScc_;
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes not_in_this_scc = 4;</code>
-       */
-      @java.lang.Override
-      public boolean hasNotInThisScc() {
-        return ((bitField0_ & 0x00000002) != 0);
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes not_in_this_scc = 4;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes getNotInThisScc() {
-        return notInThisScc_ == null ? protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance() : notInThisScc_;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes not_in_this_scc = 4;</code>
-       */
-      private void setNotInThisScc(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  notInThisScc_ = value;
-        bitField0_ |= 0x00000002;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes not_in_this_scc = 4;</code>
-       */
-      @java.lang.SuppressWarnings({"ReferenceEquality"})
-      private void mergeNotInThisScc(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  if (notInThisScc_ != null &&
-            notInThisScc_ != protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance()) {
-          notInThisScc_ =
-            protobuf_unittest.UnittestProto.TestAllTypes.newBuilder(notInThisScc_).mergeFrom(value).buildPartial();
-        } else {
-          notInThisScc_ = value;
-        }
-        bitField0_ |= 0x00000002;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes not_in_this_scc = 4;</code>
-       */
-      private void clearNotInThisScc() {  notInThisScc_ = null;
-        bitField0_ = (bitField0_ & ~0x00000002);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestMutualRecursionA.SubGroup}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestMutualRecursionA.SubGroup)
-          protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroupOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <pre>
-         * Needed because of bug in javatest
-         * </pre>
-         *
-         * <code>optional .protobuf_unittest.TestMutualRecursionA.SubMessage sub_message = 3;</code>
-         */
-        @java.lang.Override
-        public boolean hasSubMessage() {
-          return instance.hasSubMessage();
-        }
-        /**
-         * <pre>
-         * Needed because of bug in javatest
-         * </pre>
-         *
-         * <code>optional .protobuf_unittest.TestMutualRecursionA.SubMessage sub_message = 3;</code>
-         */
-        @java.lang.Override
-        public protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage getSubMessage() {
-          return instance.getSubMessage();
-        }
-        /**
-         * <pre>
-         * Needed because of bug in javatest
-         * </pre>
-         *
-         * <code>optional .protobuf_unittest.TestMutualRecursionA.SubMessage sub_message = 3;</code>
-         */
-        public Builder setSubMessage(protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage value) {
-          copyOnWrite();
-          instance.setSubMessage(value);
-          return this;
-          }
-        /**
-         * <pre>
-         * Needed because of bug in javatest
-         * </pre>
-         *
-         * <code>optional .protobuf_unittest.TestMutualRecursionA.SubMessage sub_message = 3;</code>
-         */
-        public Builder setSubMessage(
-            protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage.Builder builderForValue) {
-          copyOnWrite();
-          instance.setSubMessage(builderForValue.build());
-          return this;
-        }
-        /**
-         * <pre>
-         * Needed because of bug in javatest
-         * </pre>
-         *
-         * <code>optional .protobuf_unittest.TestMutualRecursionA.SubMessage sub_message = 3;</code>
-         */
-        public Builder mergeSubMessage(protobuf_unittest.UnittestProto.TestMutualRecursionA.SubMessage value) {
-          copyOnWrite();
-          instance.mergeSubMessage(value);
-          return this;
-        }
-        /**
-         * <pre>
-         * Needed because of bug in javatest
-         * </pre>
-         *
-         * <code>optional .protobuf_unittest.TestMutualRecursionA.SubMessage sub_message = 3;</code>
-         */
-        public Builder clearSubMessage() {  copyOnWrite();
-          instance.clearSubMessage();
-          return this;
-        }
-
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes not_in_this_scc = 4;</code>
-         */
-        @java.lang.Override
-        public boolean hasNotInThisScc() {
-          return instance.hasNotInThisScc();
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes not_in_this_scc = 4;</code>
-         */
-        @java.lang.Override
-        public protobuf_unittest.UnittestProto.TestAllTypes getNotInThisScc() {
-          return instance.getNotInThisScc();
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes not_in_this_scc = 4;</code>
-         */
-        public Builder setNotInThisScc(protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.setNotInThisScc(value);
-          return this;
-          }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes not_in_this_scc = 4;</code>
-         */
-        public Builder setNotInThisScc(
-            protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-          copyOnWrite();
-          instance.setNotInThisScc(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes not_in_this_scc = 4;</code>
-         */
-        public Builder mergeNotInThisScc(protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.mergeNotInThisScc(value);
-          return this;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes not_in_this_scc = 4;</code>
-         */
-        public Builder clearNotInThisScc() {  copyOnWrite();
-          instance.clearNotInThisScc();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestMutualRecursionA.SubGroup)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "subMessage_",
-                "notInThisScc_",
-              };
-              java.lang.String info =
-                  "\u0001\u0002\u0000\u0001\u0003\u0004\u0002\u0000\u0000\u0000\u0003\u1009\u0000\u0004" +
-                  "\u1009\u0001";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestMutualRecursionA.SubGroup)
-      private static final protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup DEFAULT_INSTANCE;
-      static {
-        SubGroup defaultInstance = new SubGroup();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          SubGroup.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<SubGroup> PARSER;
-
-      public static com.google.protobuf.Parser<SubGroup> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int bitField0_;
-    public static final int BB_FIELD_NUMBER = 1;
-    private protobuf_unittest.UnittestProto.TestMutualRecursionB bb_;
-    /**
-     * <code>optional .protobuf_unittest.TestMutualRecursionB bb = 1;</code>
-     */
-    @java.lang.Override
-    public boolean hasBb() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestMutualRecursionB bb = 1;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestMutualRecursionB getBb() {
-      return bb_ == null ? protobuf_unittest.UnittestProto.TestMutualRecursionB.getDefaultInstance() : bb_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestMutualRecursionB bb = 1;</code>
-     */
-    private void setBb(protobuf_unittest.UnittestProto.TestMutualRecursionB value) {
-      value.getClass();
-  bb_ = value;
-      bitField0_ |= 0x00000001;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestMutualRecursionB bb = 1;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeBb(protobuf_unittest.UnittestProto.TestMutualRecursionB value) {
-      value.getClass();
-  if (bb_ != null &&
-          bb_ != protobuf_unittest.UnittestProto.TestMutualRecursionB.getDefaultInstance()) {
-        bb_ =
-          protobuf_unittest.UnittestProto.TestMutualRecursionB.newBuilder(bb_).mergeFrom(value).buildPartial();
-      } else {
-        bb_ = value;
-      }
-      bitField0_ |= 0x00000001;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestMutualRecursionB bb = 1;</code>
-     */
-    private void clearBb() {  bb_ = null;
-      bitField0_ = (bitField0_ & ~0x00000001);
-    }
-
-    public static final int SUBGROUP_FIELD_NUMBER = 2;
-    private protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup subGroup_;
-    /**
-     * <code>optional group SubGroup = 2 { ... }</code>
-     */
-    @java.lang.Override
-    public boolean hasSubGroup() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional group SubGroup = 2 { ... }</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup getSubGroup() {
-      return subGroup_ == null ? protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup.getDefaultInstance() : subGroup_;
-    }
-    /**
-     * <code>optional group SubGroup = 2 { ... }</code>
-     */
-    private void setSubGroup(protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup value) {
-      value.getClass();
-  subGroup_ = value;
-      bitField0_ |= 0x00000002;
-      }
-    /**
-     * <code>optional group SubGroup = 2 { ... }</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeSubGroup(protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup value) {
-      value.getClass();
-  if (subGroup_ != null &&
-          subGroup_ != protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup.getDefaultInstance()) {
-        subGroup_ =
-          protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup.newBuilder(subGroup_).mergeFrom(value).buildPartial();
-      } else {
-        subGroup_ = value;
-      }
-      bitField0_ |= 0x00000002;
-    }
-    /**
-     * <code>optional group SubGroup = 2 { ... }</code>
-     */
-    private void clearSubGroup() {  subGroup_ = null;
-      bitField0_ = (bitField0_ & ~0x00000002);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionA parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionA parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionA parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionA parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionA parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionA parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionA parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionA parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionA parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionA parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionA parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionA parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestMutualRecursionA prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Test that mutual recursion works.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestMutualRecursionA}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestMutualRecursionA, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestMutualRecursionA)
-        protobuf_unittest.UnittestProto.TestMutualRecursionAOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestMutualRecursionA.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional .protobuf_unittest.TestMutualRecursionB bb = 1;</code>
-       */
-      @java.lang.Override
-      public boolean hasBb() {
-        return instance.hasBb();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestMutualRecursionB bb = 1;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestMutualRecursionB getBb() {
-        return instance.getBb();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestMutualRecursionB bb = 1;</code>
-       */
-      public Builder setBb(protobuf_unittest.UnittestProto.TestMutualRecursionB value) {
-        copyOnWrite();
-        instance.setBb(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestMutualRecursionB bb = 1;</code>
-       */
-      public Builder setBb(
-          protobuf_unittest.UnittestProto.TestMutualRecursionB.Builder builderForValue) {
-        copyOnWrite();
-        instance.setBb(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestMutualRecursionB bb = 1;</code>
-       */
-      public Builder mergeBb(protobuf_unittest.UnittestProto.TestMutualRecursionB value) {
-        copyOnWrite();
-        instance.mergeBb(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestMutualRecursionB bb = 1;</code>
-       */
-      public Builder clearBb() {  copyOnWrite();
-        instance.clearBb();
-        return this;
-      }
-
-      /**
-       * <code>optional group SubGroup = 2 { ... }</code>
-       */
-      @java.lang.Override
-      public boolean hasSubGroup() {
-        return instance.hasSubGroup();
-      }
-      /**
-       * <code>optional group SubGroup = 2 { ... }</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup getSubGroup() {
-        return instance.getSubGroup();
-      }
-      /**
-       * <code>optional group SubGroup = 2 { ... }</code>
-       */
-      public Builder setSubGroup(protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup value) {
-        copyOnWrite();
-        instance.setSubGroup(value);
-        return this;
-        }
-      /**
-       * <code>optional group SubGroup = 2 { ... }</code>
-       */
-      public Builder setSubGroup(
-          protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.setSubGroup(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional group SubGroup = 2 { ... }</code>
-       */
-      public Builder mergeSubGroup(protobuf_unittest.UnittestProto.TestMutualRecursionA.SubGroup value) {
-        copyOnWrite();
-        instance.mergeSubGroup(value);
-        return this;
-      }
-      /**
-       * <code>optional group SubGroup = 2 { ... }</code>
-       */
-      public Builder clearSubGroup() {  copyOnWrite();
-        instance.clearSubGroup();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestMutualRecursionA)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestMutualRecursionA();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "bb_",
-              "subGroup_",
-            };
-            java.lang.String info =
-                "\u0001\u0002\u0000\u0001\u0001\u0002\u0002\u0000\u0000\u0000\u0001\u1009\u0000\u0002" +
-                "\u1011\u0001";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestMutualRecursionA> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestMutualRecursionA.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestMutualRecursionA>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestMutualRecursionA)
-    private static final protobuf_unittest.UnittestProto.TestMutualRecursionA DEFAULT_INSTANCE;
-    static {
-      TestMutualRecursionA defaultInstance = new TestMutualRecursionA();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestMutualRecursionA.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionA getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestMutualRecursionA> PARSER;
-
-    public static com.google.protobuf.Parser<TestMutualRecursionA> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestMutualRecursionBOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestMutualRecursionB)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional .protobuf_unittest.TestMutualRecursionA a = 1;</code>
-     * @return Whether the a field is set.
-     */
-    boolean hasA();
-    /**
-     * <code>optional .protobuf_unittest.TestMutualRecursionA a = 1;</code>
-     * @return The a.
-     */
-    protobuf_unittest.UnittestProto.TestMutualRecursionA getA();
-
-    /**
-     * <code>optional int32 optional_int32 = 2;</code>
-     * @return Whether the optionalInt32 field is set.
-     */
-    boolean hasOptionalInt32();
-    /**
-     * <code>optional int32 optional_int32 = 2;</code>
-     * @return The optionalInt32.
-     */
-    int getOptionalInt32();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestMutualRecursionB}
-   */
-  public  static final class TestMutualRecursionB extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestMutualRecursionB, TestMutualRecursionB.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestMutualRecursionB)
-      TestMutualRecursionBOrBuilder {
-    private TestMutualRecursionB() {
-    }
-    private int bitField0_;
-    public static final int A_FIELD_NUMBER = 1;
-    private protobuf_unittest.UnittestProto.TestMutualRecursionA a_;
-    /**
-     * <code>optional .protobuf_unittest.TestMutualRecursionA a = 1;</code>
-     */
-    @java.lang.Override
-    public boolean hasA() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestMutualRecursionA a = 1;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestMutualRecursionA getA() {
-      return a_ == null ? protobuf_unittest.UnittestProto.TestMutualRecursionA.getDefaultInstance() : a_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestMutualRecursionA a = 1;</code>
-     */
-    private void setA(protobuf_unittest.UnittestProto.TestMutualRecursionA value) {
-      value.getClass();
-  a_ = value;
-      bitField0_ |= 0x00000001;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestMutualRecursionA a = 1;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeA(protobuf_unittest.UnittestProto.TestMutualRecursionA value) {
-      value.getClass();
-  if (a_ != null &&
-          a_ != protobuf_unittest.UnittestProto.TestMutualRecursionA.getDefaultInstance()) {
-        a_ =
-          protobuf_unittest.UnittestProto.TestMutualRecursionA.newBuilder(a_).mergeFrom(value).buildPartial();
-      } else {
-        a_ = value;
-      }
-      bitField0_ |= 0x00000001;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestMutualRecursionA a = 1;</code>
-     */
-    private void clearA() {  a_ = null;
-      bitField0_ = (bitField0_ & ~0x00000001);
-    }
-
-    public static final int OPTIONAL_INT32_FIELD_NUMBER = 2;
-    private int optionalInt32_;
-    /**
-     * <code>optional int32 optional_int32 = 2;</code>
-     * @return Whether the optionalInt32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalInt32() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional int32 optional_int32 = 2;</code>
-     * @return The optionalInt32.
-     */
-    @java.lang.Override
-    public int getOptionalInt32() {
-      return optionalInt32_;
-    }
-    /**
-     * <code>optional int32 optional_int32 = 2;</code>
-     * @param value The optionalInt32 to set.
-     */
-    private void setOptionalInt32(int value) {
-      bitField0_ |= 0x00000002;
-      optionalInt32_ = value;
-    }
-    /**
-     * <code>optional int32 optional_int32 = 2;</code>
-     */
-    private void clearOptionalInt32() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      optionalInt32_ = 0;
-    }
-
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionB parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionB parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionB parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionB parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionB parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionB parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionB parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionB parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionB parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionB parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionB parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionB parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestMutualRecursionB prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestMutualRecursionB}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestMutualRecursionB, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestMutualRecursionB)
-        protobuf_unittest.UnittestProto.TestMutualRecursionBOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestMutualRecursionB.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional .protobuf_unittest.TestMutualRecursionA a = 1;</code>
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return instance.hasA();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestMutualRecursionA a = 1;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestMutualRecursionA getA() {
-        return instance.getA();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestMutualRecursionA a = 1;</code>
-       */
-      public Builder setA(protobuf_unittest.UnittestProto.TestMutualRecursionA value) {
-        copyOnWrite();
-        instance.setA(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestMutualRecursionA a = 1;</code>
-       */
-      public Builder setA(
-          protobuf_unittest.UnittestProto.TestMutualRecursionA.Builder builderForValue) {
-        copyOnWrite();
-        instance.setA(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestMutualRecursionA a = 1;</code>
-       */
-      public Builder mergeA(protobuf_unittest.UnittestProto.TestMutualRecursionA value) {
-        copyOnWrite();
-        instance.mergeA(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestMutualRecursionA a = 1;</code>
-       */
-      public Builder clearA() {  copyOnWrite();
-        instance.clearA();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 optional_int32 = 2;</code>
-       * @return Whether the optionalInt32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalInt32() {
-        return instance.hasOptionalInt32();
-      }
-      /**
-       * <code>optional int32 optional_int32 = 2;</code>
-       * @return The optionalInt32.
-       */
-      @java.lang.Override
-      public int getOptionalInt32() {
-        return instance.getOptionalInt32();
-      }
-      /**
-       * <code>optional int32 optional_int32 = 2;</code>
-       * @param value The optionalInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalInt32(int value) {
-        copyOnWrite();
-        instance.setOptionalInt32(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 optional_int32 = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalInt32() {
-        copyOnWrite();
-        instance.clearOptionalInt32();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestMutualRecursionB)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestMutualRecursionB();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "a_",
-              "optionalInt32_",
-            };
-            java.lang.String info =
-                "\u0001\u0002\u0000\u0001\u0001\u0002\u0002\u0000\u0000\u0000\u0001\u1009\u0000\u0002" +
-                "\u1004\u0001";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestMutualRecursionB> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestMutualRecursionB.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestMutualRecursionB>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestMutualRecursionB)
-    private static final protobuf_unittest.UnittestProto.TestMutualRecursionB DEFAULT_INSTANCE;
-    static {
-      TestMutualRecursionB defaultInstance = new TestMutualRecursionB();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestMutualRecursionB.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestMutualRecursionB getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestMutualRecursionB> PARSER;
-
-    public static com.google.protobuf.Parser<TestMutualRecursionB> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestIsInitializedOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestIsInitialized)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional .protobuf_unittest.TestIsInitialized.SubMessage sub_message = 1;</code>
-     * @return Whether the subMessage field is set.
-     */
-    boolean hasSubMessage();
-    /**
-     * <code>optional .protobuf_unittest.TestIsInitialized.SubMessage sub_message = 1;</code>
-     * @return The subMessage.
-     */
-    protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage getSubMessage();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestIsInitialized}
-   */
-  public  static final class TestIsInitialized extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestIsInitialized, TestIsInitialized.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestIsInitialized)
-      TestIsInitializedOrBuilder {
-    private TestIsInitialized() {
-    }
-    public interface SubMessageOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestIsInitialized.SubMessage)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional group SubGroup = 1 { ... }</code>
-       * @return Whether the subgroup field is set.
-       */
-      boolean hasSubGroup();
-      /**
-       * <code>optional group SubGroup = 1 { ... }</code>
-       * @return The subgroup.
-       */
-      protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup getSubGroup();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestIsInitialized.SubMessage}
-     */
-    public  static final class SubMessage extends
-        com.google.protobuf.GeneratedMessageLite<
-            SubMessage, SubMessage.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestIsInitialized.SubMessage)
-        SubMessageOrBuilder {
-      private SubMessage() {
-      }
-      public interface SubGroupOrBuilder extends
-          // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestIsInitialized.SubMessage.SubGroup)
-          com.google.protobuf.MessageLiteOrBuilder {
-
-        /**
-         * <code>required int32 i = 2;</code>
-         * @return Whether the i field is set.
-         */
-        boolean hasI();
-        /**
-         * <code>required int32 i = 2;</code>
-         * @return The i.
-         */
-        int getI();
-      }
-      /**
-       * Protobuf type {@code protobuf_unittest.TestIsInitialized.SubMessage.SubGroup}
-       */
-      public  static final class SubGroup extends
-          com.google.protobuf.GeneratedMessageLite<
-              SubGroup, SubGroup.Builder> implements
-          // @@protoc_insertion_point(message_implements:protobuf_unittest.TestIsInitialized.SubMessage.SubGroup)
-          SubGroupOrBuilder {
-        private SubGroup() {
-        }
-        private int bitField0_;
-        public static final int I_FIELD_NUMBER = 2;
-        private int i_;
-        /**
-         * <code>required int32 i = 2;</code>
-         * @return Whether the i field is set.
-         */
-        @java.lang.Override
-        public boolean hasI() {
-          return ((bitField0_ & 0x00000001) != 0);
-        }
-        /**
-         * <code>required int32 i = 2;</code>
-         * @return The i.
-         */
-        @java.lang.Override
-        public int getI() {
-          return i_;
-        }
-        /**
-         * <code>required int32 i = 2;</code>
-         * @param value The i to set.
-         */
-        private void setI(int value) {
-          bitField0_ |= 0x00000001;
-          i_ = value;
-        }
-        /**
-         * <code>required int32 i = 2;</code>
-         */
-        private void clearI() {
-          bitField0_ = (bitField0_ & ~0x00000001);
-          i_ = 0;
-        }
-
-        public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup parseFrom(
-            java.nio.ByteBuffer data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data);
-        }
-        public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup parseFrom(
-            java.nio.ByteBuffer data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup parseFrom(
-            com.google.protobuf.ByteString data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data);
-        }
-        public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup parseFrom(
-            com.google.protobuf.ByteString data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup parseFrom(byte[] data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data);
-        }
-        public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup parseFrom(
-            byte[] data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup parseFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input);
-        }
-        public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup parseFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup parseDelimitedFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-        }
-        public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup parseDelimitedFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup parseFrom(
-            com.google.protobuf.CodedInputStream input)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input);
-        }
-        public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup parseFrom(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input, extensionRegistry);
-        }
-
-        public static Builder newBuilder() {
-          return (Builder) DEFAULT_INSTANCE.createBuilder();
-        }
-        public static Builder newBuilder(protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup prototype) {
-          return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-        }
-
-        /**
-         * Protobuf type {@code protobuf_unittest.TestIsInitialized.SubMessage.SubGroup}
-         */
-        public static final class Builder extends
-            com.google.protobuf.GeneratedMessageLite.Builder<
-              protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup, Builder> implements
-            // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestIsInitialized.SubMessage.SubGroup)
-            protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroupOrBuilder {
-          // Construct using protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup.newBuilder()
-          private Builder() {
-            super(DEFAULT_INSTANCE);
-          }
-
-
-          /**
-           * <code>required int32 i = 2;</code>
-           * @return Whether the i field is set.
-           */
-          @java.lang.Override
-          public boolean hasI() {
-            return instance.hasI();
-          }
-          /**
-           * <code>required int32 i = 2;</code>
-           * @return The i.
-           */
-          @java.lang.Override
-          public int getI() {
-            return instance.getI();
-          }
-          /**
-           * <code>required int32 i = 2;</code>
-           * @param value The i to set.
-           * @return This builder for chaining.
-           */
-          public Builder setI(int value) {
-            copyOnWrite();
-            instance.setI(value);
-            return this;
-          }
-          /**
-           * <code>required int32 i = 2;</code>
-           * @return This builder for chaining.
-           */
-          public Builder clearI() {
-            copyOnWrite();
-            instance.clearI();
-            return this;
-          }
-
-          // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestIsInitialized.SubMessage.SubGroup)
-        }
-        private byte memoizedIsInitialized = 2;
-        @java.lang.Override
-        @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-        protected final java.lang.Object dynamicMethod(
-            com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-            java.lang.Object arg0, java.lang.Object arg1) {
-          switch (method) {
-            case NEW_MUTABLE_INSTANCE: {
-              return new protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup();
-            }
-            case NEW_BUILDER: {
-              return new Builder();
-            }
-            case BUILD_MESSAGE_INFO: {
-                java.lang.Object[] objects = new java.lang.Object[] {
-                  "bitField0_",
-                  "i_",
-                };
-                java.lang.String info =
-                    "\u0001\u0001\u0000\u0001\u0002\u0002\u0001\u0000\u0000\u0001\u0002\u1504\u0000";
-                return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-            }
-            // fall through
-            case GET_DEFAULT_INSTANCE: {
-              return DEFAULT_INSTANCE;
-            }
-            case GET_PARSER: {
-              com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup> parser = PARSER;
-              if (parser == null) {
-                synchronized (protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup.class) {
-                  parser = PARSER;
-                  if (parser == null) {
-                    parser =
-                        new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup>(
-                            DEFAULT_INSTANCE);
-                    PARSER = parser;
-                  }
-                }
-              }
-              return parser;
-          }
-          case GET_MEMOIZED_IS_INITIALIZED: {
-            return memoizedIsInitialized;
-          }
-          case SET_MEMOIZED_IS_INITIALIZED: {
-            memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-            return null;
-          }
-          }
-          throw new UnsupportedOperationException();
-        }
-
-
-        // @@protoc_insertion_point(class_scope:protobuf_unittest.TestIsInitialized.SubMessage.SubGroup)
-        private static final protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup DEFAULT_INSTANCE;
-        static {
-          SubGroup defaultInstance = new SubGroup();
-          // New instances are implicitly immutable so no need to make
-          // immutable.
-          DEFAULT_INSTANCE = defaultInstance;
-          com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-            SubGroup.class, defaultInstance);
-        }
-
-        public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup getDefaultInstance() {
-          return DEFAULT_INSTANCE;
-        }
-
-        private static volatile com.google.protobuf.Parser<SubGroup> PARSER;
-
-        public static com.google.protobuf.Parser<SubGroup> parser() {
-          return DEFAULT_INSTANCE.getParserForType();
-        }
-      }
-
-      private int bitField0_;
-      public static final int SUBGROUP_FIELD_NUMBER = 1;
-      private protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup subGroup_;
-      /**
-       * <code>optional group SubGroup = 1 { ... }</code>
-       */
-      @java.lang.Override
-      public boolean hasSubGroup() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional group SubGroup = 1 { ... }</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup getSubGroup() {
-        return subGroup_ == null ? protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup.getDefaultInstance() : subGroup_;
-      }
-      /**
-       * <code>optional group SubGroup = 1 { ... }</code>
-       */
-      private void setSubGroup(protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup value) {
-        value.getClass();
-  subGroup_ = value;
-        bitField0_ |= 0x00000001;
-        }
-      /**
-       * <code>optional group SubGroup = 1 { ... }</code>
-       */
-      @java.lang.SuppressWarnings({"ReferenceEquality"})
-      private void mergeSubGroup(protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup value) {
-        value.getClass();
-  if (subGroup_ != null &&
-            subGroup_ != protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup.getDefaultInstance()) {
-          subGroup_ =
-            protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup.newBuilder(subGroup_).mergeFrom(value).buildPartial();
-        } else {
-          subGroup_ = value;
-        }
-        bitField0_ |= 0x00000001;
-      }
-      /**
-       * <code>optional group SubGroup = 1 { ... }</code>
-       */
-      private void clearSubGroup() {  subGroup_ = null;
-        bitField0_ = (bitField0_ & ~0x00000001);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestIsInitialized.SubMessage}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestIsInitialized.SubMessage)
-          protobuf_unittest.UnittestProto.TestIsInitialized.SubMessageOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional group SubGroup = 1 { ... }</code>
-         */
-        @java.lang.Override
-        public boolean hasSubGroup() {
-          return instance.hasSubGroup();
-        }
-        /**
-         * <code>optional group SubGroup = 1 { ... }</code>
-         */
-        @java.lang.Override
-        public protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup getSubGroup() {
-          return instance.getSubGroup();
-        }
-        /**
-         * <code>optional group SubGroup = 1 { ... }</code>
-         */
-        public Builder setSubGroup(protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup value) {
-          copyOnWrite();
-          instance.setSubGroup(value);
-          return this;
-          }
-        /**
-         * <code>optional group SubGroup = 1 { ... }</code>
-         */
-        public Builder setSubGroup(
-            protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup.Builder builderForValue) {
-          copyOnWrite();
-          instance.setSubGroup(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>optional group SubGroup = 1 { ... }</code>
-         */
-        public Builder mergeSubGroup(protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.SubGroup value) {
-          copyOnWrite();
-          instance.mergeSubGroup(value);
-          return this;
-        }
-        /**
-         * <code>optional group SubGroup = 1 { ... }</code>
-         */
-        public Builder clearSubGroup() {  copyOnWrite();
-          instance.clearSubGroup();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestIsInitialized.SubMessage)
-      }
-      private byte memoizedIsInitialized = 2;
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "subGroup_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0001\u0001\u1411\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return memoizedIsInitialized;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestIsInitialized.SubMessage)
-      private static final protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage DEFAULT_INSTANCE;
-      static {
-        SubMessage defaultInstance = new SubMessage();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          SubMessage.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<SubMessage> PARSER;
-
-      public static com.google.protobuf.Parser<SubMessage> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int bitField0_;
-    public static final int SUB_MESSAGE_FIELD_NUMBER = 1;
-    private protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage subMessage_;
-    /**
-     * <code>optional .protobuf_unittest.TestIsInitialized.SubMessage sub_message = 1;</code>
-     */
-    @java.lang.Override
-    public boolean hasSubMessage() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestIsInitialized.SubMessage sub_message = 1;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage getSubMessage() {
-      return subMessage_ == null ? protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.getDefaultInstance() : subMessage_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestIsInitialized.SubMessage sub_message = 1;</code>
-     */
-    private void setSubMessage(protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage value) {
-      value.getClass();
-  subMessage_ = value;
-      bitField0_ |= 0x00000001;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestIsInitialized.SubMessage sub_message = 1;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeSubMessage(protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage value) {
-      value.getClass();
-  if (subMessage_ != null &&
-          subMessage_ != protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.getDefaultInstance()) {
-        subMessage_ =
-          protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.newBuilder(subMessage_).mergeFrom(value).buildPartial();
-      } else {
-        subMessage_ = value;
-      }
-      bitField0_ |= 0x00000001;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestIsInitialized.SubMessage sub_message = 1;</code>
-     */
-    private void clearSubMessage() {  subMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x00000001);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestIsInitialized parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestIsInitialized parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestIsInitialized parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestIsInitialized parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestIsInitialized parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestIsInitialized parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestIsInitialized parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestIsInitialized parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestIsInitialized parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestIsInitialized parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestIsInitialized parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestIsInitialized parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestIsInitialized prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestIsInitialized}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestIsInitialized, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestIsInitialized)
-        protobuf_unittest.UnittestProto.TestIsInitializedOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestIsInitialized.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional .protobuf_unittest.TestIsInitialized.SubMessage sub_message = 1;</code>
-       */
-      @java.lang.Override
-      public boolean hasSubMessage() {
-        return instance.hasSubMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestIsInitialized.SubMessage sub_message = 1;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage getSubMessage() {
-        return instance.getSubMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestIsInitialized.SubMessage sub_message = 1;</code>
-       */
-      public Builder setSubMessage(protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage value) {
-        copyOnWrite();
-        instance.setSubMessage(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestIsInitialized.SubMessage sub_message = 1;</code>
-       */
-      public Builder setSubMessage(
-          protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setSubMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestIsInitialized.SubMessage sub_message = 1;</code>
-       */
-      public Builder mergeSubMessage(protobuf_unittest.UnittestProto.TestIsInitialized.SubMessage value) {
-        copyOnWrite();
-        instance.mergeSubMessage(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestIsInitialized.SubMessage sub_message = 1;</code>
-       */
-      public Builder clearSubMessage() {  copyOnWrite();
-        instance.clearSubMessage();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestIsInitialized)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestIsInitialized();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "subMessage_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0001\u0001\u1409\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestIsInitialized> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestIsInitialized.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestIsInitialized>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestIsInitialized)
-    private static final protobuf_unittest.UnittestProto.TestIsInitialized DEFAULT_INSTANCE;
-    static {
-      TestIsInitialized defaultInstance = new TestIsInitialized();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestIsInitialized.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestIsInitialized getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestIsInitialized> PARSER;
-
-    public static com.google.protobuf.Parser<TestIsInitialized> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestDupFieldNumberOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestDupFieldNumber)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <pre>
-     * NO_PROTO1
-     * </pre>
-     *
-     * <code>optional int32 a = 1;</code>
-     * @return Whether the a field is set.
-     */
-    boolean hasA();
-    /**
-     * <pre>
-     * NO_PROTO1
-     * </pre>
-     *
-     * <code>optional int32 a = 1;</code>
-     * @return The a.
-     */
-    int getA();
-
-    /**
-     * <code>optional group Foo = 2 { ... }</code>
-     * @return Whether the foo field is set.
-     */
-    boolean hasFoo();
-    /**
-     * <code>optional group Foo = 2 { ... }</code>
-     * @return The foo.
-     */
-    protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo getFoo();
-
-    /**
-     * <code>optional group Bar = 3 { ... }</code>
-     * @return Whether the bar field is set.
-     */
-    boolean hasBar();
-    /**
-     * <code>optional group Bar = 3 { ... }</code>
-     * @return The bar.
-     */
-    protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar getBar();
-  }
-  /**
-   * <pre>
-   * Test that groups have disjoint field numbers from their siblings and
-   * parents.  This is NOT possible in proto1; only google.protobuf.  When attempting
-   * to compile with proto1, this will emit an error; so we only include it
-   * in protobuf_unittest_proto.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestDupFieldNumber}
-   */
-  public  static final class TestDupFieldNumber extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestDupFieldNumber, TestDupFieldNumber.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestDupFieldNumber)
-      TestDupFieldNumberOrBuilder {
-    private TestDupFieldNumber() {
-    }
-    public interface FooOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestDupFieldNumber.Foo)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int32 a = 1;</code>
-       * @return Whether the a field is set.
-       */
-      boolean hasA();
-      /**
-       * <code>optional int32 a = 1;</code>
-       * @return The a.
-       */
-      int getA();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestDupFieldNumber.Foo}
-     */
-    public  static final class Foo extends
-        com.google.protobuf.GeneratedMessageLite<
-            Foo, Foo.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestDupFieldNumber.Foo)
-        FooOrBuilder {
-      private Foo() {
-      }
-      private int bitField0_;
-      public static final int A_FIELD_NUMBER = 1;
-      private int a_;
-      /**
-       * <code>optional int32 a = 1;</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int32 a = 1;</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public int getA() {
-        return a_;
-      }
-      /**
-       * <code>optional int32 a = 1;</code>
-       * @param value The a to set.
-       */
-      private void setA(int value) {
-        bitField0_ |= 0x00000001;
-        a_ = value;
-      }
-      /**
-       * <code>optional int32 a = 1;</code>
-       */
-      private void clearA() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        a_ = 0;
-      }
-
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestDupFieldNumber.Foo}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestDupFieldNumber.Foo)
-          protobuf_unittest.UnittestProto.TestDupFieldNumber.FooOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int32 a = 1;</code>
-         * @return Whether the a field is set.
-         */
-        @java.lang.Override
-        public boolean hasA() {
-          return instance.hasA();
-        }
-        /**
-         * <code>optional int32 a = 1;</code>
-         * @return The a.
-         */
-        @java.lang.Override
-        public int getA() {
-          return instance.getA();
-        }
-        /**
-         * <code>optional int32 a = 1;</code>
-         * @param value The a to set.
-         * @return This builder for chaining.
-         */
-        public Builder setA(int value) {
-          copyOnWrite();
-          instance.setA(value);
-          return this;
-        }
-        /**
-         * <code>optional int32 a = 1;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearA() {
-          copyOnWrite();
-          instance.clearA();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestDupFieldNumber.Foo)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "a_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1004\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestDupFieldNumber.Foo)
-      private static final protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo DEFAULT_INSTANCE;
-      static {
-        Foo defaultInstance = new Foo();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          Foo.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<Foo> PARSER;
-
-      public static com.google.protobuf.Parser<Foo> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    public interface BarOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestDupFieldNumber.Bar)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int32 a = 1;</code>
-       * @return Whether the a field is set.
-       */
-      boolean hasA();
-      /**
-       * <code>optional int32 a = 1;</code>
-       * @return The a.
-       */
-      int getA();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestDupFieldNumber.Bar}
-     */
-    public  static final class Bar extends
-        com.google.protobuf.GeneratedMessageLite<
-            Bar, Bar.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestDupFieldNumber.Bar)
-        BarOrBuilder {
-      private Bar() {
-      }
-      private int bitField0_;
-      public static final int A_FIELD_NUMBER = 1;
-      private int a_;
-      /**
-       * <code>optional int32 a = 1;</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int32 a = 1;</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public int getA() {
-        return a_;
-      }
-      /**
-       * <code>optional int32 a = 1;</code>
-       * @param value The a to set.
-       */
-      private void setA(int value) {
-        bitField0_ |= 0x00000001;
-        a_ = value;
-      }
-      /**
-       * <code>optional int32 a = 1;</code>
-       */
-      private void clearA() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        a_ = 0;
-      }
-
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestDupFieldNumber.Bar}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestDupFieldNumber.Bar)
-          protobuf_unittest.UnittestProto.TestDupFieldNumber.BarOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int32 a = 1;</code>
-         * @return Whether the a field is set.
-         */
-        @java.lang.Override
-        public boolean hasA() {
-          return instance.hasA();
-        }
-        /**
-         * <code>optional int32 a = 1;</code>
-         * @return The a.
-         */
-        @java.lang.Override
-        public int getA() {
-          return instance.getA();
-        }
-        /**
-         * <code>optional int32 a = 1;</code>
-         * @param value The a to set.
-         * @return This builder for chaining.
-         */
-        public Builder setA(int value) {
-          copyOnWrite();
-          instance.setA(value);
-          return this;
-        }
-        /**
-         * <code>optional int32 a = 1;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearA() {
-          copyOnWrite();
-          instance.clearA();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestDupFieldNumber.Bar)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "a_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1004\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestDupFieldNumber.Bar)
-      private static final protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar DEFAULT_INSTANCE;
-      static {
-        Bar defaultInstance = new Bar();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          Bar.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<Bar> PARSER;
-
-      public static com.google.protobuf.Parser<Bar> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int bitField0_;
-    public static final int A_FIELD_NUMBER = 1;
-    private int a_;
-    /**
-     * <pre>
-     * NO_PROTO1
-     * </pre>
-     *
-     * <code>optional int32 a = 1;</code>
-     * @return Whether the a field is set.
-     */
-    @java.lang.Override
-    public boolean hasA() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <pre>
-     * NO_PROTO1
-     * </pre>
-     *
-     * <code>optional int32 a = 1;</code>
-     * @return The a.
-     */
-    @java.lang.Override
-    public int getA() {
-      return a_;
-    }
-    /**
-     * <pre>
-     * NO_PROTO1
-     * </pre>
-     *
-     * <code>optional int32 a = 1;</code>
-     * @param value The a to set.
-     */
-    private void setA(int value) {
-      bitField0_ |= 0x00000001;
-      a_ = value;
-    }
-    /**
-     * <pre>
-     * NO_PROTO1
-     * </pre>
-     *
-     * <code>optional int32 a = 1;</code>
-     */
-    private void clearA() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      a_ = 0;
-    }
-
-    public static final int FOO_FIELD_NUMBER = 2;
-    private protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo foo_;
-    /**
-     * <code>optional group Foo = 2 { ... }</code>
-     */
-    @java.lang.Override
-    public boolean hasFoo() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional group Foo = 2 { ... }</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo getFoo() {
-      return foo_ == null ? protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo.getDefaultInstance() : foo_;
-    }
-    /**
-     * <code>optional group Foo = 2 { ... }</code>
-     */
-    private void setFoo(protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo value) {
-      value.getClass();
-  foo_ = value;
-      bitField0_ |= 0x00000002;
-      }
-    /**
-     * <code>optional group Foo = 2 { ... }</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeFoo(protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo value) {
-      value.getClass();
-  if (foo_ != null &&
-          foo_ != protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo.getDefaultInstance()) {
-        foo_ =
-          protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo.newBuilder(foo_).mergeFrom(value).buildPartial();
-      } else {
-        foo_ = value;
-      }
-      bitField0_ |= 0x00000002;
-    }
-    /**
-     * <code>optional group Foo = 2 { ... }</code>
-     */
-    private void clearFoo() {  foo_ = null;
-      bitField0_ = (bitField0_ & ~0x00000002);
-    }
-
-    public static final int BAR_FIELD_NUMBER = 3;
-    private protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar bar_;
-    /**
-     * <code>optional group Bar = 3 { ... }</code>
-     */
-    @java.lang.Override
-    public boolean hasBar() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional group Bar = 3 { ... }</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar getBar() {
-      return bar_ == null ? protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar.getDefaultInstance() : bar_;
-    }
-    /**
-     * <code>optional group Bar = 3 { ... }</code>
-     */
-    private void setBar(protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar value) {
-      value.getClass();
-  bar_ = value;
-      bitField0_ |= 0x00000004;
-      }
-    /**
-     * <code>optional group Bar = 3 { ... }</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeBar(protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar value) {
-      value.getClass();
-  if (bar_ != null &&
-          bar_ != protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar.getDefaultInstance()) {
-        bar_ =
-          protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar.newBuilder(bar_).mergeFrom(value).buildPartial();
-      } else {
-        bar_ = value;
-      }
-      bitField0_ |= 0x00000004;
-    }
-    /**
-     * <code>optional group Bar = 3 { ... }</code>
-     */
-    private void clearBar() {  bar_ = null;
-      bitField0_ = (bitField0_ & ~0x00000004);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestDupFieldNumber parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestDupFieldNumber parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDupFieldNumber parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestDupFieldNumber parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDupFieldNumber parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestDupFieldNumber parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDupFieldNumber parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestDupFieldNumber parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDupFieldNumber parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestDupFieldNumber parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDupFieldNumber parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestDupFieldNumber parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestDupFieldNumber prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Test that groups have disjoint field numbers from their siblings and
-     * parents.  This is NOT possible in proto1; only google.protobuf.  When attempting
-     * to compile with proto1, this will emit an error; so we only include it
-     * in protobuf_unittest_proto.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestDupFieldNumber}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestDupFieldNumber, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestDupFieldNumber)
-        protobuf_unittest.UnittestProto.TestDupFieldNumberOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestDupFieldNumber.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <pre>
-       * NO_PROTO1
-       * </pre>
-       *
-       * <code>optional int32 a = 1;</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return instance.hasA();
-      }
-      /**
-       * <pre>
-       * NO_PROTO1
-       * </pre>
-       *
-       * <code>optional int32 a = 1;</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public int getA() {
-        return instance.getA();
-      }
-      /**
-       * <pre>
-       * NO_PROTO1
-       * </pre>
-       *
-       * <code>optional int32 a = 1;</code>
-       * @param value The a to set.
-       * @return This builder for chaining.
-       */
-      public Builder setA(int value) {
-        copyOnWrite();
-        instance.setA(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * NO_PROTO1
-       * </pre>
-       *
-       * <code>optional int32 a = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearA() {
-        copyOnWrite();
-        instance.clearA();
-        return this;
-      }
-
-      /**
-       * <code>optional group Foo = 2 { ... }</code>
-       */
-      @java.lang.Override
-      public boolean hasFoo() {
-        return instance.hasFoo();
-      }
-      /**
-       * <code>optional group Foo = 2 { ... }</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo getFoo() {
-        return instance.getFoo();
-      }
-      /**
-       * <code>optional group Foo = 2 { ... }</code>
-       */
-      public Builder setFoo(protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo value) {
-        copyOnWrite();
-        instance.setFoo(value);
-        return this;
-        }
-      /**
-       * <code>optional group Foo = 2 { ... }</code>
-       */
-      public Builder setFoo(
-          protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo.Builder builderForValue) {
-        copyOnWrite();
-        instance.setFoo(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional group Foo = 2 { ... }</code>
-       */
-      public Builder mergeFoo(protobuf_unittest.UnittestProto.TestDupFieldNumber.Foo value) {
-        copyOnWrite();
-        instance.mergeFoo(value);
-        return this;
-      }
-      /**
-       * <code>optional group Foo = 2 { ... }</code>
-       */
-      public Builder clearFoo() {  copyOnWrite();
-        instance.clearFoo();
-        return this;
-      }
-
-      /**
-       * <code>optional group Bar = 3 { ... }</code>
-       */
-      @java.lang.Override
-      public boolean hasBar() {
-        return instance.hasBar();
-      }
-      /**
-       * <code>optional group Bar = 3 { ... }</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar getBar() {
-        return instance.getBar();
-      }
-      /**
-       * <code>optional group Bar = 3 { ... }</code>
-       */
-      public Builder setBar(protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar value) {
-        copyOnWrite();
-        instance.setBar(value);
-        return this;
-        }
-      /**
-       * <code>optional group Bar = 3 { ... }</code>
-       */
-      public Builder setBar(
-          protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar.Builder builderForValue) {
-        copyOnWrite();
-        instance.setBar(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional group Bar = 3 { ... }</code>
-       */
-      public Builder mergeBar(protobuf_unittest.UnittestProto.TestDupFieldNumber.Bar value) {
-        copyOnWrite();
-        instance.mergeBar(value);
-        return this;
-      }
-      /**
-       * <code>optional group Bar = 3 { ... }</code>
-       */
-      public Builder clearBar() {  copyOnWrite();
-        instance.clearBar();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestDupFieldNumber)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestDupFieldNumber();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "a_",
-              "foo_",
-              "bar_",
-            };
-            java.lang.String info =
-                "\u0001\u0003\u0000\u0001\u0001\u0003\u0003\u0000\u0000\u0000\u0001\u1004\u0000\u0002" +
-                "\u1011\u0001\u0003\u1011\u0002";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestDupFieldNumber> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestDupFieldNumber.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestDupFieldNumber>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestDupFieldNumber)
-    private static final protobuf_unittest.UnittestProto.TestDupFieldNumber DEFAULT_INSTANCE;
-    static {
-      TestDupFieldNumber defaultInstance = new TestDupFieldNumber();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestDupFieldNumber.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestDupFieldNumber getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestDupFieldNumber> PARSER;
-
-    public static com.google.protobuf.Parser<TestDupFieldNumber> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestEagerMessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestEagerMessage)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = false];</code>
-     * @return Whether the subMessage field is set.
-     */
-    boolean hasSubMessage();
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = false];</code>
-     * @return The subMessage.
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes getSubMessage();
-  }
-  /**
-   * <pre>
-   * Additional messages for testing lazy fields.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestEagerMessage}
-   */
-  public  static final class TestEagerMessage extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestEagerMessage, TestEagerMessage.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestEagerMessage)
-      TestEagerMessageOrBuilder {
-    private TestEagerMessage() {
-    }
-    private int bitField0_;
-    public static final int SUB_MESSAGE_FIELD_NUMBER = 1;
-    private protobuf_unittest.UnittestProto.TestAllTypes subMessage_;
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = false];</code>
-     */
-    @java.lang.Override
-    public boolean hasSubMessage() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = false];</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes getSubMessage() {
-      return subMessage_ == null ? protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance() : subMessage_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = false];</code>
-     */
-    private void setSubMessage(protobuf_unittest.UnittestProto.TestAllTypes value) {
-      value.getClass();
-  subMessage_ = value;
-      bitField0_ |= 0x00000001;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = false];</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeSubMessage(protobuf_unittest.UnittestProto.TestAllTypes value) {
-      value.getClass();
-  if (subMessage_ != null &&
-          subMessage_ != protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance()) {
-        subMessage_ =
-          protobuf_unittest.UnittestProto.TestAllTypes.newBuilder(subMessage_).mergeFrom(value).buildPartial();
-      } else {
-        subMessage_ = value;
-      }
-      bitField0_ |= 0x00000001;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = false];</code>
-     */
-    private void clearSubMessage() {  subMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x00000001);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestEagerMessage parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestEagerMessage parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestEagerMessage parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestEagerMessage parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestEagerMessage parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestEagerMessage parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestEagerMessage parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestEagerMessage parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestEagerMessage parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestEagerMessage parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestEagerMessage parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestEagerMessage parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestEagerMessage prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Additional messages for testing lazy fields.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestEagerMessage}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestEagerMessage, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestEagerMessage)
-        protobuf_unittest.UnittestProto.TestEagerMessageOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestEagerMessage.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = false];</code>
-       */
-      @java.lang.Override
-      public boolean hasSubMessage() {
-        return instance.hasSubMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = false];</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes getSubMessage() {
-        return instance.getSubMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = false];</code>
-       */
-      public Builder setSubMessage(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        copyOnWrite();
-        instance.setSubMessage(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = false];</code>
-       */
-      public Builder setSubMessage(
-          protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-        copyOnWrite();
-        instance.setSubMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = false];</code>
-       */
-      public Builder mergeSubMessage(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        copyOnWrite();
-        instance.mergeSubMessage(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = false];</code>
-       */
-      public Builder clearSubMessage() {  copyOnWrite();
-        instance.clearSubMessage();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestEagerMessage)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestEagerMessage();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "subMessage_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1009\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestEagerMessage> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestEagerMessage.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestEagerMessage>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestEagerMessage)
-    private static final protobuf_unittest.UnittestProto.TestEagerMessage DEFAULT_INSTANCE;
-    static {
-      TestEagerMessage defaultInstance = new TestEagerMessage();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestEagerMessage.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestEagerMessage getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestEagerMessage> PARSER;
-
-    public static com.google.protobuf.Parser<TestEagerMessage> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestLazyMessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestLazyMessage)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = true];</code>
-     * @return Whether the subMessage field is set.
-     */
-    boolean hasSubMessage();
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = true];</code>
-     * @return The subMessage.
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes getSubMessage();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestLazyMessage}
-   */
-  public  static final class TestLazyMessage extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestLazyMessage, TestLazyMessage.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestLazyMessage)
-      TestLazyMessageOrBuilder {
-    private TestLazyMessage() {
-    }
-    private int bitField0_;
-    public static final int SUB_MESSAGE_FIELD_NUMBER = 1;
-    private protobuf_unittest.UnittestProto.TestAllTypes subMessage_;
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public boolean hasSubMessage() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes getSubMessage() {
-      return subMessage_ == null ? protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance() : subMessage_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = true];</code>
-     */
-    private void setSubMessage(protobuf_unittest.UnittestProto.TestAllTypes value) {
-      value.getClass();
-  subMessage_ = value;
-      bitField0_ |= 0x00000001;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = true];</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeSubMessage(protobuf_unittest.UnittestProto.TestAllTypes value) {
-      value.getClass();
-  if (subMessage_ != null &&
-          subMessage_ != protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance()) {
-        subMessage_ =
-          protobuf_unittest.UnittestProto.TestAllTypes.newBuilder(subMessage_).mergeFrom(value).buildPartial();
-      } else {
-        subMessage_ = value;
-      }
-      bitField0_ |= 0x00000001;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = true];</code>
-     */
-    private void clearSubMessage() {  subMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x00000001);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestLazyMessage parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestLazyMessage parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestLazyMessage parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestLazyMessage parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestLazyMessage parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestLazyMessage parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestLazyMessage parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestLazyMessage parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestLazyMessage parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestLazyMessage parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestLazyMessage parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestLazyMessage parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestLazyMessage prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestLazyMessage}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestLazyMessage, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestLazyMessage)
-        protobuf_unittest.UnittestProto.TestLazyMessageOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestLazyMessage.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public boolean hasSubMessage() {
-        return instance.hasSubMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes getSubMessage() {
-        return instance.getSubMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = true];</code>
-       */
-      public Builder setSubMessage(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        copyOnWrite();
-        instance.setSubMessage(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = true];</code>
-       */
-      public Builder setSubMessage(
-          protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-        copyOnWrite();
-        instance.setSubMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = true];</code>
-       */
-      public Builder mergeSubMessage(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        copyOnWrite();
-        instance.mergeSubMessage(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes sub_message = 1 [lazy = true];</code>
-       */
-      public Builder clearSubMessage() {  copyOnWrite();
-        instance.clearSubMessage();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestLazyMessage)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestLazyMessage();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "subMessage_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1009\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestLazyMessage> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestLazyMessage.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestLazyMessage>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestLazyMessage)
-    private static final protobuf_unittest.UnittestProto.TestLazyMessage DEFAULT_INSTANCE;
-    static {
-      TestLazyMessage defaultInstance = new TestLazyMessage();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestLazyMessage.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestLazyMessage getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestLazyMessage> PARSER;
-
-    public static com.google.protobuf.Parser<TestLazyMessage> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestNestedMessageHasBitsOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestNestedMessageHasBits)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional .protobuf_unittest.TestNestedMessageHasBits.NestedMessage optional_nested_message = 1;</code>
-     * @return Whether the optionalNestedMessage field is set.
-     */
-    boolean hasOptionalNestedMessage();
-    /**
-     * <code>optional .protobuf_unittest.TestNestedMessageHasBits.NestedMessage optional_nested_message = 1;</code>
-     * @return The optionalNestedMessage.
-     */
-    protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage getOptionalNestedMessage();
-  }
-  /**
-   * <pre>
-   * Needed for a Python test.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestNestedMessageHasBits}
-   */
-  public  static final class TestNestedMessageHasBits extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestNestedMessageHasBits, TestNestedMessageHasBits.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestNestedMessageHasBits)
-      TestNestedMessageHasBitsOrBuilder {
-    private TestNestedMessageHasBits() {
-    }
-    public interface NestedMessageOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestNestedMessageHasBits.NestedMessage)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>repeated int32 nestedmessage_repeated_int32 = 1;</code>
-       * @return A list containing the nestedmessageRepeatedInt32.
-       */
-      java.util.List<java.lang.Integer> getNestedmessageRepeatedInt32List();
-      /**
-       * <code>repeated int32 nestedmessage_repeated_int32 = 1;</code>
-       * @return The count of nestedmessageRepeatedInt32.
-       */
-      int getNestedmessageRepeatedInt32Count();
-      /**
-       * <code>repeated int32 nestedmessage_repeated_int32 = 1;</code>
-       * @param index The index of the element to return.
-       * @return The nestedmessageRepeatedInt32 at the given index.
-       */
-      int getNestedmessageRepeatedInt32(int index);
-
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-       */
-      java.util.List<protobuf_unittest.UnittestProto.ForeignMessage> 
-          getNestedmessageRepeatedForeignmessageList();
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-       */
-      protobuf_unittest.UnittestProto.ForeignMessage getNestedmessageRepeatedForeignmessage(int index);
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-       */
-      int getNestedmessageRepeatedForeignmessageCount();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestNestedMessageHasBits.NestedMessage}
-     */
-    public  static final class NestedMessage extends
-        com.google.protobuf.GeneratedMessageLite<
-            NestedMessage, NestedMessage.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestNestedMessageHasBits.NestedMessage)
-        NestedMessageOrBuilder {
-      private NestedMessage() {
-        nestedmessageRepeatedInt32_ = emptyIntList();
-        nestedmessageRepeatedForeignmessage_ = emptyProtobufList();
-      }
-      public static final int NESTEDMESSAGE_REPEATED_INT32_FIELD_NUMBER = 1;
-      private com.google.protobuf.Internal.IntList nestedmessageRepeatedInt32_;
-      /**
-       * <code>repeated int32 nestedmessage_repeated_int32 = 1;</code>
-       * @return A list containing the nestedmessageRepeatedInt32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getNestedmessageRepeatedInt32List() {
-        return nestedmessageRepeatedInt32_;
-      }
-      /**
-       * <code>repeated int32 nestedmessage_repeated_int32 = 1;</code>
-       * @return The count of nestedmessageRepeatedInt32.
-       */
-      @java.lang.Override
-      public int getNestedmessageRepeatedInt32Count() {
-        return nestedmessageRepeatedInt32_.size();
-      }
-      /**
-       * <code>repeated int32 nestedmessage_repeated_int32 = 1;</code>
-       * @param index The index of the element to return.
-       * @return The nestedmessageRepeatedInt32 at the given index.
-       */
-      @java.lang.Override
-      public int getNestedmessageRepeatedInt32(int index) {
-        return nestedmessageRepeatedInt32_.getInt(index);
-      }
-      private void ensureNestedmessageRepeatedInt32IsMutable() {
-        com.google.protobuf.Internal.IntList tmp = nestedmessageRepeatedInt32_;
-        if (!tmp.isModifiable()) {
-          nestedmessageRepeatedInt32_ =
-              com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-         }
-      }
-      /**
-       * <code>repeated int32 nestedmessage_repeated_int32 = 1;</code>
-       * @param index The index to set the value at.
-       * @param value The nestedmessageRepeatedInt32 to set.
-       */
-      private void setNestedmessageRepeatedInt32(
-          int index, int value) {
-        ensureNestedmessageRepeatedInt32IsMutable();
-        nestedmessageRepeatedInt32_.setInt(index, value);
-      }
-      /**
-       * <code>repeated int32 nestedmessage_repeated_int32 = 1;</code>
-       * @param value The nestedmessageRepeatedInt32 to add.
-       */
-      private void addNestedmessageRepeatedInt32(int value) {
-        ensureNestedmessageRepeatedInt32IsMutable();
-        nestedmessageRepeatedInt32_.addInt(value);
-      }
-      /**
-       * <code>repeated int32 nestedmessage_repeated_int32 = 1;</code>
-       * @param values The nestedmessageRepeatedInt32 to add.
-       */
-      private void addAllNestedmessageRepeatedInt32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        ensureNestedmessageRepeatedInt32IsMutable();
-        com.google.protobuf.AbstractMessageLite.addAll(
-            values, nestedmessageRepeatedInt32_);
-      }
-      /**
-       * <code>repeated int32 nestedmessage_repeated_int32 = 1;</code>
-       */
-      private void clearNestedmessageRepeatedInt32() {
-        nestedmessageRepeatedInt32_ = emptyIntList();
-      }
-
-      public static final int NESTEDMESSAGE_REPEATED_FOREIGNMESSAGE_FIELD_NUMBER = 2;
-      private com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.ForeignMessage> nestedmessageRepeatedForeignmessage_;
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.ForeignMessage> getNestedmessageRepeatedForeignmessageList() {
-        return nestedmessageRepeatedForeignmessage_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-       */
-      public java.util.List<? extends protobuf_unittest.UnittestProto.ForeignMessageOrBuilder> 
-          getNestedmessageRepeatedForeignmessageOrBuilderList() {
-        return nestedmessageRepeatedForeignmessage_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-       */
-      @java.lang.Override
-      public int getNestedmessageRepeatedForeignmessageCount() {
-        return nestedmessageRepeatedForeignmessage_.size();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.ForeignMessage getNestedmessageRepeatedForeignmessage(int index) {
-        return nestedmessageRepeatedForeignmessage_.get(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-       */
-      public protobuf_unittest.UnittestProto.ForeignMessageOrBuilder getNestedmessageRepeatedForeignmessageOrBuilder(
-          int index) {
-        return nestedmessageRepeatedForeignmessage_.get(index);
-      }
-      private void ensureNestedmessageRepeatedForeignmessageIsMutable() {
-        com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.ForeignMessage> tmp = nestedmessageRepeatedForeignmessage_;
-        if (!tmp.isModifiable()) {
-          nestedmessageRepeatedForeignmessage_ =
-              com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-         }
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-       */
-      private void setNestedmessageRepeatedForeignmessage(
-          int index, protobuf_unittest.UnittestProto.ForeignMessage value) {
-        value.getClass();
-  ensureNestedmessageRepeatedForeignmessageIsMutable();
-        nestedmessageRepeatedForeignmessage_.set(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-       */
-      private void addNestedmessageRepeatedForeignmessage(protobuf_unittest.UnittestProto.ForeignMessage value) {
-        value.getClass();
-  ensureNestedmessageRepeatedForeignmessageIsMutable();
-        nestedmessageRepeatedForeignmessage_.add(value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-       */
-      private void addNestedmessageRepeatedForeignmessage(
-          int index, protobuf_unittest.UnittestProto.ForeignMessage value) {
-        value.getClass();
-  ensureNestedmessageRepeatedForeignmessageIsMutable();
-        nestedmessageRepeatedForeignmessage_.add(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-       */
-      private void addAllNestedmessageRepeatedForeignmessage(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.ForeignMessage> values) {
-        ensureNestedmessageRepeatedForeignmessageIsMutable();
-        com.google.protobuf.AbstractMessageLite.addAll(
-            values, nestedmessageRepeatedForeignmessage_);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-       */
-      private void clearNestedmessageRepeatedForeignmessage() {
-        nestedmessageRepeatedForeignmessage_ = emptyProtobufList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-       */
-      private void removeNestedmessageRepeatedForeignmessage(int index) {
-        ensureNestedmessageRepeatedForeignmessageIsMutable();
-        nestedmessageRepeatedForeignmessage_.remove(index);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestNestedMessageHasBits.NestedMessage}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestNestedMessageHasBits.NestedMessage)
-          protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessageOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>repeated int32 nestedmessage_repeated_int32 = 1;</code>
-         * @return A list containing the nestedmessageRepeatedInt32.
-         */
-        @java.lang.Override
-        public java.util.List<java.lang.Integer>
-            getNestedmessageRepeatedInt32List() {
-          return java.util.Collections.unmodifiableList(
-              instance.getNestedmessageRepeatedInt32List());
-        }
-        /**
-         * <code>repeated int32 nestedmessage_repeated_int32 = 1;</code>
-         * @return The count of nestedmessageRepeatedInt32.
-         */
-        @java.lang.Override
-        public int getNestedmessageRepeatedInt32Count() {
-          return instance.getNestedmessageRepeatedInt32Count();
-        }
-        /**
-         * <code>repeated int32 nestedmessage_repeated_int32 = 1;</code>
-         * @param index The index of the element to return.
-         * @return The nestedmessageRepeatedInt32 at the given index.
-         */
-        @java.lang.Override
-        public int getNestedmessageRepeatedInt32(int index) {
-          return instance.getNestedmessageRepeatedInt32(index);
-        }
-        /**
-         * <code>repeated int32 nestedmessage_repeated_int32 = 1;</code>
-         * @param value The nestedmessageRepeatedInt32 to set.
-         * @return This builder for chaining.
-         */
-        public Builder setNestedmessageRepeatedInt32(
-            int index, int value) {
-          copyOnWrite();
-          instance.setNestedmessageRepeatedInt32(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated int32 nestedmessage_repeated_int32 = 1;</code>
-         * @param value The nestedmessageRepeatedInt32 to add.
-         * @return This builder for chaining.
-         */
-        public Builder addNestedmessageRepeatedInt32(int value) {
-          copyOnWrite();
-          instance.addNestedmessageRepeatedInt32(value);
-          return this;
-        }
-        /**
-         * <code>repeated int32 nestedmessage_repeated_int32 = 1;</code>
-         * @param values The nestedmessageRepeatedInt32 to add.
-         * @return This builder for chaining.
-         */
-        public Builder addAllNestedmessageRepeatedInt32(
-            java.lang.Iterable<? extends java.lang.Integer> values) {
-          copyOnWrite();
-          instance.addAllNestedmessageRepeatedInt32(values);
-          return this;
-        }
-        /**
-         * <code>repeated int32 nestedmessage_repeated_int32 = 1;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearNestedmessageRepeatedInt32() {
-          copyOnWrite();
-          instance.clearNestedmessageRepeatedInt32();
-          return this;
-        }
-
-        /**
-         * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-         */
-        @java.lang.Override
-        public java.util.List<protobuf_unittest.UnittestProto.ForeignMessage> getNestedmessageRepeatedForeignmessageList() {
-          return java.util.Collections.unmodifiableList(
-              instance.getNestedmessageRepeatedForeignmessageList());
-        }
-        /**
-         * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-         */
-        @java.lang.Override
-        public int getNestedmessageRepeatedForeignmessageCount() {
-          return instance.getNestedmessageRepeatedForeignmessageCount();
-        }/**
-         * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-         */
-        @java.lang.Override
-        public protobuf_unittest.UnittestProto.ForeignMessage getNestedmessageRepeatedForeignmessage(int index) {
-          return instance.getNestedmessageRepeatedForeignmessage(index);
-        }
-        /**
-         * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-         */
-        public Builder setNestedmessageRepeatedForeignmessage(
-            int index, protobuf_unittest.UnittestProto.ForeignMessage value) {
-          copyOnWrite();
-          instance.setNestedmessageRepeatedForeignmessage(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-         */
-        public Builder setNestedmessageRepeatedForeignmessage(
-            int index, protobuf_unittest.UnittestProto.ForeignMessage.Builder builderForValue) {
-          copyOnWrite();
-          instance.setNestedmessageRepeatedForeignmessage(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-         */
-        public Builder addNestedmessageRepeatedForeignmessage(protobuf_unittest.UnittestProto.ForeignMessage value) {
-          copyOnWrite();
-          instance.addNestedmessageRepeatedForeignmessage(value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-         */
-        public Builder addNestedmessageRepeatedForeignmessage(
-            int index, protobuf_unittest.UnittestProto.ForeignMessage value) {
-          copyOnWrite();
-          instance.addNestedmessageRepeatedForeignmessage(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-         */
-        public Builder addNestedmessageRepeatedForeignmessage(
-            protobuf_unittest.UnittestProto.ForeignMessage.Builder builderForValue) {
-          copyOnWrite();
-          instance.addNestedmessageRepeatedForeignmessage(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-         */
-        public Builder addNestedmessageRepeatedForeignmessage(
-            int index, protobuf_unittest.UnittestProto.ForeignMessage.Builder builderForValue) {
-          copyOnWrite();
-          instance.addNestedmessageRepeatedForeignmessage(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-         */
-        public Builder addAllNestedmessageRepeatedForeignmessage(
-            java.lang.Iterable<? extends protobuf_unittest.UnittestProto.ForeignMessage> values) {
-          copyOnWrite();
-          instance.addAllNestedmessageRepeatedForeignmessage(values);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-         */
-        public Builder clearNestedmessageRepeatedForeignmessage() {
-          copyOnWrite();
-          instance.clearNestedmessageRepeatedForeignmessage();
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.ForeignMessage nestedmessage_repeated_foreignmessage = 2;</code>
-         */
-        public Builder removeNestedmessageRepeatedForeignmessage(int index) {
-          copyOnWrite();
-          instance.removeNestedmessageRepeatedForeignmessage(index);
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestNestedMessageHasBits.NestedMessage)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "nestedmessageRepeatedInt32_",
-                "nestedmessageRepeatedForeignmessage_",
-                protobuf_unittest.UnittestProto.ForeignMessage.class,
-              };
-              java.lang.String info =
-                  "\u0001\u0002\u0000\u0000\u0001\u0002\u0002\u0000\u0002\u0000\u0001\u0016\u0002\u001b" +
-                  "";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestNestedMessageHasBits.NestedMessage)
-      private static final protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage DEFAULT_INSTANCE;
-      static {
-        NestedMessage defaultInstance = new NestedMessage();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          NestedMessage.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<NestedMessage> PARSER;
-
-      public static com.google.protobuf.Parser<NestedMessage> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int bitField0_;
-    public static final int OPTIONAL_NESTED_MESSAGE_FIELD_NUMBER = 1;
-    private protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage optionalNestedMessage_;
-    /**
-     * <code>optional .protobuf_unittest.TestNestedMessageHasBits.NestedMessage optional_nested_message = 1;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalNestedMessage() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestNestedMessageHasBits.NestedMessage optional_nested_message = 1;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage getOptionalNestedMessage() {
-      return optionalNestedMessage_ == null ? protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage.getDefaultInstance() : optionalNestedMessage_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestNestedMessageHasBits.NestedMessage optional_nested_message = 1;</code>
-     */
-    private void setOptionalNestedMessage(protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage value) {
-      value.getClass();
-  optionalNestedMessage_ = value;
-      bitField0_ |= 0x00000001;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestNestedMessageHasBits.NestedMessage optional_nested_message = 1;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalNestedMessage(protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage value) {
-      value.getClass();
-  if (optionalNestedMessage_ != null &&
-          optionalNestedMessage_ != protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage.getDefaultInstance()) {
-        optionalNestedMessage_ =
-          protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage.newBuilder(optionalNestedMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalNestedMessage_ = value;
-      }
-      bitField0_ |= 0x00000001;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestNestedMessageHasBits.NestedMessage optional_nested_message = 1;</code>
-     */
-    private void clearOptionalNestedMessage() {  optionalNestedMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x00000001);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestNestedMessageHasBits prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Needed for a Python test.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestNestedMessageHasBits}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestNestedMessageHasBits, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestNestedMessageHasBits)
-        protobuf_unittest.UnittestProto.TestNestedMessageHasBitsOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestNestedMessageHasBits.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional .protobuf_unittest.TestNestedMessageHasBits.NestedMessage optional_nested_message = 1;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalNestedMessage() {
-        return instance.hasOptionalNestedMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestNestedMessageHasBits.NestedMessage optional_nested_message = 1;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage getOptionalNestedMessage() {
-        return instance.getOptionalNestedMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestNestedMessageHasBits.NestedMessage optional_nested_message = 1;</code>
-       */
-      public Builder setOptionalNestedMessage(protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage value) {
-        copyOnWrite();
-        instance.setOptionalNestedMessage(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestNestedMessageHasBits.NestedMessage optional_nested_message = 1;</code>
-       */
-      public Builder setOptionalNestedMessage(
-          protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalNestedMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestNestedMessageHasBits.NestedMessage optional_nested_message = 1;</code>
-       */
-      public Builder mergeOptionalNestedMessage(protobuf_unittest.UnittestProto.TestNestedMessageHasBits.NestedMessage value) {
-        copyOnWrite();
-        instance.mergeOptionalNestedMessage(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestNestedMessageHasBits.NestedMessage optional_nested_message = 1;</code>
-       */
-      public Builder clearOptionalNestedMessage() {  copyOnWrite();
-        instance.clearOptionalNestedMessage();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestNestedMessageHasBits)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestNestedMessageHasBits();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "optionalNestedMessage_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1009\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestNestedMessageHasBits> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestNestedMessageHasBits.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestNestedMessageHasBits>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestNestedMessageHasBits)
-    private static final protobuf_unittest.UnittestProto.TestNestedMessageHasBits DEFAULT_INSTANCE;
-    static {
-      TestNestedMessageHasBits defaultInstance = new TestNestedMessageHasBits();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestNestedMessageHasBits.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestNestedMessageHasBits getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestNestedMessageHasBits> PARSER;
-
-    public static com.google.protobuf.Parser<TestNestedMessageHasBits> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestCamelCaseFieldNamesOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestCamelCaseFieldNames)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional int32 PrimitiveField = 1;</code>
-     * @return Whether the primitiveField field is set.
-     */
-    boolean hasPrimitiveField();
-    /**
-     * <code>optional int32 PrimitiveField = 1;</code>
-     * @return The primitiveField.
-     */
-    int getPrimitiveField();
-
-    /**
-     * <code>optional string StringField = 2;</code>
-     * @return Whether the stringField field is set.
-     */
-    boolean hasStringField();
-    /**
-     * <code>optional string StringField = 2;</code>
-     * @return The stringField.
-     */
-    java.lang.String getStringField();
-    /**
-     * <code>optional string StringField = 2;</code>
-     * @return The bytes for stringField.
-     */
-    com.google.protobuf.ByteString
-        getStringFieldBytes();
-
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum EnumField = 3;</code>
-     * @return Whether the enumField field is set.
-     */
-    boolean hasEnumField();
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum EnumField = 3;</code>
-     * @return The enumField.
-     */
-    protobuf_unittest.UnittestProto.ForeignEnum getEnumField();
-
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage MessageField = 4;</code>
-     * @return Whether the messageField field is set.
-     */
-    boolean hasMessageField();
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage MessageField = 4;</code>
-     * @return The messageField.
-     */
-    protobuf_unittest.UnittestProto.ForeignMessage getMessageField();
-
-    /**
-     * <code>optional string StringPieceField = 5 [ctype = STRING_PIECE];</code>
-     * @return Whether the stringPieceField field is set.
-     */
-    boolean hasStringPieceField();
-    /**
-     * <code>optional string StringPieceField = 5 [ctype = STRING_PIECE];</code>
-     * @return The stringPieceField.
-     */
-    java.lang.String getStringPieceField();
-    /**
-     * <code>optional string StringPieceField = 5 [ctype = STRING_PIECE];</code>
-     * @return The bytes for stringPieceField.
-     */
-    com.google.protobuf.ByteString
-        getStringPieceFieldBytes();
-
-    /**
-     * <code>optional string CordField = 6 [ctype = CORD];</code>
-     * @return Whether the cordField field is set.
-     */
-    boolean hasCordField();
-    /**
-     * <code>optional string CordField = 6 [ctype = CORD];</code>
-     * @return The cordField.
-     */
-    java.lang.String getCordField();
-    /**
-     * <code>optional string CordField = 6 [ctype = CORD];</code>
-     * @return The bytes for cordField.
-     */
-    com.google.protobuf.ByteString
-        getCordFieldBytes();
-
-    /**
-     * <code>repeated int32 RepeatedPrimitiveField = 7;</code>
-     * @return A list containing the repeatedPrimitiveField.
-     */
-    java.util.List<java.lang.Integer> getRepeatedPrimitiveFieldList();
-    /**
-     * <code>repeated int32 RepeatedPrimitiveField = 7;</code>
-     * @return The count of repeatedPrimitiveField.
-     */
-    int getRepeatedPrimitiveFieldCount();
-    /**
-     * <code>repeated int32 RepeatedPrimitiveField = 7;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedPrimitiveField at the given index.
-     */
-    int getRepeatedPrimitiveField(int index);
-
-    /**
-     * <code>repeated string RepeatedStringField = 8;</code>
-     * @return A list containing the repeatedStringField.
-     */
-    java.util.List<java.lang.String>
-        getRepeatedStringFieldList();
-    /**
-     * <code>repeated string RepeatedStringField = 8;</code>
-     * @return The count of repeatedStringField.
-     */
-    int getRepeatedStringFieldCount();
-    /**
-     * <code>repeated string RepeatedStringField = 8;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedStringField at the given index.
-     */
-    java.lang.String getRepeatedStringField(int index);
-    /**
-     * <code>repeated string RepeatedStringField = 8;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedStringField at the given index.
-     */
-    com.google.protobuf.ByteString
-        getRepeatedStringFieldBytes(int index);
-
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum RepeatedEnumField = 9;</code>
-     * @return A list containing the repeatedEnumField.
-     */
-    java.util.List<protobuf_unittest.UnittestProto.ForeignEnum> getRepeatedEnumFieldList();
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum RepeatedEnumField = 9;</code>
-     * @return The count of repeatedEnumField.
-     */
-    int getRepeatedEnumFieldCount();
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum RepeatedEnumField = 9;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedEnumField at the given index.
-     */
-    protobuf_unittest.UnittestProto.ForeignEnum getRepeatedEnumField(int index);
-
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-     */
-    java.util.List<protobuf_unittest.UnittestProto.ForeignMessage> 
-        getRepeatedMessageFieldList();
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-     */
-    protobuf_unittest.UnittestProto.ForeignMessage getRepeatedMessageField(int index);
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-     */
-    int getRepeatedMessageFieldCount();
-
-    /**
-     * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-     * @return A list containing the repeatedStringPieceField.
-     */
-    java.util.List<java.lang.String>
-        getRepeatedStringPieceFieldList();
-    /**
-     * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-     * @return The count of repeatedStringPieceField.
-     */
-    int getRepeatedStringPieceFieldCount();
-    /**
-     * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedStringPieceField at the given index.
-     */
-    java.lang.String getRepeatedStringPieceField(int index);
-    /**
-     * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedStringPieceField at the given index.
-     */
-    com.google.protobuf.ByteString
-        getRepeatedStringPieceFieldBytes(int index);
-
-    /**
-     * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-     * @return A list containing the repeatedCordField.
-     */
-    java.util.List<java.lang.String>
-        getRepeatedCordFieldList();
-    /**
-     * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-     * @return The count of repeatedCordField.
-     */
-    int getRepeatedCordFieldCount();
-    /**
-     * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedCordField at the given index.
-     */
-    java.lang.String getRepeatedCordField(int index);
-    /**
-     * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedCordField at the given index.
-     */
-    com.google.protobuf.ByteString
-        getRepeatedCordFieldBytes(int index);
-  }
-  /**
-   * <pre>
-   * Test message with CamelCase field names.  This violates Protocol Buffer
-   * standard style.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestCamelCaseFieldNames}
-   */
-  public  static final class TestCamelCaseFieldNames extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestCamelCaseFieldNames, TestCamelCaseFieldNames.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestCamelCaseFieldNames)
-      TestCamelCaseFieldNamesOrBuilder {
-    private TestCamelCaseFieldNames() {
-      stringField_ = "";
-      enumField_ = 4;
-      stringPieceField_ = "";
-      cordField_ = "";
-      repeatedPrimitiveField_ = emptyIntList();
-      repeatedStringField_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      repeatedEnumField_ = emptyIntList();
-      repeatedMessageField_ = emptyProtobufList();
-      repeatedStringPieceField_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      repeatedCordField_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    private int bitField0_;
-    public static final int PRIMITIVEFIELD_FIELD_NUMBER = 1;
-    private int primitiveField_;
-    /**
-     * <code>optional int32 PrimitiveField = 1;</code>
-     * @return Whether the primitiveField field is set.
-     */
-    @java.lang.Override
-    public boolean hasPrimitiveField() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 PrimitiveField = 1;</code>
-     * @return The primitiveField.
-     */
-    @java.lang.Override
-    public int getPrimitiveField() {
-      return primitiveField_;
-    }
-    /**
-     * <code>optional int32 PrimitiveField = 1;</code>
-     * @param value The primitiveField to set.
-     */
-    private void setPrimitiveField(int value) {
-      bitField0_ |= 0x00000001;
-      primitiveField_ = value;
-    }
-    /**
-     * <code>optional int32 PrimitiveField = 1;</code>
-     */
-    private void clearPrimitiveField() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      primitiveField_ = 0;
-    }
-
-    public static final int STRINGFIELD_FIELD_NUMBER = 2;
-    private java.lang.String stringField_;
-    /**
-     * <code>optional string StringField = 2;</code>
-     * @return Whether the stringField field is set.
-     */
-    @java.lang.Override
-    public boolean hasStringField() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional string StringField = 2;</code>
-     * @return The stringField.
-     */
-    @java.lang.Override
-    public java.lang.String getStringField() {
-      return stringField_;
-    }
-    /**
-     * <code>optional string StringField = 2;</code>
-     * @return The bytes for stringField.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getStringFieldBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(stringField_);
-    }
-    /**
-     * <code>optional string StringField = 2;</code>
-     * @param value The stringField to set.
-     */
-    private void setStringField(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00000002;
-      stringField_ = value;
-    }
-    /**
-     * <code>optional string StringField = 2;</code>
-     */
-    private void clearStringField() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      stringField_ = getDefaultInstance().getStringField();
-    }
-    /**
-     * <code>optional string StringField = 2;</code>
-     * @param value The bytes for stringField to set.
-     */
-    private void setStringFieldBytes(
-        com.google.protobuf.ByteString value) {
-      stringField_ = value.toStringUtf8();
-      bitField0_ |= 0x00000002;
-    }
-
-    public static final int ENUMFIELD_FIELD_NUMBER = 3;
-    private int enumField_;
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum EnumField = 3;</code>
-     * @return Whether the enumField field is set.
-     */
-    @java.lang.Override
-    public boolean hasEnumField() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum EnumField = 3;</code>
-     * @return The enumField.
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.ForeignEnum getEnumField() {
-      protobuf_unittest.UnittestProto.ForeignEnum result = protobuf_unittest.UnittestProto.ForeignEnum.forNumber(enumField_);
-      return result == null ? protobuf_unittest.UnittestProto.ForeignEnum.FOREIGN_FOO : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum EnumField = 3;</code>
-     * @param value The enumField to set.
-     */
-    private void setEnumField(protobuf_unittest.UnittestProto.ForeignEnum value) {
-      enumField_ = value.getNumber();
-      bitField0_ |= 0x00000004;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum EnumField = 3;</code>
-     */
-    private void clearEnumField() {
-      bitField0_ = (bitField0_ & ~0x00000004);
-      enumField_ = 4;
-    }
-
-    public static final int MESSAGEFIELD_FIELD_NUMBER = 4;
-    private protobuf_unittest.UnittestProto.ForeignMessage messageField_;
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage MessageField = 4;</code>
-     */
-    @java.lang.Override
-    public boolean hasMessageField() {
-      return ((bitField0_ & 0x00000008) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage MessageField = 4;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.ForeignMessage getMessageField() {
-      return messageField_ == null ? protobuf_unittest.UnittestProto.ForeignMessage.getDefaultInstance() : messageField_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage MessageField = 4;</code>
-     */
-    private void setMessageField(protobuf_unittest.UnittestProto.ForeignMessage value) {
-      value.getClass();
-  messageField_ = value;
-      bitField0_ |= 0x00000008;
-      }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage MessageField = 4;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeMessageField(protobuf_unittest.UnittestProto.ForeignMessage value) {
-      value.getClass();
-  if (messageField_ != null &&
-          messageField_ != protobuf_unittest.UnittestProto.ForeignMessage.getDefaultInstance()) {
-        messageField_ =
-          protobuf_unittest.UnittestProto.ForeignMessage.newBuilder(messageField_).mergeFrom(value).buildPartial();
-      } else {
-        messageField_ = value;
-      }
-      bitField0_ |= 0x00000008;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage MessageField = 4;</code>
-     */
-    private void clearMessageField() {  messageField_ = null;
-      bitField0_ = (bitField0_ & ~0x00000008);
-    }
-
-    public static final int STRINGPIECEFIELD_FIELD_NUMBER = 5;
-    private java.lang.String stringPieceField_;
-    /**
-     * <code>optional string StringPieceField = 5 [ctype = STRING_PIECE];</code>
-     * @return Whether the stringPieceField field is set.
-     */
-    @java.lang.Override
-    public boolean hasStringPieceField() {
-      return ((bitField0_ & 0x00000010) != 0);
-    }
-    /**
-     * <code>optional string StringPieceField = 5 [ctype = STRING_PIECE];</code>
-     * @return The stringPieceField.
-     */
-    @java.lang.Override
-    public java.lang.String getStringPieceField() {
-      return stringPieceField_;
-    }
-    /**
-     * <code>optional string StringPieceField = 5 [ctype = STRING_PIECE];</code>
-     * @return The bytes for stringPieceField.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getStringPieceFieldBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(stringPieceField_);
-    }
-    /**
-     * <code>optional string StringPieceField = 5 [ctype = STRING_PIECE];</code>
-     * @param value The stringPieceField to set.
-     */
-    private void setStringPieceField(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00000010;
-      stringPieceField_ = value;
-    }
-    /**
-     * <code>optional string StringPieceField = 5 [ctype = STRING_PIECE];</code>
-     */
-    private void clearStringPieceField() {
-      bitField0_ = (bitField0_ & ~0x00000010);
-      stringPieceField_ = getDefaultInstance().getStringPieceField();
-    }
-    /**
-     * <code>optional string StringPieceField = 5 [ctype = STRING_PIECE];</code>
-     * @param value The bytes for stringPieceField to set.
-     */
-    private void setStringPieceFieldBytes(
-        com.google.protobuf.ByteString value) {
-      stringPieceField_ = value.toStringUtf8();
-      bitField0_ |= 0x00000010;
-    }
-
-    public static final int CORDFIELD_FIELD_NUMBER = 6;
-    private java.lang.String cordField_;
-    /**
-     * <code>optional string CordField = 6 [ctype = CORD];</code>
-     * @return Whether the cordField field is set.
-     */
-    @java.lang.Override
-    public boolean hasCordField() {
-      return ((bitField0_ & 0x00000020) != 0);
-    }
-    /**
-     * <code>optional string CordField = 6 [ctype = CORD];</code>
-     * @return The cordField.
-     */
-    @java.lang.Override
-    public java.lang.String getCordField() {
-      return cordField_;
-    }
-    /**
-     * <code>optional string CordField = 6 [ctype = CORD];</code>
-     * @return The bytes for cordField.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getCordFieldBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(cordField_);
-    }
-    /**
-     * <code>optional string CordField = 6 [ctype = CORD];</code>
-     * @param value The cordField to set.
-     */
-    private void setCordField(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00000020;
-      cordField_ = value;
-    }
-    /**
-     * <code>optional string CordField = 6 [ctype = CORD];</code>
-     */
-    private void clearCordField() {
-      bitField0_ = (bitField0_ & ~0x00000020);
-      cordField_ = getDefaultInstance().getCordField();
-    }
-    /**
-     * <code>optional string CordField = 6 [ctype = CORD];</code>
-     * @param value The bytes for cordField to set.
-     */
-    private void setCordFieldBytes(
-        com.google.protobuf.ByteString value) {
-      cordField_ = value.toStringUtf8();
-      bitField0_ |= 0x00000020;
-    }
-
-    public static final int REPEATEDPRIMITIVEFIELD_FIELD_NUMBER = 7;
-    private com.google.protobuf.Internal.IntList repeatedPrimitiveField_;
-    /**
-     * <code>repeated int32 RepeatedPrimitiveField = 7;</code>
-     * @return A list containing the repeatedPrimitiveField.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedPrimitiveFieldList() {
-      return repeatedPrimitiveField_;
-    }
-    /**
-     * <code>repeated int32 RepeatedPrimitiveField = 7;</code>
-     * @return The count of repeatedPrimitiveField.
-     */
-    @java.lang.Override
-    public int getRepeatedPrimitiveFieldCount() {
-      return repeatedPrimitiveField_.size();
-    }
-    /**
-     * <code>repeated int32 RepeatedPrimitiveField = 7;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedPrimitiveField at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedPrimitiveField(int index) {
-      return repeatedPrimitiveField_.getInt(index);
-    }
-    private void ensureRepeatedPrimitiveFieldIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedPrimitiveField_;
-      if (!tmp.isModifiable()) {
-        repeatedPrimitiveField_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int32 RepeatedPrimitiveField = 7;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedPrimitiveField to set.
-     */
-    private void setRepeatedPrimitiveField(
-        int index, int value) {
-      ensureRepeatedPrimitiveFieldIsMutable();
-      repeatedPrimitiveField_.setInt(index, value);
-    }
-    /**
-     * <code>repeated int32 RepeatedPrimitiveField = 7;</code>
-     * @param value The repeatedPrimitiveField to add.
-     */
-    private void addRepeatedPrimitiveField(int value) {
-      ensureRepeatedPrimitiveFieldIsMutable();
-      repeatedPrimitiveField_.addInt(value);
-    }
-    /**
-     * <code>repeated int32 RepeatedPrimitiveField = 7;</code>
-     * @param values The repeatedPrimitiveField to add.
-     */
-    private void addAllRepeatedPrimitiveField(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedPrimitiveFieldIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedPrimitiveField_);
-    }
-    /**
-     * <code>repeated int32 RepeatedPrimitiveField = 7;</code>
-     */
-    private void clearRepeatedPrimitiveField() {
-      repeatedPrimitiveField_ = emptyIntList();
-    }
-
-    public static final int REPEATEDSTRINGFIELD_FIELD_NUMBER = 8;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> repeatedStringField_;
-    /**
-     * <code>repeated string RepeatedStringField = 8;</code>
-     * @return A list containing the repeatedStringField.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getRepeatedStringFieldList() {
-      return repeatedStringField_;
-    }
-    /**
-     * <code>repeated string RepeatedStringField = 8;</code>
-     * @return The count of repeatedStringField.
-     */
-    @java.lang.Override
-    public int getRepeatedStringFieldCount() {
-      return repeatedStringField_.size();
-    }
-    /**
-     * <code>repeated string RepeatedStringField = 8;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedStringField at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getRepeatedStringField(int index) {
-      return repeatedStringField_.get(index);
-    }
-    /**
-     * <code>repeated string RepeatedStringField = 8;</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the repeatedStringField at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getRepeatedStringFieldBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          repeatedStringField_.get(index));
-    }
-    private void ensureRepeatedStringFieldIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          repeatedStringField_;  if (!tmp.isModifiable()) {
-        repeatedStringField_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string RepeatedStringField = 8;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedStringField to set.
-     */
-    private void setRepeatedStringField(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureRepeatedStringFieldIsMutable();
-      repeatedStringField_.set(index, value);
-    }
-    /**
-     * <code>repeated string RepeatedStringField = 8;</code>
-     * @param value The repeatedStringField to add.
-     */
-    private void addRepeatedStringField(
-        java.lang.String value) {
-      value.getClass();
-  ensureRepeatedStringFieldIsMutable();
-      repeatedStringField_.add(value);
-    }
-    /**
-     * <code>repeated string RepeatedStringField = 8;</code>
-     * @param values The repeatedStringField to add.
-     */
-    private void addAllRepeatedStringField(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureRepeatedStringFieldIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedStringField_);
-    }
-    /**
-     * <code>repeated string RepeatedStringField = 8;</code>
-     */
-    private void clearRepeatedStringField() {
-      repeatedStringField_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string RepeatedStringField = 8;</code>
-     * @param value The bytes of the repeatedStringField to add.
-     */
-    private void addRepeatedStringFieldBytes(
-        com.google.protobuf.ByteString value) {
-      ensureRepeatedStringFieldIsMutable();
-      repeatedStringField_.add(value.toStringUtf8());
-    }
-
-    public static final int REPEATEDENUMFIELD_FIELD_NUMBER = 9;
-    private com.google.protobuf.Internal.IntList repeatedEnumField_;
-    private static final com.google.protobuf.Internal.ListAdapter.Converter<
-        java.lang.Integer, protobuf_unittest.UnittestProto.ForeignEnum> repeatedEnumField_converter_ =
-            new com.google.protobuf.Internal.ListAdapter.Converter<
-                java.lang.Integer, protobuf_unittest.UnittestProto.ForeignEnum>() {
-              @java.lang.Override
-              public protobuf_unittest.UnittestProto.ForeignEnum convert(java.lang.Integer from) {
-                protobuf_unittest.UnittestProto.ForeignEnum result = protobuf_unittest.UnittestProto.ForeignEnum.forNumber(from);
-                return result == null ? protobuf_unittest.UnittestProto.ForeignEnum.FOREIGN_FOO : result;
-              }
-            };
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum RepeatedEnumField = 9;</code>
-     * @return A list containing the repeatedEnumField.
-     */
-    @java.lang.Override
-    public java.util.List<protobuf_unittest.UnittestProto.ForeignEnum> getRepeatedEnumFieldList() {
-      return new com.google.protobuf.Internal.ListAdapter<
-          java.lang.Integer, protobuf_unittest.UnittestProto.ForeignEnum>(repeatedEnumField_, repeatedEnumField_converter_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum RepeatedEnumField = 9;</code>
-     * @return The count of repeatedEnumField.
-     */
-    @java.lang.Override
-    public int getRepeatedEnumFieldCount() {
-      return repeatedEnumField_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum RepeatedEnumField = 9;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedEnumField at the given index.
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.ForeignEnum getRepeatedEnumField(int index) {
-      return repeatedEnumField_converter_.convert(repeatedEnumField_.getInt(index));
-    }
-    private void ensureRepeatedEnumFieldIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedEnumField_;
-      if (!tmp.isModifiable()) {
-        repeatedEnumField_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum RepeatedEnumField = 9;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedEnumField to set.
-     */
-    private void setRepeatedEnumField(
-        int index, protobuf_unittest.UnittestProto.ForeignEnum value) {
-      value.getClass();
-  ensureRepeatedEnumFieldIsMutable();
-      repeatedEnumField_.setInt(index, value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum RepeatedEnumField = 9;</code>
-     * @param value The repeatedEnumField to add.
-     */
-    private void addRepeatedEnumField(protobuf_unittest.UnittestProto.ForeignEnum value) {
-      value.getClass();
-  ensureRepeatedEnumFieldIsMutable();
-      repeatedEnumField_.addInt(value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum RepeatedEnumField = 9;</code>
-     * @param values The repeatedEnumField to add.
-     */
-    private void addAllRepeatedEnumField(
-        java.lang.Iterable<? extends protobuf_unittest.UnittestProto.ForeignEnum> values) {
-      ensureRepeatedEnumFieldIsMutable();
-      for (protobuf_unittest.UnittestProto.ForeignEnum value : values) {
-        repeatedEnumField_.addInt(value.getNumber());
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum RepeatedEnumField = 9;</code>
-     */
-    private void clearRepeatedEnumField() {
-      repeatedEnumField_ = emptyIntList();
-    }
-
-    public static final int REPEATEDMESSAGEFIELD_FIELD_NUMBER = 10;
-    private com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.ForeignMessage> repeatedMessageField_;
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-     */
-    @java.lang.Override
-    public java.util.List<protobuf_unittest.UnittestProto.ForeignMessage> getRepeatedMessageFieldList() {
-      return repeatedMessageField_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-     */
-    public java.util.List<? extends protobuf_unittest.UnittestProto.ForeignMessageOrBuilder> 
-        getRepeatedMessageFieldOrBuilderList() {
-      return repeatedMessageField_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-     */
-    @java.lang.Override
-    public int getRepeatedMessageFieldCount() {
-      return repeatedMessageField_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.ForeignMessage getRepeatedMessageField(int index) {
-      return repeatedMessageField_.get(index);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-     */
-    public protobuf_unittest.UnittestProto.ForeignMessageOrBuilder getRepeatedMessageFieldOrBuilder(
-        int index) {
-      return repeatedMessageField_.get(index);
-    }
-    private void ensureRepeatedMessageFieldIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.ForeignMessage> tmp = repeatedMessageField_;
-      if (!tmp.isModifiable()) {
-        repeatedMessageField_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-     */
-    private void setRepeatedMessageField(
-        int index, protobuf_unittest.UnittestProto.ForeignMessage value) {
-      value.getClass();
-  ensureRepeatedMessageFieldIsMutable();
-      repeatedMessageField_.set(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-     */
-    private void addRepeatedMessageField(protobuf_unittest.UnittestProto.ForeignMessage value) {
-      value.getClass();
-  ensureRepeatedMessageFieldIsMutable();
-      repeatedMessageField_.add(value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-     */
-    private void addRepeatedMessageField(
-        int index, protobuf_unittest.UnittestProto.ForeignMessage value) {
-      value.getClass();
-  ensureRepeatedMessageFieldIsMutable();
-      repeatedMessageField_.add(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-     */
-    private void addAllRepeatedMessageField(
-        java.lang.Iterable<? extends protobuf_unittest.UnittestProto.ForeignMessage> values) {
-      ensureRepeatedMessageFieldIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedMessageField_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-     */
-    private void clearRepeatedMessageField() {
-      repeatedMessageField_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-     */
-    private void removeRepeatedMessageField(int index) {
-      ensureRepeatedMessageFieldIsMutable();
-      repeatedMessageField_.remove(index);
-    }
-
-    public static final int REPEATEDSTRINGPIECEFIELD_FIELD_NUMBER = 11;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> repeatedStringPieceField_;
-    /**
-     * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-     * @return A list containing the repeatedStringPieceField.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getRepeatedStringPieceFieldList() {
-      return repeatedStringPieceField_;
-    }
-    /**
-     * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-     * @return The count of repeatedStringPieceField.
-     */
-    @java.lang.Override
-    public int getRepeatedStringPieceFieldCount() {
-      return repeatedStringPieceField_.size();
-    }
-    /**
-     * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedStringPieceField at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getRepeatedStringPieceField(int index) {
-      return repeatedStringPieceField_.get(index);
-    }
-    /**
-     * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the repeatedStringPieceField at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getRepeatedStringPieceFieldBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          repeatedStringPieceField_.get(index));
-    }
-    private void ensureRepeatedStringPieceFieldIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          repeatedStringPieceField_;  if (!tmp.isModifiable()) {
-        repeatedStringPieceField_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedStringPieceField to set.
-     */
-    private void setRepeatedStringPieceField(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureRepeatedStringPieceFieldIsMutable();
-      repeatedStringPieceField_.set(index, value);
-    }
-    /**
-     * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-     * @param value The repeatedStringPieceField to add.
-     */
-    private void addRepeatedStringPieceField(
-        java.lang.String value) {
-      value.getClass();
-  ensureRepeatedStringPieceFieldIsMutable();
-      repeatedStringPieceField_.add(value);
-    }
-    /**
-     * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-     * @param values The repeatedStringPieceField to add.
-     */
-    private void addAllRepeatedStringPieceField(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureRepeatedStringPieceFieldIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedStringPieceField_);
-    }
-    /**
-     * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-     */
-    private void clearRepeatedStringPieceField() {
-      repeatedStringPieceField_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-     * @param value The bytes of the repeatedStringPieceField to add.
-     */
-    private void addRepeatedStringPieceFieldBytes(
-        com.google.protobuf.ByteString value) {
-      ensureRepeatedStringPieceFieldIsMutable();
-      repeatedStringPieceField_.add(value.toStringUtf8());
-    }
-
-    public static final int REPEATEDCORDFIELD_FIELD_NUMBER = 12;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> repeatedCordField_;
-    /**
-     * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-     * @return A list containing the repeatedCordField.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getRepeatedCordFieldList() {
-      return repeatedCordField_;
-    }
-    /**
-     * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-     * @return The count of repeatedCordField.
-     */
-    @java.lang.Override
-    public int getRepeatedCordFieldCount() {
-      return repeatedCordField_.size();
-    }
-    /**
-     * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedCordField at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getRepeatedCordField(int index) {
-      return repeatedCordField_.get(index);
-    }
-    /**
-     * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the repeatedCordField at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getRepeatedCordFieldBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          repeatedCordField_.get(index));
-    }
-    private void ensureRepeatedCordFieldIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          repeatedCordField_;  if (!tmp.isModifiable()) {
-        repeatedCordField_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedCordField to set.
-     */
-    private void setRepeatedCordField(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureRepeatedCordFieldIsMutable();
-      repeatedCordField_.set(index, value);
-    }
-    /**
-     * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-     * @param value The repeatedCordField to add.
-     */
-    private void addRepeatedCordField(
-        java.lang.String value) {
-      value.getClass();
-  ensureRepeatedCordFieldIsMutable();
-      repeatedCordField_.add(value);
-    }
-    /**
-     * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-     * @param values The repeatedCordField to add.
-     */
-    private void addAllRepeatedCordField(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureRepeatedCordFieldIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedCordField_);
-    }
-    /**
-     * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-     */
-    private void clearRepeatedCordField() {
-      repeatedCordField_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-     * @param value The bytes of the repeatedCordField to add.
-     */
-    private void addRepeatedCordFieldBytes(
-        com.google.protobuf.ByteString value) {
-      ensureRepeatedCordFieldIsMutable();
-      repeatedCordField_.add(value.toStringUtf8());
-    }
-
-    public static protobuf_unittest.UnittestProto.TestCamelCaseFieldNames parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestCamelCaseFieldNames parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestCamelCaseFieldNames parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestCamelCaseFieldNames parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestCamelCaseFieldNames parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestCamelCaseFieldNames parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestCamelCaseFieldNames parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestCamelCaseFieldNames parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestCamelCaseFieldNames parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestCamelCaseFieldNames parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestCamelCaseFieldNames parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestCamelCaseFieldNames parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestCamelCaseFieldNames prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Test message with CamelCase field names.  This violates Protocol Buffer
-     * standard style.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestCamelCaseFieldNames}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestCamelCaseFieldNames, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestCamelCaseFieldNames)
-        protobuf_unittest.UnittestProto.TestCamelCaseFieldNamesOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestCamelCaseFieldNames.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int32 PrimitiveField = 1;</code>
-       * @return Whether the primitiveField field is set.
-       */
-      @java.lang.Override
-      public boolean hasPrimitiveField() {
-        return instance.hasPrimitiveField();
-      }
-      /**
-       * <code>optional int32 PrimitiveField = 1;</code>
-       * @return The primitiveField.
-       */
-      @java.lang.Override
-      public int getPrimitiveField() {
-        return instance.getPrimitiveField();
-      }
-      /**
-       * <code>optional int32 PrimitiveField = 1;</code>
-       * @param value The primitiveField to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPrimitiveField(int value) {
-        copyOnWrite();
-        instance.setPrimitiveField(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 PrimitiveField = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPrimitiveField() {
-        copyOnWrite();
-        instance.clearPrimitiveField();
-        return this;
-      }
-
-      /**
-       * <code>optional string StringField = 2;</code>
-       * @return Whether the stringField field is set.
-       */
-      @java.lang.Override
-      public boolean hasStringField() {
-        return instance.hasStringField();
-      }
-      /**
-       * <code>optional string StringField = 2;</code>
-       * @return The stringField.
-       */
-      @java.lang.Override
-      public java.lang.String getStringField() {
-        return instance.getStringField();
-      }
-      /**
-       * <code>optional string StringField = 2;</code>
-       * @return The bytes for stringField.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getStringFieldBytes() {
-        return instance.getStringFieldBytes();
-      }
-      /**
-       * <code>optional string StringField = 2;</code>
-       * @param value The stringField to set.
-       * @return This builder for chaining.
-       */
-      public Builder setStringField(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setStringField(value);
-        return this;
-      }
-      /**
-       * <code>optional string StringField = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearStringField() {
-        copyOnWrite();
-        instance.clearStringField();
-        return this;
-      }
-      /**
-       * <code>optional string StringField = 2;</code>
-       * @param value The bytes for stringField to set.
-       * @return This builder for chaining.
-       */
-      public Builder setStringFieldBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setStringFieldBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum EnumField = 3;</code>
-       * @return Whether the enumField field is set.
-       */
-      @java.lang.Override
-      public boolean hasEnumField() {
-        return instance.hasEnumField();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum EnumField = 3;</code>
-       * @return The enumField.
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.ForeignEnum getEnumField() {
-        return instance.getEnumField();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum EnumField = 3;</code>
-       * @param value The enum numeric value on the wire for enumField to set.
-       * @return This builder for chaining.
-       */
-      public Builder setEnumField(protobuf_unittest.UnittestProto.ForeignEnum value) {
-        copyOnWrite();
-        instance.setEnumField(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum EnumField = 3;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearEnumField() {
-        copyOnWrite();
-        instance.clearEnumField();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage MessageField = 4;</code>
-       */
-      @java.lang.Override
-      public boolean hasMessageField() {
-        return instance.hasMessageField();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage MessageField = 4;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.ForeignMessage getMessageField() {
-        return instance.getMessageField();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage MessageField = 4;</code>
-       */
-      public Builder setMessageField(protobuf_unittest.UnittestProto.ForeignMessage value) {
-        copyOnWrite();
-        instance.setMessageField(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage MessageField = 4;</code>
-       */
-      public Builder setMessageField(
-          protobuf_unittest.UnittestProto.ForeignMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setMessageField(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage MessageField = 4;</code>
-       */
-      public Builder mergeMessageField(protobuf_unittest.UnittestProto.ForeignMessage value) {
-        copyOnWrite();
-        instance.mergeMessageField(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage MessageField = 4;</code>
-       */
-      public Builder clearMessageField() {  copyOnWrite();
-        instance.clearMessageField();
-        return this;
-      }
-
-      /**
-       * <code>optional string StringPieceField = 5 [ctype = STRING_PIECE];</code>
-       * @return Whether the stringPieceField field is set.
-       */
-      @java.lang.Override
-      public boolean hasStringPieceField() {
-        return instance.hasStringPieceField();
-      }
-      /**
-       * <code>optional string StringPieceField = 5 [ctype = STRING_PIECE];</code>
-       * @return The stringPieceField.
-       */
-      @java.lang.Override
-      public java.lang.String getStringPieceField() {
-        return instance.getStringPieceField();
-      }
-      /**
-       * <code>optional string StringPieceField = 5 [ctype = STRING_PIECE];</code>
-       * @return The bytes for stringPieceField.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getStringPieceFieldBytes() {
-        return instance.getStringPieceFieldBytes();
-      }
-      /**
-       * <code>optional string StringPieceField = 5 [ctype = STRING_PIECE];</code>
-       * @param value The stringPieceField to set.
-       * @return This builder for chaining.
-       */
-      public Builder setStringPieceField(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setStringPieceField(value);
-        return this;
-      }
-      /**
-       * <code>optional string StringPieceField = 5 [ctype = STRING_PIECE];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearStringPieceField() {
-        copyOnWrite();
-        instance.clearStringPieceField();
-        return this;
-      }
-      /**
-       * <code>optional string StringPieceField = 5 [ctype = STRING_PIECE];</code>
-       * @param value The bytes for stringPieceField to set.
-       * @return This builder for chaining.
-       */
-      public Builder setStringPieceFieldBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setStringPieceFieldBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional string CordField = 6 [ctype = CORD];</code>
-       * @return Whether the cordField field is set.
-       */
-      @java.lang.Override
-      public boolean hasCordField() {
-        return instance.hasCordField();
-      }
-      /**
-       * <code>optional string CordField = 6 [ctype = CORD];</code>
-       * @return The cordField.
-       */
-      @java.lang.Override
-      public java.lang.String getCordField() {
-        return instance.getCordField();
-      }
-      /**
-       * <code>optional string CordField = 6 [ctype = CORD];</code>
-       * @return The bytes for cordField.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getCordFieldBytes() {
-        return instance.getCordFieldBytes();
-      }
-      /**
-       * <code>optional string CordField = 6 [ctype = CORD];</code>
-       * @param value The cordField to set.
-       * @return This builder for chaining.
-       */
-      public Builder setCordField(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setCordField(value);
-        return this;
-      }
-      /**
-       * <code>optional string CordField = 6 [ctype = CORD];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearCordField() {
-        copyOnWrite();
-        instance.clearCordField();
-        return this;
-      }
-      /**
-       * <code>optional string CordField = 6 [ctype = CORD];</code>
-       * @param value The bytes for cordField to set.
-       * @return This builder for chaining.
-       */
-      public Builder setCordFieldBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setCordFieldBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>repeated int32 RepeatedPrimitiveField = 7;</code>
-       * @return A list containing the repeatedPrimitiveField.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedPrimitiveFieldList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedPrimitiveFieldList());
-      }
-      /**
-       * <code>repeated int32 RepeatedPrimitiveField = 7;</code>
-       * @return The count of repeatedPrimitiveField.
-       */
-      @java.lang.Override
-      public int getRepeatedPrimitiveFieldCount() {
-        return instance.getRepeatedPrimitiveFieldCount();
-      }
-      /**
-       * <code>repeated int32 RepeatedPrimitiveField = 7;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedPrimitiveField at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedPrimitiveField(int index) {
-        return instance.getRepeatedPrimitiveField(index);
-      }
-      /**
-       * <code>repeated int32 RepeatedPrimitiveField = 7;</code>
-       * @param value The repeatedPrimitiveField to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedPrimitiveField(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedPrimitiveField(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 RepeatedPrimitiveField = 7;</code>
-       * @param value The repeatedPrimitiveField to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedPrimitiveField(int value) {
-        copyOnWrite();
-        instance.addRepeatedPrimitiveField(value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 RepeatedPrimitiveField = 7;</code>
-       * @param values The repeatedPrimitiveField to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedPrimitiveField(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedPrimitiveField(values);
-        return this;
-      }
-      /**
-       * <code>repeated int32 RepeatedPrimitiveField = 7;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedPrimitiveField() {
-        copyOnWrite();
-        instance.clearRepeatedPrimitiveField();
-        return this;
-      }
-
-      /**
-       * <code>repeated string RepeatedStringField = 8;</code>
-       * @return A list containing the repeatedStringField.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getRepeatedStringFieldList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedStringFieldList());
-      }
-      /**
-       * <code>repeated string RepeatedStringField = 8;</code>
-       * @return The count of repeatedStringField.
-       */
-      @java.lang.Override
-      public int getRepeatedStringFieldCount() {
-        return instance.getRepeatedStringFieldCount();
-      }
-      /**
-       * <code>repeated string RepeatedStringField = 8;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedStringField at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getRepeatedStringField(int index) {
-        return instance.getRepeatedStringField(index);
-      }
-      /**
-       * <code>repeated string RepeatedStringField = 8;</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the repeatedStringField at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getRepeatedStringFieldBytes(int index) {
-        return instance.getRepeatedStringFieldBytes(index);
-      }
-      /**
-       * <code>repeated string RepeatedStringField = 8;</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedStringField to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedStringField(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setRepeatedStringField(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string RepeatedStringField = 8;</code>
-       * @param value The repeatedStringField to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedStringField(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addRepeatedStringField(value);
-        return this;
-      }
-      /**
-       * <code>repeated string RepeatedStringField = 8;</code>
-       * @param values The repeatedStringField to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedStringField(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllRepeatedStringField(values);
-        return this;
-      }
-      /**
-       * <code>repeated string RepeatedStringField = 8;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedStringField() {
-        copyOnWrite();
-        instance.clearRepeatedStringField();
-        return this;
-      }
-      /**
-       * <code>repeated string RepeatedStringField = 8;</code>
-       * @param value The bytes of the repeatedStringField to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedStringFieldBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addRepeatedStringFieldBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum RepeatedEnumField = 9;</code>
-       * @return A list containing the repeatedEnumField.
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.ForeignEnum> getRepeatedEnumFieldList() {
-        return instance.getRepeatedEnumFieldList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum RepeatedEnumField = 9;</code>
-       * @return The count of repeatedEnumField.
-       */
-      @java.lang.Override
-      public int getRepeatedEnumFieldCount() {
-        return instance.getRepeatedEnumFieldCount();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum RepeatedEnumField = 9;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedEnumField at the given index.
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.ForeignEnum getRepeatedEnumField(int index) {
-        return instance.getRepeatedEnumField(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum RepeatedEnumField = 9;</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedEnumField to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedEnumField(
-          int index, protobuf_unittest.UnittestProto.ForeignEnum value) {
-        copyOnWrite();
-        instance.setRepeatedEnumField(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum RepeatedEnumField = 9;</code>
-       * @param value The repeatedEnumField to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedEnumField(protobuf_unittest.UnittestProto.ForeignEnum value) {
-        copyOnWrite();
-        instance.addRepeatedEnumField(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum RepeatedEnumField = 9;</code>
-       * @param values The repeatedEnumField to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedEnumField(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.ForeignEnum> values) {
-        copyOnWrite();
-        instance.addAllRepeatedEnumField(values);  return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum RepeatedEnumField = 9;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedEnumField() {
-        copyOnWrite();
-        instance.clearRepeatedEnumField();
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.ForeignMessage> getRepeatedMessageFieldList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedMessageFieldList());
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-       */
-      @java.lang.Override
-      public int getRepeatedMessageFieldCount() {
-        return instance.getRepeatedMessageFieldCount();
-      }/**
-       * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.ForeignMessage getRepeatedMessageField(int index) {
-        return instance.getRepeatedMessageField(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-       */
-      public Builder setRepeatedMessageField(
-          int index, protobuf_unittest.UnittestProto.ForeignMessage value) {
-        copyOnWrite();
-        instance.setRepeatedMessageField(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-       */
-      public Builder setRepeatedMessageField(
-          int index, protobuf_unittest.UnittestProto.ForeignMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedMessageField(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-       */
-      public Builder addRepeatedMessageField(protobuf_unittest.UnittestProto.ForeignMessage value) {
-        copyOnWrite();
-        instance.addRepeatedMessageField(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-       */
-      public Builder addRepeatedMessageField(
-          int index, protobuf_unittest.UnittestProto.ForeignMessage value) {
-        copyOnWrite();
-        instance.addRepeatedMessageField(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-       */
-      public Builder addRepeatedMessageField(
-          protobuf_unittest.UnittestProto.ForeignMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedMessageField(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-       */
-      public Builder addRepeatedMessageField(
-          int index, protobuf_unittest.UnittestProto.ForeignMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedMessageField(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-       */
-      public Builder addAllRepeatedMessageField(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.ForeignMessage> values) {
-        copyOnWrite();
-        instance.addAllRepeatedMessageField(values);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-       */
-      public Builder clearRepeatedMessageField() {
-        copyOnWrite();
-        instance.clearRepeatedMessageField();
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignMessage RepeatedMessageField = 10;</code>
-       */
-      public Builder removeRepeatedMessageField(int index) {
-        copyOnWrite();
-        instance.removeRepeatedMessageField(index);
-        return this;
-      }
-
-      /**
-       * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-       * @return A list containing the repeatedStringPieceField.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getRepeatedStringPieceFieldList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedStringPieceFieldList());
-      }
-      /**
-       * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-       * @return The count of repeatedStringPieceField.
-       */
-      @java.lang.Override
-      public int getRepeatedStringPieceFieldCount() {
-        return instance.getRepeatedStringPieceFieldCount();
-      }
-      /**
-       * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedStringPieceField at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getRepeatedStringPieceField(int index) {
-        return instance.getRepeatedStringPieceField(index);
-      }
-      /**
-       * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the repeatedStringPieceField at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getRepeatedStringPieceFieldBytes(int index) {
-        return instance.getRepeatedStringPieceFieldBytes(index);
-      }
-      /**
-       * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedStringPieceField to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedStringPieceField(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setRepeatedStringPieceField(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-       * @param value The repeatedStringPieceField to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedStringPieceField(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addRepeatedStringPieceField(value);
-        return this;
-      }
-      /**
-       * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-       * @param values The repeatedStringPieceField to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedStringPieceField(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllRepeatedStringPieceField(values);
-        return this;
-      }
-      /**
-       * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedStringPieceField() {
-        copyOnWrite();
-        instance.clearRepeatedStringPieceField();
-        return this;
-      }
-      /**
-       * <code>repeated string RepeatedStringPieceField = 11 [ctype = STRING_PIECE];</code>
-       * @param value The bytes of the repeatedStringPieceField to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedStringPieceFieldBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addRepeatedStringPieceFieldBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-       * @return A list containing the repeatedCordField.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getRepeatedCordFieldList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedCordFieldList());
-      }
-      /**
-       * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-       * @return The count of repeatedCordField.
-       */
-      @java.lang.Override
-      public int getRepeatedCordFieldCount() {
-        return instance.getRepeatedCordFieldCount();
-      }
-      /**
-       * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedCordField at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getRepeatedCordField(int index) {
-        return instance.getRepeatedCordField(index);
-      }
-      /**
-       * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the repeatedCordField at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getRepeatedCordFieldBytes(int index) {
-        return instance.getRepeatedCordFieldBytes(index);
-      }
-      /**
-       * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedCordField to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedCordField(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setRepeatedCordField(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-       * @param value The repeatedCordField to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedCordField(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addRepeatedCordField(value);
-        return this;
-      }
-      /**
-       * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-       * @param values The repeatedCordField to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedCordField(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllRepeatedCordField(values);
-        return this;
-      }
-      /**
-       * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedCordField() {
-        copyOnWrite();
-        instance.clearRepeatedCordField();
-        return this;
-      }
-      /**
-       * <code>repeated string RepeatedCordField = 12 [ctype = CORD];</code>
-       * @param value The bytes of the repeatedCordField to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedCordFieldBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addRepeatedCordFieldBytes(value);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestCamelCaseFieldNames)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestCamelCaseFieldNames();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "primitiveField_",
-              "stringField_",
-              "enumField_",
-              protobuf_unittest.UnittestProto.ForeignEnum.internalGetVerifier(),
-              "messageField_",
-              "stringPieceField_",
-              "cordField_",
-              "repeatedPrimitiveField_",
-              "repeatedStringField_",
-              "repeatedEnumField_",
-              protobuf_unittest.UnittestProto.ForeignEnum.internalGetVerifier(),
-              "repeatedMessageField_",
-              protobuf_unittest.UnittestProto.ForeignMessage.class,
-              "repeatedStringPieceField_",
-              "repeatedCordField_",
-            };
-            java.lang.String info =
-                "\u0001\f\u0000\u0001\u0001\f\f\u0000\u0006\u0000\u0001\u1004\u0000\u0002\u1008\u0001" +
-                "\u0003\u100c\u0002\u0004\u1009\u0003\u0005\u1008\u0004\u0006\u1008\u0005\u0007\u0016" +
-                "\b\u001a\t\u001e\n\u001b\u000b\u001a\f\u001a";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestCamelCaseFieldNames> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestCamelCaseFieldNames.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestCamelCaseFieldNames>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestCamelCaseFieldNames)
-    private static final protobuf_unittest.UnittestProto.TestCamelCaseFieldNames DEFAULT_INSTANCE;
-    static {
-      TestCamelCaseFieldNames defaultInstance = new TestCamelCaseFieldNames();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestCamelCaseFieldNames.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestCamelCaseFieldNames getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestCamelCaseFieldNames> PARSER;
-
-    public static com.google.protobuf.Parser<TestCamelCaseFieldNames> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestFieldOrderingsOrBuilder extends 
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestFieldOrderings)
-       com.google.protobuf.GeneratedMessageLite.
-            ExtendableMessageOrBuilder<
-                TestFieldOrderings, TestFieldOrderings.Builder> {
-
-    /**
-     * <code>optional string my_string = 11;</code>
-     * @return Whether the myString field is set.
-     */
-    boolean hasMyString();
-    /**
-     * <code>optional string my_string = 11;</code>
-     * @return The myString.
-     */
-    java.lang.String getMyString();
-    /**
-     * <code>optional string my_string = 11;</code>
-     * @return The bytes for myString.
-     */
-    com.google.protobuf.ByteString
-        getMyStringBytes();
-
-    /**
-     * <code>optional int64 my_int = 1;</code>
-     * @return Whether the myInt field is set.
-     */
-    boolean hasMyInt();
-    /**
-     * <code>optional int64 my_int = 1;</code>
-     * @return The myInt.
-     */
-    long getMyInt();
-
-    /**
-     * <code>optional float my_float = 101;</code>
-     * @return Whether the myFloat field is set.
-     */
-    boolean hasMyFloat();
-    /**
-     * <code>optional float my_float = 101;</code>
-     * @return The myFloat.
-     */
-    float getMyFloat();
-
-    /**
-     * <code>optional .protobuf_unittest.TestFieldOrderings.NestedMessage optional_nested_message = 200;</code>
-     * @return Whether the optionalNestedMessage field is set.
-     */
-    boolean hasOptionalNestedMessage();
-    /**
-     * <code>optional .protobuf_unittest.TestFieldOrderings.NestedMessage optional_nested_message = 200;</code>
-     * @return The optionalNestedMessage.
-     */
-    protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage getOptionalNestedMessage();
-  }
-  /**
-   * <pre>
-   * We list fields out of order, to ensure that we're using field number and not
-   * field index to determine serialization order.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestFieldOrderings}
-   */
-  public  static final class TestFieldOrderings extends
-      com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
-        TestFieldOrderings, TestFieldOrderings.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestFieldOrderings)
-      TestFieldOrderingsOrBuilder {
-    private TestFieldOrderings() {
-      myString_ = "";
-    }
-    public interface NestedMessageOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestFieldOrderings.NestedMessage)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int64 oo = 2;</code>
-       * @return Whether the oo field is set.
-       */
-      boolean hasOo();
-      /**
-       * <code>optional int64 oo = 2;</code>
-       * @return The oo.
-       */
-      long getOo();
-
-      /**
-       * <pre>
-       * The field name "b" fails to compile in proto1 because it conflicts with
-       * a local variable named "b" in one of the generated methods.  Doh.
-       * This file needs to compile in proto1 to test backwards-compatibility.
-       * </pre>
-       *
-       * <code>optional int32 bb = 1;</code>
-       * @return Whether the bb field is set.
-       */
-      boolean hasBb();
-      /**
-       * <pre>
-       * The field name "b" fails to compile in proto1 because it conflicts with
-       * a local variable named "b" in one of the generated methods.  Doh.
-       * This file needs to compile in proto1 to test backwards-compatibility.
-       * </pre>
-       *
-       * <code>optional int32 bb = 1;</code>
-       * @return The bb.
-       */
-      int getBb();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestFieldOrderings.NestedMessage}
-     */
-    public  static final class NestedMessage extends
-        com.google.protobuf.GeneratedMessageLite<
-            NestedMessage, NestedMessage.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestFieldOrderings.NestedMessage)
-        NestedMessageOrBuilder {
-      private NestedMessage() {
-      }
-      private int bitField0_;
-      public static final int OO_FIELD_NUMBER = 2;
-      private long oo_;
-      /**
-       * <code>optional int64 oo = 2;</code>
-       * @return Whether the oo field is set.
-       */
-      @java.lang.Override
-      public boolean hasOo() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int64 oo = 2;</code>
-       * @return The oo.
-       */
-      @java.lang.Override
-      public long getOo() {
-        return oo_;
-      }
-      /**
-       * <code>optional int64 oo = 2;</code>
-       * @param value The oo to set.
-       */
-      private void setOo(long value) {
-        bitField0_ |= 0x00000001;
-        oo_ = value;
-      }
-      /**
-       * <code>optional int64 oo = 2;</code>
-       */
-      private void clearOo() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        oo_ = 0L;
-      }
-
-      public static final int BB_FIELD_NUMBER = 1;
-      private int bb_;
-      /**
-       * <pre>
-       * The field name "b" fails to compile in proto1 because it conflicts with
-       * a local variable named "b" in one of the generated methods.  Doh.
-       * This file needs to compile in proto1 to test backwards-compatibility.
-       * </pre>
-       *
-       * <code>optional int32 bb = 1;</code>
-       * @return Whether the bb field is set.
-       */
-      @java.lang.Override
-      public boolean hasBb() {
-        return ((bitField0_ & 0x00000002) != 0);
-      }
-      /**
-       * <pre>
-       * The field name "b" fails to compile in proto1 because it conflicts with
-       * a local variable named "b" in one of the generated methods.  Doh.
-       * This file needs to compile in proto1 to test backwards-compatibility.
-       * </pre>
-       *
-       * <code>optional int32 bb = 1;</code>
-       * @return The bb.
-       */
-      @java.lang.Override
-      public int getBb() {
-        return bb_;
-      }
-      /**
-       * <pre>
-       * The field name "b" fails to compile in proto1 because it conflicts with
-       * a local variable named "b" in one of the generated methods.  Doh.
-       * This file needs to compile in proto1 to test backwards-compatibility.
-       * </pre>
-       *
-       * <code>optional int32 bb = 1;</code>
-       * @param value The bb to set.
-       */
-      private void setBb(int value) {
-        bitField0_ |= 0x00000002;
-        bb_ = value;
-      }
-      /**
-       * <pre>
-       * The field name "b" fails to compile in proto1 because it conflicts with
-       * a local variable named "b" in one of the generated methods.  Doh.
-       * This file needs to compile in proto1 to test backwards-compatibility.
-       * </pre>
-       *
-       * <code>optional int32 bb = 1;</code>
-       */
-      private void clearBb() {
-        bitField0_ = (bitField0_ & ~0x00000002);
-        bb_ = 0;
-      }
-
-      public static protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestFieldOrderings.NestedMessage}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestFieldOrderings.NestedMessage)
-          protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessageOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int64 oo = 2;</code>
-         * @return Whether the oo field is set.
-         */
-        @java.lang.Override
-        public boolean hasOo() {
-          return instance.hasOo();
-        }
-        /**
-         * <code>optional int64 oo = 2;</code>
-         * @return The oo.
-         */
-        @java.lang.Override
-        public long getOo() {
-          return instance.getOo();
-        }
-        /**
-         * <code>optional int64 oo = 2;</code>
-         * @param value The oo to set.
-         * @return This builder for chaining.
-         */
-        public Builder setOo(long value) {
-          copyOnWrite();
-          instance.setOo(value);
-          return this;
-        }
-        /**
-         * <code>optional int64 oo = 2;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearOo() {
-          copyOnWrite();
-          instance.clearOo();
-          return this;
-        }
-
-        /**
-         * <pre>
-         * The field name "b" fails to compile in proto1 because it conflicts with
-         * a local variable named "b" in one of the generated methods.  Doh.
-         * This file needs to compile in proto1 to test backwards-compatibility.
-         * </pre>
-         *
-         * <code>optional int32 bb = 1;</code>
-         * @return Whether the bb field is set.
-         */
-        @java.lang.Override
-        public boolean hasBb() {
-          return instance.hasBb();
-        }
-        /**
-         * <pre>
-         * The field name "b" fails to compile in proto1 because it conflicts with
-         * a local variable named "b" in one of the generated methods.  Doh.
-         * This file needs to compile in proto1 to test backwards-compatibility.
-         * </pre>
-         *
-         * <code>optional int32 bb = 1;</code>
-         * @return The bb.
-         */
-        @java.lang.Override
-        public int getBb() {
-          return instance.getBb();
-        }
-        /**
-         * <pre>
-         * The field name "b" fails to compile in proto1 because it conflicts with
-         * a local variable named "b" in one of the generated methods.  Doh.
-         * This file needs to compile in proto1 to test backwards-compatibility.
-         * </pre>
-         *
-         * <code>optional int32 bb = 1;</code>
-         * @param value The bb to set.
-         * @return This builder for chaining.
-         */
-        public Builder setBb(int value) {
-          copyOnWrite();
-          instance.setBb(value);
-          return this;
-        }
-        /**
-         * <pre>
-         * The field name "b" fails to compile in proto1 because it conflicts with
-         * a local variable named "b" in one of the generated methods.  Doh.
-         * This file needs to compile in proto1 to test backwards-compatibility.
-         * </pre>
-         *
-         * <code>optional int32 bb = 1;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearBb() {
-          copyOnWrite();
-          instance.clearBb();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestFieldOrderings.NestedMessage)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "bb_",
-                "oo_",
-              };
-              java.lang.String info =
-                  "\u0001\u0002\u0000\u0001\u0001\u0002\u0002\u0000\u0000\u0000\u0001\u1004\u0001\u0002" +
-                  "\u1002\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestFieldOrderings.NestedMessage)
-      private static final protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage DEFAULT_INSTANCE;
-      static {
-        NestedMessage defaultInstance = new NestedMessage();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          NestedMessage.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<NestedMessage> PARSER;
-
-      public static com.google.protobuf.Parser<NestedMessage> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int bitField0_;
-    public static final int MY_STRING_FIELD_NUMBER = 11;
-    private java.lang.String myString_;
-    /**
-     * <code>optional string my_string = 11;</code>
-     * @return Whether the myString field is set.
-     */
-    @java.lang.Override
-    public boolean hasMyString() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional string my_string = 11;</code>
-     * @return The myString.
-     */
-    @java.lang.Override
-    public java.lang.String getMyString() {
-      return myString_;
-    }
-    /**
-     * <code>optional string my_string = 11;</code>
-     * @return The bytes for myString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getMyStringBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(myString_);
-    }
-    /**
-     * <code>optional string my_string = 11;</code>
-     * @param value The myString to set.
-     */
-    private void setMyString(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00000001;
-      myString_ = value;
-    }
-    /**
-     * <code>optional string my_string = 11;</code>
-     */
-    private void clearMyString() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      myString_ = getDefaultInstance().getMyString();
-    }
-    /**
-     * <code>optional string my_string = 11;</code>
-     * @param value The bytes for myString to set.
-     */
-    private void setMyStringBytes(
-        com.google.protobuf.ByteString value) {
-      myString_ = value.toStringUtf8();
-      bitField0_ |= 0x00000001;
-    }
-
-    public static final int MY_INT_FIELD_NUMBER = 1;
-    private long myInt_;
-    /**
-     * <code>optional int64 my_int = 1;</code>
-     * @return Whether the myInt field is set.
-     */
-    @java.lang.Override
-    public boolean hasMyInt() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional int64 my_int = 1;</code>
-     * @return The myInt.
-     */
-    @java.lang.Override
-    public long getMyInt() {
-      return myInt_;
-    }
-    /**
-     * <code>optional int64 my_int = 1;</code>
-     * @param value The myInt to set.
-     */
-    private void setMyInt(long value) {
-      bitField0_ |= 0x00000002;
-      myInt_ = value;
-    }
-    /**
-     * <code>optional int64 my_int = 1;</code>
-     */
-    private void clearMyInt() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      myInt_ = 0L;
-    }
-
-    public static final int MY_FLOAT_FIELD_NUMBER = 101;
-    private float myFloat_;
-    /**
-     * <code>optional float my_float = 101;</code>
-     * @return Whether the myFloat field is set.
-     */
-    @java.lang.Override
-    public boolean hasMyFloat() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional float my_float = 101;</code>
-     * @return The myFloat.
-     */
-    @java.lang.Override
-    public float getMyFloat() {
-      return myFloat_;
-    }
-    /**
-     * <code>optional float my_float = 101;</code>
-     * @param value The myFloat to set.
-     */
-    private void setMyFloat(float value) {
-      bitField0_ |= 0x00000004;
-      myFloat_ = value;
-    }
-    /**
-     * <code>optional float my_float = 101;</code>
-     */
-    private void clearMyFloat() {
-      bitField0_ = (bitField0_ & ~0x00000004);
-      myFloat_ = 0F;
-    }
-
-    public static final int OPTIONAL_NESTED_MESSAGE_FIELD_NUMBER = 200;
-    private protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage optionalNestedMessage_;
-    /**
-     * <code>optional .protobuf_unittest.TestFieldOrderings.NestedMessage optional_nested_message = 200;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalNestedMessage() {
-      return ((bitField0_ & 0x00000008) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestFieldOrderings.NestedMessage optional_nested_message = 200;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage getOptionalNestedMessage() {
-      return optionalNestedMessage_ == null ? protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage.getDefaultInstance() : optionalNestedMessage_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestFieldOrderings.NestedMessage optional_nested_message = 200;</code>
-     */
-    private void setOptionalNestedMessage(protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage value) {
-      value.getClass();
-  optionalNestedMessage_ = value;
-      bitField0_ |= 0x00000008;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestFieldOrderings.NestedMessage optional_nested_message = 200;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalNestedMessage(protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage value) {
-      value.getClass();
-  if (optionalNestedMessage_ != null &&
-          optionalNestedMessage_ != protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage.getDefaultInstance()) {
-        optionalNestedMessage_ =
-          protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage.newBuilder(optionalNestedMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalNestedMessage_ = value;
-      }
-      bitField0_ |= 0x00000008;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestFieldOrderings.NestedMessage optional_nested_message = 200;</code>
-     */
-    private void clearOptionalNestedMessage() {  optionalNestedMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x00000008);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestFieldOrderings parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestFieldOrderings parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestFieldOrderings parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestFieldOrderings parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestFieldOrderings parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestFieldOrderings parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestFieldOrderings parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestFieldOrderings parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestFieldOrderings parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestFieldOrderings parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestFieldOrderings parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestFieldOrderings parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestFieldOrderings prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * We list fields out of order, to ensure that we're using field number and not
-     * field index to determine serialization order.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestFieldOrderings}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
-          protobuf_unittest.UnittestProto.TestFieldOrderings, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestFieldOrderings)
-        protobuf_unittest.UnittestProto.TestFieldOrderingsOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestFieldOrderings.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional string my_string = 11;</code>
-       * @return Whether the myString field is set.
-       */
-      @java.lang.Override
-      public boolean hasMyString() {
-        return instance.hasMyString();
-      }
-      /**
-       * <code>optional string my_string = 11;</code>
-       * @return The myString.
-       */
-      @java.lang.Override
-      public java.lang.String getMyString() {
-        return instance.getMyString();
-      }
-      /**
-       * <code>optional string my_string = 11;</code>
-       * @return The bytes for myString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getMyStringBytes() {
-        return instance.getMyStringBytes();
-      }
-      /**
-       * <code>optional string my_string = 11;</code>
-       * @param value The myString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setMyString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setMyString(value);
-        return this;
-      }
-      /**
-       * <code>optional string my_string = 11;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearMyString() {
-        copyOnWrite();
-        instance.clearMyString();
-        return this;
-      }
-      /**
-       * <code>optional string my_string = 11;</code>
-       * @param value The bytes for myString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setMyStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setMyStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional int64 my_int = 1;</code>
-       * @return Whether the myInt field is set.
-       */
-      @java.lang.Override
-      public boolean hasMyInt() {
-        return instance.hasMyInt();
-      }
-      /**
-       * <code>optional int64 my_int = 1;</code>
-       * @return The myInt.
-       */
-      @java.lang.Override
-      public long getMyInt() {
-        return instance.getMyInt();
-      }
-      /**
-       * <code>optional int64 my_int = 1;</code>
-       * @param value The myInt to set.
-       * @return This builder for chaining.
-       */
-      public Builder setMyInt(long value) {
-        copyOnWrite();
-        instance.setMyInt(value);
-        return this;
-      }
-      /**
-       * <code>optional int64 my_int = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearMyInt() {
-        copyOnWrite();
-        instance.clearMyInt();
-        return this;
-      }
-
-      /**
-       * <code>optional float my_float = 101;</code>
-       * @return Whether the myFloat field is set.
-       */
-      @java.lang.Override
-      public boolean hasMyFloat() {
-        return instance.hasMyFloat();
-      }
-      /**
-       * <code>optional float my_float = 101;</code>
-       * @return The myFloat.
-       */
-      @java.lang.Override
-      public float getMyFloat() {
-        return instance.getMyFloat();
-      }
-      /**
-       * <code>optional float my_float = 101;</code>
-       * @param value The myFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setMyFloat(float value) {
-        copyOnWrite();
-        instance.setMyFloat(value);
-        return this;
-      }
-      /**
-       * <code>optional float my_float = 101;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearMyFloat() {
-        copyOnWrite();
-        instance.clearMyFloat();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.TestFieldOrderings.NestedMessage optional_nested_message = 200;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalNestedMessage() {
-        return instance.hasOptionalNestedMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestFieldOrderings.NestedMessage optional_nested_message = 200;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage getOptionalNestedMessage() {
-        return instance.getOptionalNestedMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestFieldOrderings.NestedMessage optional_nested_message = 200;</code>
-       */
-      public Builder setOptionalNestedMessage(protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage value) {
-        copyOnWrite();
-        instance.setOptionalNestedMessage(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestFieldOrderings.NestedMessage optional_nested_message = 200;</code>
-       */
-      public Builder setOptionalNestedMessage(
-          protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalNestedMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestFieldOrderings.NestedMessage optional_nested_message = 200;</code>
-       */
-      public Builder mergeOptionalNestedMessage(protobuf_unittest.UnittestProto.TestFieldOrderings.NestedMessage value) {
-        copyOnWrite();
-        instance.mergeOptionalNestedMessage(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestFieldOrderings.NestedMessage optional_nested_message = 200;</code>
-       */
-      public Builder clearOptionalNestedMessage() {  copyOnWrite();
-        instance.clearOptionalNestedMessage();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestFieldOrderings)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestFieldOrderings();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "myInt_",
-              "myString_",
-              "myFloat_",
-              "optionalNestedMessage_",
-            };
-            java.lang.String info =
-                "\u0001\u0004\u0000\u0001\u0001\u00c8\u0004\u0000\u0000\u0000\u0001\u1002\u0001\u000b" +
-                "\u1008\u0000e\u1001\u0002\u00c8\u1009\u0003";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestFieldOrderings> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestFieldOrderings.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestFieldOrderings>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestFieldOrderings)
-    private static final protobuf_unittest.UnittestProto.TestFieldOrderings DEFAULT_INSTANCE;
-    static {
-      TestFieldOrderings defaultInstance = new TestFieldOrderings();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestFieldOrderings.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestFieldOrderings getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestFieldOrderings> PARSER;
-
-    public static com.google.protobuf.Parser<TestFieldOrderings> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestExtensionOrderings1OrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestExtensionOrderings1)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional string my_string = 1;</code>
-     * @return Whether the myString field is set.
-     */
-    boolean hasMyString();
-    /**
-     * <code>optional string my_string = 1;</code>
-     * @return The myString.
-     */
-    java.lang.String getMyString();
-    /**
-     * <code>optional string my_string = 1;</code>
-     * @return The bytes for myString.
-     */
-    com.google.protobuf.ByteString
-        getMyStringBytes();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestExtensionOrderings1}
-   */
-  public  static final class TestExtensionOrderings1 extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestExtensionOrderings1, TestExtensionOrderings1.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestExtensionOrderings1)
-      TestExtensionOrderings1OrBuilder {
-    private TestExtensionOrderings1() {
-      myString_ = "";
-    }
-    private int bitField0_;
-    public static final int MY_STRING_FIELD_NUMBER = 1;
-    private java.lang.String myString_;
-    /**
-     * <code>optional string my_string = 1;</code>
-     * @return Whether the myString field is set.
-     */
-    @java.lang.Override
-    public boolean hasMyString() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional string my_string = 1;</code>
-     * @return The myString.
-     */
-    @java.lang.Override
-    public java.lang.String getMyString() {
-      return myString_;
-    }
-    /**
-     * <code>optional string my_string = 1;</code>
-     * @return The bytes for myString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getMyStringBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(myString_);
-    }
-    /**
-     * <code>optional string my_string = 1;</code>
-     * @param value The myString to set.
-     */
-    private void setMyString(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00000001;
-      myString_ = value;
-    }
-    /**
-     * <code>optional string my_string = 1;</code>
-     */
-    private void clearMyString() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      myString_ = getDefaultInstance().getMyString();
-    }
-    /**
-     * <code>optional string my_string = 1;</code>
-     * @param value The bytes for myString to set.
-     */
-    private void setMyStringBytes(
-        com.google.protobuf.ByteString value) {
-      myString_ = value.toStringUtf8();
-      bitField0_ |= 0x00000001;
-    }
-
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings1 parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings1 parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings1 parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings1 parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings1 parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings1 parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings1 parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings1 parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings1 parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings1 parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings1 parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings1 parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestExtensionOrderings1 prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestExtensionOrderings1}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestExtensionOrderings1, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestExtensionOrderings1)
-        protobuf_unittest.UnittestProto.TestExtensionOrderings1OrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestExtensionOrderings1.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @return Whether the myString field is set.
-       */
-      @java.lang.Override
-      public boolean hasMyString() {
-        return instance.hasMyString();
-      }
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @return The myString.
-       */
-      @java.lang.Override
-      public java.lang.String getMyString() {
-        return instance.getMyString();
-      }
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @return The bytes for myString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getMyStringBytes() {
-        return instance.getMyStringBytes();
-      }
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @param value The myString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setMyString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setMyString(value);
-        return this;
-      }
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearMyString() {
-        copyOnWrite();
-        instance.clearMyString();
-        return this;
-      }
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @param value The bytes for myString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setMyStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setMyStringBytes(value);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestExtensionOrderings1)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestExtensionOrderings1();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "myString_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1008\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestExtensionOrderings1> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestExtensionOrderings1.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestExtensionOrderings1>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestExtensionOrderings1)
-    private static final protobuf_unittest.UnittestProto.TestExtensionOrderings1 DEFAULT_INSTANCE;
-    static {
-      TestExtensionOrderings1 defaultInstance = new TestExtensionOrderings1();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestExtensionOrderings1.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings1 getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestExtensionOrderings1> PARSER;
-
-    public static com.google.protobuf.Parser<TestExtensionOrderings1> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-    public static final int TEST_EXT_ORDERINGS1_FIELD_NUMBER = 13;
-    /**
-     * <code>extend .protobuf_unittest.TestFieldOrderings { ... }</code>
-     */
-    public static final
-      com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-        protobuf_unittest.UnittestProto.TestFieldOrderings,
-        protobuf_unittest.UnittestProto.TestExtensionOrderings1> testExtOrderings1 = com.google.protobuf.GeneratedMessageLite
-            .newSingularGeneratedExtension(
-          protobuf_unittest.UnittestProto.TestFieldOrderings.getDefaultInstance(),
-          protobuf_unittest.UnittestProto.TestExtensionOrderings1.getDefaultInstance(),
-          protobuf_unittest.UnittestProto.TestExtensionOrderings1.getDefaultInstance(),
-          null,
-          13,
-          com.google.protobuf.WireFormat.FieldType.MESSAGE,
-          protobuf_unittest.UnittestProto.TestExtensionOrderings1.class);
-  }
-
-  public interface TestExtensionOrderings2OrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestExtensionOrderings2)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional string my_string = 1;</code>
-     * @return Whether the myString field is set.
-     */
-    boolean hasMyString();
-    /**
-     * <code>optional string my_string = 1;</code>
-     * @return The myString.
-     */
-    java.lang.String getMyString();
-    /**
-     * <code>optional string my_string = 1;</code>
-     * @return The bytes for myString.
-     */
-    com.google.protobuf.ByteString
-        getMyStringBytes();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestExtensionOrderings2}
-   */
-  public  static final class TestExtensionOrderings2 extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestExtensionOrderings2, TestExtensionOrderings2.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestExtensionOrderings2)
-      TestExtensionOrderings2OrBuilder {
-    private TestExtensionOrderings2() {
-      myString_ = "";
-    }
-    public interface TestExtensionOrderings3OrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestExtensionOrderings2.TestExtensionOrderings3)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @return Whether the myString field is set.
-       */
-      boolean hasMyString();
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @return The myString.
-       */
-      java.lang.String getMyString();
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @return The bytes for myString.
-       */
-      com.google.protobuf.ByteString
-          getMyStringBytes();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestExtensionOrderings2.TestExtensionOrderings3}
-     */
-    public  static final class TestExtensionOrderings3 extends
-        com.google.protobuf.GeneratedMessageLite<
-            TestExtensionOrderings3, TestExtensionOrderings3.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestExtensionOrderings2.TestExtensionOrderings3)
-        TestExtensionOrderings3OrBuilder {
-      private TestExtensionOrderings3() {
-        myString_ = "";
-      }
-      private int bitField0_;
-      public static final int MY_STRING_FIELD_NUMBER = 1;
-      private java.lang.String myString_;
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @return Whether the myString field is set.
-       */
-      @java.lang.Override
-      public boolean hasMyString() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @return The myString.
-       */
-      @java.lang.Override
-      public java.lang.String getMyString() {
-        return myString_;
-      }
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @return The bytes for myString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getMyStringBytes() {
-        return com.google.protobuf.ByteString.copyFromUtf8(myString_);
-      }
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @param value The myString to set.
-       */
-      private void setMyString(
-          java.lang.String value) {
-        value.getClass();
-  bitField0_ |= 0x00000001;
-        myString_ = value;
-      }
-      /**
-       * <code>optional string my_string = 1;</code>
-       */
-      private void clearMyString() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        myString_ = getDefaultInstance().getMyString();
-      }
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @param value The bytes for myString to set.
-       */
-      private void setMyStringBytes(
-          com.google.protobuf.ByteString value) {
-        myString_ = value.toStringUtf8();
-        bitField0_ |= 0x00000001;
-      }
-
-      public static protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3 parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3 parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3 parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3 parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3 parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3 parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3 parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3 parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3 parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3 parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3 parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3 parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3 prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestExtensionOrderings2.TestExtensionOrderings3}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestExtensionOrderings2.TestExtensionOrderings3)
-          protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3OrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional string my_string = 1;</code>
-         * @return Whether the myString field is set.
-         */
-        @java.lang.Override
-        public boolean hasMyString() {
-          return instance.hasMyString();
-        }
-        /**
-         * <code>optional string my_string = 1;</code>
-         * @return The myString.
-         */
-        @java.lang.Override
-        public java.lang.String getMyString() {
-          return instance.getMyString();
-        }
-        /**
-         * <code>optional string my_string = 1;</code>
-         * @return The bytes for myString.
-         */
-        @java.lang.Override
-        public com.google.protobuf.ByteString
-            getMyStringBytes() {
-          return instance.getMyStringBytes();
-        }
-        /**
-         * <code>optional string my_string = 1;</code>
-         * @param value The myString to set.
-         * @return This builder for chaining.
-         */
-        public Builder setMyString(
-            java.lang.String value) {
-          copyOnWrite();
-          instance.setMyString(value);
-          return this;
-        }
-        /**
-         * <code>optional string my_string = 1;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearMyString() {
-          copyOnWrite();
-          instance.clearMyString();
-          return this;
-        }
-        /**
-         * <code>optional string my_string = 1;</code>
-         * @param value The bytes for myString to set.
-         * @return This builder for chaining.
-         */
-        public Builder setMyStringBytes(
-            com.google.protobuf.ByteString value) {
-          copyOnWrite();
-          instance.setMyStringBytes(value);
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestExtensionOrderings2.TestExtensionOrderings3)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "myString_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1008\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestExtensionOrderings2.TestExtensionOrderings3)
-      private static final protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3 DEFAULT_INSTANCE;
-      static {
-        TestExtensionOrderings3 defaultInstance = new TestExtensionOrderings3();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          TestExtensionOrderings3.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3 getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<TestExtensionOrderings3> PARSER;
-
-      public static com.google.protobuf.Parser<TestExtensionOrderings3> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-      public static final int TEST_EXT_ORDERINGS3_FIELD_NUMBER = 14;
-      /**
-       * <code>extend .protobuf_unittest.TestFieldOrderings { ... }</code>
-       */
-      public static final
-        com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-          protobuf_unittest.UnittestProto.TestFieldOrderings,
-          protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3> testExtOrderings3 = com.google.protobuf.GeneratedMessageLite
-              .newSingularGeneratedExtension(
-            protobuf_unittest.UnittestProto.TestFieldOrderings.getDefaultInstance(),
-            protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3.getDefaultInstance(),
-            protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3.getDefaultInstance(),
-            null,
-            14,
-            com.google.protobuf.WireFormat.FieldType.MESSAGE,
-            protobuf_unittest.UnittestProto.TestExtensionOrderings2.TestExtensionOrderings3.class);
-    }
-
-    private int bitField0_;
-    public static final int MY_STRING_FIELD_NUMBER = 1;
-    private java.lang.String myString_;
-    /**
-     * <code>optional string my_string = 1;</code>
-     * @return Whether the myString field is set.
-     */
-    @java.lang.Override
-    public boolean hasMyString() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional string my_string = 1;</code>
-     * @return The myString.
-     */
-    @java.lang.Override
-    public java.lang.String getMyString() {
-      return myString_;
-    }
-    /**
-     * <code>optional string my_string = 1;</code>
-     * @return The bytes for myString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getMyStringBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(myString_);
-    }
-    /**
-     * <code>optional string my_string = 1;</code>
-     * @param value The myString to set.
-     */
-    private void setMyString(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00000001;
-      myString_ = value;
-    }
-    /**
-     * <code>optional string my_string = 1;</code>
-     */
-    private void clearMyString() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      myString_ = getDefaultInstance().getMyString();
-    }
-    /**
-     * <code>optional string my_string = 1;</code>
-     * @param value The bytes for myString to set.
-     */
-    private void setMyStringBytes(
-        com.google.protobuf.ByteString value) {
-      myString_ = value.toStringUtf8();
-      bitField0_ |= 0x00000001;
-    }
-
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings2 parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings2 parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings2 parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings2 parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings2 parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings2 parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings2 parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings2 parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings2 parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings2 parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings2 parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings2 parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestExtensionOrderings2 prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestExtensionOrderings2}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestExtensionOrderings2, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestExtensionOrderings2)
-        protobuf_unittest.UnittestProto.TestExtensionOrderings2OrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestExtensionOrderings2.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @return Whether the myString field is set.
-       */
-      @java.lang.Override
-      public boolean hasMyString() {
-        return instance.hasMyString();
-      }
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @return The myString.
-       */
-      @java.lang.Override
-      public java.lang.String getMyString() {
-        return instance.getMyString();
-      }
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @return The bytes for myString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getMyStringBytes() {
-        return instance.getMyStringBytes();
-      }
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @param value The myString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setMyString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setMyString(value);
-        return this;
-      }
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearMyString() {
-        copyOnWrite();
-        instance.clearMyString();
-        return this;
-      }
-      /**
-       * <code>optional string my_string = 1;</code>
-       * @param value The bytes for myString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setMyStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setMyStringBytes(value);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestExtensionOrderings2)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestExtensionOrderings2();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "myString_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1008\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestExtensionOrderings2> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestExtensionOrderings2.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestExtensionOrderings2>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestExtensionOrderings2)
-    private static final protobuf_unittest.UnittestProto.TestExtensionOrderings2 DEFAULT_INSTANCE;
-    static {
-      TestExtensionOrderings2 defaultInstance = new TestExtensionOrderings2();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestExtensionOrderings2.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestExtensionOrderings2 getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestExtensionOrderings2> PARSER;
-
-    public static com.google.protobuf.Parser<TestExtensionOrderings2> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-    public static final int TEST_EXT_ORDERINGS2_FIELD_NUMBER = 12;
-    /**
-     * <code>extend .protobuf_unittest.TestFieldOrderings { ... }</code>
-     */
-    public static final
-      com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-        protobuf_unittest.UnittestProto.TestFieldOrderings,
-        protobuf_unittest.UnittestProto.TestExtensionOrderings2> testExtOrderings2 = com.google.protobuf.GeneratedMessageLite
-            .newSingularGeneratedExtension(
-          protobuf_unittest.UnittestProto.TestFieldOrderings.getDefaultInstance(),
-          protobuf_unittest.UnittestProto.TestExtensionOrderings2.getDefaultInstance(),
-          protobuf_unittest.UnittestProto.TestExtensionOrderings2.getDefaultInstance(),
-          null,
-          12,
-          com.google.protobuf.WireFormat.FieldType.MESSAGE,
-          protobuf_unittest.UnittestProto.TestExtensionOrderings2.class);
-  }
-
-  public interface TestExtremeDefaultValuesOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestExtremeDefaultValues)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional bytes escaped_bytes = 1 [default = "&#92;000&#92;001&#92;007&#92;010&#92;014&#92;n&#92;r&#92;t&#92;013&#92;&#92;&#92;'&#92;"&#92;376"];</code>
-     * @return Whether the escapedBytes field is set.
-     */
-    boolean hasEscapedBytes();
-    /**
-     * <code>optional bytes escaped_bytes = 1 [default = "&#92;000&#92;001&#92;007&#92;010&#92;014&#92;n&#92;r&#92;t&#92;013&#92;&#92;&#92;'&#92;"&#92;376"];</code>
-     * @return The escapedBytes.
-     */
-    com.google.protobuf.ByteString getEscapedBytes();
-
-    /**
-     * <code>optional uint32 large_uint32 = 2 [default = 4294967295];</code>
-     * @return Whether the largeUint32 field is set.
-     */
-    boolean hasLargeUint32();
-    /**
-     * <code>optional uint32 large_uint32 = 2 [default = 4294967295];</code>
-     * @return The largeUint32.
-     */
-    int getLargeUint32();
-
-    /**
-     * <code>optional uint64 large_uint64 = 3 [default = 18446744073709551615];</code>
-     * @return Whether the largeUint64 field is set.
-     */
-    boolean hasLargeUint64();
-    /**
-     * <code>optional uint64 large_uint64 = 3 [default = 18446744073709551615];</code>
-     * @return The largeUint64.
-     */
-    long getLargeUint64();
-
-    /**
-     * <code>optional int32 small_int32 = 4 [default = -2147483647];</code>
-     * @return Whether the smallInt32 field is set.
-     */
-    boolean hasSmallInt32();
-    /**
-     * <code>optional int32 small_int32 = 4 [default = -2147483647];</code>
-     * @return The smallInt32.
-     */
-    int getSmallInt32();
-
-    /**
-     * <code>optional int64 small_int64 = 5 [default = -9223372036854775807];</code>
-     * @return Whether the smallInt64 field is set.
-     */
-    boolean hasSmallInt64();
-    /**
-     * <code>optional int64 small_int64 = 5 [default = -9223372036854775807];</code>
-     * @return The smallInt64.
-     */
-    long getSmallInt64();
-
-    /**
-     * <code>optional int32 really_small_int32 = 21 [default = -2147483648];</code>
-     * @return Whether the reallySmallInt32 field is set.
-     */
-    boolean hasReallySmallInt32();
-    /**
-     * <code>optional int32 really_small_int32 = 21 [default = -2147483648];</code>
-     * @return The reallySmallInt32.
-     */
-    int getReallySmallInt32();
-
-    /**
-     * <code>optional int64 really_small_int64 = 22 [default = -9223372036854775808];</code>
-     * @return Whether the reallySmallInt64 field is set.
-     */
-    boolean hasReallySmallInt64();
-    /**
-     * <code>optional int64 really_small_int64 = 22 [default = -9223372036854775808];</code>
-     * @return The reallySmallInt64.
-     */
-    long getReallySmallInt64();
-
-    /**
-     * <pre>
-     * The default value here is UTF-8 for "&#92;u1234".  (We could also just type
-     * the UTF-8 text directly into this text file rather than escape it, but
-     * lots of people use editors that would be confused by this.)
-     * </pre>
-     *
-     * <code>optional string utf8_string = 6 [default = "&#92;341&#92;210&#92;264"];</code>
-     * @return Whether the utf8String field is set.
-     */
-    boolean hasUtf8String();
-    /**
-     * <pre>
-     * The default value here is UTF-8 for "&#92;u1234".  (We could also just type
-     * the UTF-8 text directly into this text file rather than escape it, but
-     * lots of people use editors that would be confused by this.)
-     * </pre>
-     *
-     * <code>optional string utf8_string = 6 [default = "&#92;341&#92;210&#92;264"];</code>
-     * @return The utf8String.
-     */
-    java.lang.String getUtf8String();
-    /**
-     * <pre>
-     * The default value here is UTF-8 for "&#92;u1234".  (We could also just type
-     * the UTF-8 text directly into this text file rather than escape it, but
-     * lots of people use editors that would be confused by this.)
-     * </pre>
-     *
-     * <code>optional string utf8_string = 6 [default = "&#92;341&#92;210&#92;264"];</code>
-     * @return The bytes for utf8String.
-     */
-    com.google.protobuf.ByteString
-        getUtf8StringBytes();
-
-    /**
-     * <pre>
-     * Tests for single-precision floating-point values.
-     * </pre>
-     *
-     * <code>optional float zero_float = 7 [default = 0];</code>
-     * @return Whether the zeroFloat field is set.
-     */
-    boolean hasZeroFloat();
-    /**
-     * <pre>
-     * Tests for single-precision floating-point values.
-     * </pre>
-     *
-     * <code>optional float zero_float = 7 [default = 0];</code>
-     * @return The zeroFloat.
-     */
-    float getZeroFloat();
-
-    /**
-     * <code>optional float one_float = 8 [default = 1];</code>
-     * @return Whether the oneFloat field is set.
-     */
-    boolean hasOneFloat();
-    /**
-     * <code>optional float one_float = 8 [default = 1];</code>
-     * @return The oneFloat.
-     */
-    float getOneFloat();
-
-    /**
-     * <code>optional float small_float = 9 [default = 1.5];</code>
-     * @return Whether the smallFloat field is set.
-     */
-    boolean hasSmallFloat();
-    /**
-     * <code>optional float small_float = 9 [default = 1.5];</code>
-     * @return The smallFloat.
-     */
-    float getSmallFloat();
-
-    /**
-     * <code>optional float negative_one_float = 10 [default = -1];</code>
-     * @return Whether the negativeOneFloat field is set.
-     */
-    boolean hasNegativeOneFloat();
-    /**
-     * <code>optional float negative_one_float = 10 [default = -1];</code>
-     * @return The negativeOneFloat.
-     */
-    float getNegativeOneFloat();
-
-    /**
-     * <code>optional float negative_float = 11 [default = -1.5];</code>
-     * @return Whether the negativeFloat field is set.
-     */
-    boolean hasNegativeFloat();
-    /**
-     * <code>optional float negative_float = 11 [default = -1.5];</code>
-     * @return The negativeFloat.
-     */
-    float getNegativeFloat();
-
-    /**
-     * <pre>
-     * Using exponents
-     * </pre>
-     *
-     * <code>optional float large_float = 12 [default = 2e+08];</code>
-     * @return Whether the largeFloat field is set.
-     */
-    boolean hasLargeFloat();
-    /**
-     * <pre>
-     * Using exponents
-     * </pre>
-     *
-     * <code>optional float large_float = 12 [default = 2e+08];</code>
-     * @return The largeFloat.
-     */
-    float getLargeFloat();
-
-    /**
-     * <code>optional float small_negative_float = 13 [default = -8e-28];</code>
-     * @return Whether the smallNegativeFloat field is set.
-     */
-    boolean hasSmallNegativeFloat();
-    /**
-     * <code>optional float small_negative_float = 13 [default = -8e-28];</code>
-     * @return The smallNegativeFloat.
-     */
-    float getSmallNegativeFloat();
-
-    /**
-     * <pre>
-     * Text for nonfinite floating-point values.
-     * </pre>
-     *
-     * <code>optional double inf_double = 14 [default = inf];</code>
-     * @return Whether the infDouble field is set.
-     */
-    boolean hasInfDouble();
-    /**
-     * <pre>
-     * Text for nonfinite floating-point values.
-     * </pre>
-     *
-     * <code>optional double inf_double = 14 [default = inf];</code>
-     * @return The infDouble.
-     */
-    double getInfDouble();
-
-    /**
-     * <code>optional double neg_inf_double = 15 [default = -inf];</code>
-     * @return Whether the negInfDouble field is set.
-     */
-    boolean hasNegInfDouble();
-    /**
-     * <code>optional double neg_inf_double = 15 [default = -inf];</code>
-     * @return The negInfDouble.
-     */
-    double getNegInfDouble();
-
-    /**
-     * <code>optional double nan_double = 16 [default = nan];</code>
-     * @return Whether the nanDouble field is set.
-     */
-    boolean hasNanDouble();
-    /**
-     * <code>optional double nan_double = 16 [default = nan];</code>
-     * @return The nanDouble.
-     */
-    double getNanDouble();
-
-    /**
-     * <code>optional float inf_float = 17 [default = inf];</code>
-     * @return Whether the infFloat field is set.
-     */
-    boolean hasInfFloat();
-    /**
-     * <code>optional float inf_float = 17 [default = inf];</code>
-     * @return The infFloat.
-     */
-    float getInfFloat();
-
-    /**
-     * <code>optional float neg_inf_float = 18 [default = -inf];</code>
-     * @return Whether the negInfFloat field is set.
-     */
-    boolean hasNegInfFloat();
-    /**
-     * <code>optional float neg_inf_float = 18 [default = -inf];</code>
-     * @return The negInfFloat.
-     */
-    float getNegInfFloat();
-
-    /**
-     * <code>optional float nan_float = 19 [default = nan];</code>
-     * @return Whether the nanFloat field is set.
-     */
-    boolean hasNanFloat();
-    /**
-     * <code>optional float nan_float = 19 [default = nan];</code>
-     * @return The nanFloat.
-     */
-    float getNanFloat();
-
-    /**
-     * <pre>
-     * Tests for C++ trigraphs.
-     * Trigraphs should be escaped in C++ generated files, but they should not be
-     * escaped for other languages.
-     * Note that in .proto file, "&#92;?" is a valid way to escape ? in string
-     * literals.
-     * </pre>
-     *
-     * <code>optional string cpp_trigraph = 20 [default = "? ? ?? ?? ??? ??/ ??-"];</code>
-     * @return Whether the cppTrigraph field is set.
-     */
-    boolean hasCppTrigraph();
-    /**
-     * <pre>
-     * Tests for C++ trigraphs.
-     * Trigraphs should be escaped in C++ generated files, but they should not be
-     * escaped for other languages.
-     * Note that in .proto file, "&#92;?" is a valid way to escape ? in string
-     * literals.
-     * </pre>
-     *
-     * <code>optional string cpp_trigraph = 20 [default = "? ? ?? ?? ??? ??/ ??-"];</code>
-     * @return The cppTrigraph.
-     */
-    java.lang.String getCppTrigraph();
-    /**
-     * <pre>
-     * Tests for C++ trigraphs.
-     * Trigraphs should be escaped in C++ generated files, but they should not be
-     * escaped for other languages.
-     * Note that in .proto file, "&#92;?" is a valid way to escape ? in string
-     * literals.
-     * </pre>
-     *
-     * <code>optional string cpp_trigraph = 20 [default = "? ? ?? ?? ??? ??/ ??-"];</code>
-     * @return The bytes for cppTrigraph.
-     */
-    com.google.protobuf.ByteString
-        getCppTrigraphBytes();
-
-    /**
-     * <pre>
-     * String defaults containing the character '&#92;000'
-     * </pre>
-     *
-     * <code>optional string string_with_zero = 23 [default = "hel&#92;000lo"];</code>
-     * @return Whether the stringWithZero field is set.
-     */
-    boolean hasStringWithZero();
-    /**
-     * <pre>
-     * String defaults containing the character '&#92;000'
-     * </pre>
-     *
-     * <code>optional string string_with_zero = 23 [default = "hel&#92;000lo"];</code>
-     * @return The stringWithZero.
-     */
-    java.lang.String getStringWithZero();
-    /**
-     * <pre>
-     * String defaults containing the character '&#92;000'
-     * </pre>
-     *
-     * <code>optional string string_with_zero = 23 [default = "hel&#92;000lo"];</code>
-     * @return The bytes for stringWithZero.
-     */
-    com.google.protobuf.ByteString
-        getStringWithZeroBytes();
-
-    /**
-     * <code>optional bytes bytes_with_zero = 24 [default = "wor&#92;000ld"];</code>
-     * @return Whether the bytesWithZero field is set.
-     */
-    boolean hasBytesWithZero();
-    /**
-     * <code>optional bytes bytes_with_zero = 24 [default = "wor&#92;000ld"];</code>
-     * @return The bytesWithZero.
-     */
-    com.google.protobuf.ByteString getBytesWithZero();
-
-    /**
-     * <code>optional string string_piece_with_zero = 25 [default = "ab&#92;000c", ctype = STRING_PIECE];</code>
-     * @return Whether the stringPieceWithZero field is set.
-     */
-    boolean hasStringPieceWithZero();
-    /**
-     * <code>optional string string_piece_with_zero = 25 [default = "ab&#92;000c", ctype = STRING_PIECE];</code>
-     * @return The stringPieceWithZero.
-     */
-    java.lang.String getStringPieceWithZero();
-    /**
-     * <code>optional string string_piece_with_zero = 25 [default = "ab&#92;000c", ctype = STRING_PIECE];</code>
-     * @return The bytes for stringPieceWithZero.
-     */
-    com.google.protobuf.ByteString
-        getStringPieceWithZeroBytes();
-
-    /**
-     * <code>optional string cord_with_zero = 26 [default = "12&#92;0003", ctype = CORD];</code>
-     * @return Whether the cordWithZero field is set.
-     */
-    boolean hasCordWithZero();
-    /**
-     * <code>optional string cord_with_zero = 26 [default = "12&#92;0003", ctype = CORD];</code>
-     * @return The cordWithZero.
-     */
-    java.lang.String getCordWithZero();
-    /**
-     * <code>optional string cord_with_zero = 26 [default = "12&#92;0003", ctype = CORD];</code>
-     * @return The bytes for cordWithZero.
-     */
-    com.google.protobuf.ByteString
-        getCordWithZeroBytes();
-
-    /**
-     * <code>optional string replacement_string = 27 [default = "${unknown}"];</code>
-     * @return Whether the replacementString field is set.
-     */
-    boolean hasReplacementString();
-    /**
-     * <code>optional string replacement_string = 27 [default = "${unknown}"];</code>
-     * @return The replacementString.
-     */
-    java.lang.String getReplacementString();
-    /**
-     * <code>optional string replacement_string = 27 [default = "${unknown}"];</code>
-     * @return The bytes for replacementString.
-     */
-    com.google.protobuf.ByteString
-        getReplacementStringBytes();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestExtremeDefaultValues}
-   */
-  public  static final class TestExtremeDefaultValues extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestExtremeDefaultValues, TestExtremeDefaultValues.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestExtremeDefaultValues)
-      TestExtremeDefaultValuesOrBuilder {
-    private TestExtremeDefaultValues() {
-      escapedBytes_ = ESCAPEDBYTES_DEFAULT_VALUE;
-      largeUint32_ = -1;
-      largeUint64_ = -1L;
-      smallInt32_ = -2147483647;
-      smallInt64_ = -9223372036854775807L;
-      reallySmallInt32_ = -2147483648;
-      reallySmallInt64_ = -9223372036854775808L;
-      utf8String_ = com.google.protobuf.Internal.stringDefaultValue("\341\210\264");
-      oneFloat_ = 1F;
-      smallFloat_ = 1.5F;
-      negativeOneFloat_ = -1F;
-      negativeFloat_ = -1.5F;
-      largeFloat_ = 2e+08F;
-      smallNegativeFloat_ = -8e-28F;
-      infDouble_ = Double.POSITIVE_INFINITY;
-      negInfDouble_ = Double.NEGATIVE_INFINITY;
-      nanDouble_ = Double.NaN;
-      infFloat_ = Float.POSITIVE_INFINITY;
-      negInfFloat_ = Float.NEGATIVE_INFINITY;
-      nanFloat_ = Float.NaN;
-      cppTrigraph_ = "? ? ?? ?? ??? ??/ ??-";
-      stringWithZero_ = "hel\000lo";
-      bytesWithZero_ = BYTESWITHZERO_DEFAULT_VALUE;
-      stringPieceWithZero_ = "ab\000c";
-      cordWithZero_ = "12\0003";
-      replacementString_ = "${unknown}";
-    }
-    private int bitField0_;
-    public static final int ESCAPED_BYTES_FIELD_NUMBER = 1;
-    private static final com.google.protobuf.ByteString ESCAPEDBYTES_DEFAULT_VALUE = com.google.protobuf.Internal.bytesDefaultValue("\000\001\007\010\014\n\r\t\013\\\'\"\376");
-    private com.google.protobuf.ByteString escapedBytes_;
-    /**
-     * <code>optional bytes escaped_bytes = 1 [default = "&#92;000&#92;001&#92;007&#92;010&#92;014&#92;n&#92;r&#92;t&#92;013&#92;&#92;&#92;'&#92;"&#92;376"];</code>
-     * @return Whether the escapedBytes field is set.
-     */
-    @java.lang.Override
-    public boolean hasEscapedBytes() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional bytes escaped_bytes = 1 [default = "&#92;000&#92;001&#92;007&#92;010&#92;014&#92;n&#92;r&#92;t&#92;013&#92;&#92;&#92;'&#92;"&#92;376"];</code>
-     * @return The escapedBytes.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getEscapedBytes() {
-      return escapedBytes_;
-    }
-    /**
-     * <code>optional bytes escaped_bytes = 1 [default = "&#92;000&#92;001&#92;007&#92;010&#92;014&#92;n&#92;r&#92;t&#92;013&#92;&#92;&#92;'&#92;"&#92;376"];</code>
-     * @param value The escapedBytes to set.
-     */
-    private void setEscapedBytes(com.google.protobuf.ByteString value) {
-      value.getClass();
-  bitField0_ |= 0x00000001;
-      escapedBytes_ = value;
-    }
-    /**
-     * <code>optional bytes escaped_bytes = 1 [default = "&#92;000&#92;001&#92;007&#92;010&#92;014&#92;n&#92;r&#92;t&#92;013&#92;&#92;&#92;'&#92;"&#92;376"];</code>
-     */
-    private void clearEscapedBytes() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      escapedBytes_ = getDefaultInstance().getEscapedBytes();
-    }
-
-    public static final int LARGE_UINT32_FIELD_NUMBER = 2;
-    private int largeUint32_;
-    /**
-     * <code>optional uint32 large_uint32 = 2 [default = 4294967295];</code>
-     * @return Whether the largeUint32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasLargeUint32() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional uint32 large_uint32 = 2 [default = 4294967295];</code>
-     * @return The largeUint32.
-     */
-    @java.lang.Override
-    public int getLargeUint32() {
-      return largeUint32_;
-    }
-    /**
-     * <code>optional uint32 large_uint32 = 2 [default = 4294967295];</code>
-     * @param value The largeUint32 to set.
-     */
-    private void setLargeUint32(int value) {
-      bitField0_ |= 0x00000002;
-      largeUint32_ = value;
-    }
-    /**
-     * <code>optional uint32 large_uint32 = 2 [default = 4294967295];</code>
-     */
-    private void clearLargeUint32() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      largeUint32_ = -1;
-    }
-
-    public static final int LARGE_UINT64_FIELD_NUMBER = 3;
-    private long largeUint64_;
-    /**
-     * <code>optional uint64 large_uint64 = 3 [default = 18446744073709551615];</code>
-     * @return Whether the largeUint64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasLargeUint64() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional uint64 large_uint64 = 3 [default = 18446744073709551615];</code>
-     * @return The largeUint64.
-     */
-    @java.lang.Override
-    public long getLargeUint64() {
-      return largeUint64_;
-    }
-    /**
-     * <code>optional uint64 large_uint64 = 3 [default = 18446744073709551615];</code>
-     * @param value The largeUint64 to set.
-     */
-    private void setLargeUint64(long value) {
-      bitField0_ |= 0x00000004;
-      largeUint64_ = value;
-    }
-    /**
-     * <code>optional uint64 large_uint64 = 3 [default = 18446744073709551615];</code>
-     */
-    private void clearLargeUint64() {
-      bitField0_ = (bitField0_ & ~0x00000004);
-      largeUint64_ = -1L;
-    }
-
-    public static final int SMALL_INT32_FIELD_NUMBER = 4;
-    private int smallInt32_;
-    /**
-     * <code>optional int32 small_int32 = 4 [default = -2147483647];</code>
-     * @return Whether the smallInt32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasSmallInt32() {
-      return ((bitField0_ & 0x00000008) != 0);
-    }
-    /**
-     * <code>optional int32 small_int32 = 4 [default = -2147483647];</code>
-     * @return The smallInt32.
-     */
-    @java.lang.Override
-    public int getSmallInt32() {
-      return smallInt32_;
-    }
-    /**
-     * <code>optional int32 small_int32 = 4 [default = -2147483647];</code>
-     * @param value The smallInt32 to set.
-     */
-    private void setSmallInt32(int value) {
-      bitField0_ |= 0x00000008;
-      smallInt32_ = value;
-    }
-    /**
-     * <code>optional int32 small_int32 = 4 [default = -2147483647];</code>
-     */
-    private void clearSmallInt32() {
-      bitField0_ = (bitField0_ & ~0x00000008);
-      smallInt32_ = -2147483647;
-    }
-
-    public static final int SMALL_INT64_FIELD_NUMBER = 5;
-    private long smallInt64_;
-    /**
-     * <code>optional int64 small_int64 = 5 [default = -9223372036854775807];</code>
-     * @return Whether the smallInt64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasSmallInt64() {
-      return ((bitField0_ & 0x00000010) != 0);
-    }
-    /**
-     * <code>optional int64 small_int64 = 5 [default = -9223372036854775807];</code>
-     * @return The smallInt64.
-     */
-    @java.lang.Override
-    public long getSmallInt64() {
-      return smallInt64_;
-    }
-    /**
-     * <code>optional int64 small_int64 = 5 [default = -9223372036854775807];</code>
-     * @param value The smallInt64 to set.
-     */
-    private void setSmallInt64(long value) {
-      bitField0_ |= 0x00000010;
-      smallInt64_ = value;
-    }
-    /**
-     * <code>optional int64 small_int64 = 5 [default = -9223372036854775807];</code>
-     */
-    private void clearSmallInt64() {
-      bitField0_ = (bitField0_ & ~0x00000010);
-      smallInt64_ = -9223372036854775807L;
-    }
-
-    public static final int REALLY_SMALL_INT32_FIELD_NUMBER = 21;
-    private int reallySmallInt32_;
-    /**
-     * <code>optional int32 really_small_int32 = 21 [default = -2147483648];</code>
-     * @return Whether the reallySmallInt32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasReallySmallInt32() {
-      return ((bitField0_ & 0x00000020) != 0);
-    }
-    /**
-     * <code>optional int32 really_small_int32 = 21 [default = -2147483648];</code>
-     * @return The reallySmallInt32.
-     */
-    @java.lang.Override
-    public int getReallySmallInt32() {
-      return reallySmallInt32_;
-    }
-    /**
-     * <code>optional int32 really_small_int32 = 21 [default = -2147483648];</code>
-     * @param value The reallySmallInt32 to set.
-     */
-    private void setReallySmallInt32(int value) {
-      bitField0_ |= 0x00000020;
-      reallySmallInt32_ = value;
-    }
-    /**
-     * <code>optional int32 really_small_int32 = 21 [default = -2147483648];</code>
-     */
-    private void clearReallySmallInt32() {
-      bitField0_ = (bitField0_ & ~0x00000020);
-      reallySmallInt32_ = -2147483648;
-    }
-
-    public static final int REALLY_SMALL_INT64_FIELD_NUMBER = 22;
-    private long reallySmallInt64_;
-    /**
-     * <code>optional int64 really_small_int64 = 22 [default = -9223372036854775808];</code>
-     * @return Whether the reallySmallInt64 field is set.
-     */
-    @java.lang.Override
-    public boolean hasReallySmallInt64() {
-      return ((bitField0_ & 0x00000040) != 0);
-    }
-    /**
-     * <code>optional int64 really_small_int64 = 22 [default = -9223372036854775808];</code>
-     * @return The reallySmallInt64.
-     */
-    @java.lang.Override
-    public long getReallySmallInt64() {
-      return reallySmallInt64_;
-    }
-    /**
-     * <code>optional int64 really_small_int64 = 22 [default = -9223372036854775808];</code>
-     * @param value The reallySmallInt64 to set.
-     */
-    private void setReallySmallInt64(long value) {
-      bitField0_ |= 0x00000040;
-      reallySmallInt64_ = value;
-    }
-    /**
-     * <code>optional int64 really_small_int64 = 22 [default = -9223372036854775808];</code>
-     */
-    private void clearReallySmallInt64() {
-      bitField0_ = (bitField0_ & ~0x00000040);
-      reallySmallInt64_ = -9223372036854775808L;
-    }
-
-    public static final int UTF8_STRING_FIELD_NUMBER = 6;
-    private java.lang.String utf8String_;
-    /**
-     * <pre>
-     * The default value here is UTF-8 for "&#92;u1234".  (We could also just type
-     * the UTF-8 text directly into this text file rather than escape it, but
-     * lots of people use editors that would be confused by this.)
-     * </pre>
-     *
-     * <code>optional string utf8_string = 6 [default = "&#92;341&#92;210&#92;264"];</code>
-     * @return Whether the utf8String field is set.
-     */
-    @java.lang.Override
-    public boolean hasUtf8String() {
-      return ((bitField0_ & 0x00000080) != 0);
-    }
-    /**
-     * <pre>
-     * The default value here is UTF-8 for "&#92;u1234".  (We could also just type
-     * the UTF-8 text directly into this text file rather than escape it, but
-     * lots of people use editors that would be confused by this.)
-     * </pre>
-     *
-     * <code>optional string utf8_string = 6 [default = "&#92;341&#92;210&#92;264"];</code>
-     * @return The utf8String.
-     */
-    @java.lang.Override
-    public java.lang.String getUtf8String() {
-      return utf8String_;
-    }
-    /**
-     * <pre>
-     * The default value here is UTF-8 for "&#92;u1234".  (We could also just type
-     * the UTF-8 text directly into this text file rather than escape it, but
-     * lots of people use editors that would be confused by this.)
-     * </pre>
-     *
-     * <code>optional string utf8_string = 6 [default = "&#92;341&#92;210&#92;264"];</code>
-     * @return The bytes for utf8String.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getUtf8StringBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(utf8String_);
-    }
-    /**
-     * <pre>
-     * The default value here is UTF-8 for "&#92;u1234".  (We could also just type
-     * the UTF-8 text directly into this text file rather than escape it, but
-     * lots of people use editors that would be confused by this.)
-     * </pre>
-     *
-     * <code>optional string utf8_string = 6 [default = "&#92;341&#92;210&#92;264"];</code>
-     * @param value The utf8String to set.
-     */
-    private void setUtf8String(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00000080;
-      utf8String_ = value;
-    }
-    /**
-     * <pre>
-     * The default value here is UTF-8 for "&#92;u1234".  (We could also just type
-     * the UTF-8 text directly into this text file rather than escape it, but
-     * lots of people use editors that would be confused by this.)
-     * </pre>
-     *
-     * <code>optional string utf8_string = 6 [default = "&#92;341&#92;210&#92;264"];</code>
-     */
-    private void clearUtf8String() {
-      bitField0_ = (bitField0_ & ~0x00000080);
-      utf8String_ = getDefaultInstance().getUtf8String();
-    }
-    /**
-     * <pre>
-     * The default value here is UTF-8 for "&#92;u1234".  (We could also just type
-     * the UTF-8 text directly into this text file rather than escape it, but
-     * lots of people use editors that would be confused by this.)
-     * </pre>
-     *
-     * <code>optional string utf8_string = 6 [default = "&#92;341&#92;210&#92;264"];</code>
-     * @param value The bytes for utf8String to set.
-     */
-    private void setUtf8StringBytes(
-        com.google.protobuf.ByteString value) {
-      utf8String_ = value.toStringUtf8();
-      bitField0_ |= 0x00000080;
-    }
-
-    public static final int ZERO_FLOAT_FIELD_NUMBER = 7;
-    private float zeroFloat_;
-    /**
-     * <pre>
-     * Tests for single-precision floating-point values.
-     * </pre>
-     *
-     * <code>optional float zero_float = 7 [default = 0];</code>
-     * @return Whether the zeroFloat field is set.
-     */
-    @java.lang.Override
-    public boolean hasZeroFloat() {
-      return ((bitField0_ & 0x00000100) != 0);
-    }
-    /**
-     * <pre>
-     * Tests for single-precision floating-point values.
-     * </pre>
-     *
-     * <code>optional float zero_float = 7 [default = 0];</code>
-     * @return The zeroFloat.
-     */
-    @java.lang.Override
-    public float getZeroFloat() {
-      return zeroFloat_;
-    }
-    /**
-     * <pre>
-     * Tests for single-precision floating-point values.
-     * </pre>
-     *
-     * <code>optional float zero_float = 7 [default = 0];</code>
-     * @param value The zeroFloat to set.
-     */
-    private void setZeroFloat(float value) {
-      bitField0_ |= 0x00000100;
-      zeroFloat_ = value;
-    }
-    /**
-     * <pre>
-     * Tests for single-precision floating-point values.
-     * </pre>
-     *
-     * <code>optional float zero_float = 7 [default = 0];</code>
-     */
-    private void clearZeroFloat() {
-      bitField0_ = (bitField0_ & ~0x00000100);
-      zeroFloat_ = 0F;
-    }
-
-    public static final int ONE_FLOAT_FIELD_NUMBER = 8;
-    private float oneFloat_;
-    /**
-     * <code>optional float one_float = 8 [default = 1];</code>
-     * @return Whether the oneFloat field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneFloat() {
-      return ((bitField0_ & 0x00000200) != 0);
-    }
-    /**
-     * <code>optional float one_float = 8 [default = 1];</code>
-     * @return The oneFloat.
-     */
-    @java.lang.Override
-    public float getOneFloat() {
-      return oneFloat_;
-    }
-    /**
-     * <code>optional float one_float = 8 [default = 1];</code>
-     * @param value The oneFloat to set.
-     */
-    private void setOneFloat(float value) {
-      bitField0_ |= 0x00000200;
-      oneFloat_ = value;
-    }
-    /**
-     * <code>optional float one_float = 8 [default = 1];</code>
-     */
-    private void clearOneFloat() {
-      bitField0_ = (bitField0_ & ~0x00000200);
-      oneFloat_ = 1F;
-    }
-
-    public static final int SMALL_FLOAT_FIELD_NUMBER = 9;
-    private float smallFloat_;
-    /**
-     * <code>optional float small_float = 9 [default = 1.5];</code>
-     * @return Whether the smallFloat field is set.
-     */
-    @java.lang.Override
-    public boolean hasSmallFloat() {
-      return ((bitField0_ & 0x00000400) != 0);
-    }
-    /**
-     * <code>optional float small_float = 9 [default = 1.5];</code>
-     * @return The smallFloat.
-     */
-    @java.lang.Override
-    public float getSmallFloat() {
-      return smallFloat_;
-    }
-    /**
-     * <code>optional float small_float = 9 [default = 1.5];</code>
-     * @param value The smallFloat to set.
-     */
-    private void setSmallFloat(float value) {
-      bitField0_ |= 0x00000400;
-      smallFloat_ = value;
-    }
-    /**
-     * <code>optional float small_float = 9 [default = 1.5];</code>
-     */
-    private void clearSmallFloat() {
-      bitField0_ = (bitField0_ & ~0x00000400);
-      smallFloat_ = 1.5F;
-    }
-
-    public static final int NEGATIVE_ONE_FLOAT_FIELD_NUMBER = 10;
-    private float negativeOneFloat_;
-    /**
-     * <code>optional float negative_one_float = 10 [default = -1];</code>
-     * @return Whether the negativeOneFloat field is set.
-     */
-    @java.lang.Override
-    public boolean hasNegativeOneFloat() {
-      return ((bitField0_ & 0x00000800) != 0);
-    }
-    /**
-     * <code>optional float negative_one_float = 10 [default = -1];</code>
-     * @return The negativeOneFloat.
-     */
-    @java.lang.Override
-    public float getNegativeOneFloat() {
-      return negativeOneFloat_;
-    }
-    /**
-     * <code>optional float negative_one_float = 10 [default = -1];</code>
-     * @param value The negativeOneFloat to set.
-     */
-    private void setNegativeOneFloat(float value) {
-      bitField0_ |= 0x00000800;
-      negativeOneFloat_ = value;
-    }
-    /**
-     * <code>optional float negative_one_float = 10 [default = -1];</code>
-     */
-    private void clearNegativeOneFloat() {
-      bitField0_ = (bitField0_ & ~0x00000800);
-      negativeOneFloat_ = -1F;
-    }
-
-    public static final int NEGATIVE_FLOAT_FIELD_NUMBER = 11;
-    private float negativeFloat_;
-    /**
-     * <code>optional float negative_float = 11 [default = -1.5];</code>
-     * @return Whether the negativeFloat field is set.
-     */
-    @java.lang.Override
-    public boolean hasNegativeFloat() {
-      return ((bitField0_ & 0x00001000) != 0);
-    }
-    /**
-     * <code>optional float negative_float = 11 [default = -1.5];</code>
-     * @return The negativeFloat.
-     */
-    @java.lang.Override
-    public float getNegativeFloat() {
-      return negativeFloat_;
-    }
-    /**
-     * <code>optional float negative_float = 11 [default = -1.5];</code>
-     * @param value The negativeFloat to set.
-     */
-    private void setNegativeFloat(float value) {
-      bitField0_ |= 0x00001000;
-      negativeFloat_ = value;
-    }
-    /**
-     * <code>optional float negative_float = 11 [default = -1.5];</code>
-     */
-    private void clearNegativeFloat() {
-      bitField0_ = (bitField0_ & ~0x00001000);
-      negativeFloat_ = -1.5F;
-    }
-
-    public static final int LARGE_FLOAT_FIELD_NUMBER = 12;
-    private float largeFloat_;
-    /**
-     * <pre>
-     * Using exponents
-     * </pre>
-     *
-     * <code>optional float large_float = 12 [default = 2e+08];</code>
-     * @return Whether the largeFloat field is set.
-     */
-    @java.lang.Override
-    public boolean hasLargeFloat() {
-      return ((bitField0_ & 0x00002000) != 0);
-    }
-    /**
-     * <pre>
-     * Using exponents
-     * </pre>
-     *
-     * <code>optional float large_float = 12 [default = 2e+08];</code>
-     * @return The largeFloat.
-     */
-    @java.lang.Override
-    public float getLargeFloat() {
-      return largeFloat_;
-    }
-    /**
-     * <pre>
-     * Using exponents
-     * </pre>
-     *
-     * <code>optional float large_float = 12 [default = 2e+08];</code>
-     * @param value The largeFloat to set.
-     */
-    private void setLargeFloat(float value) {
-      bitField0_ |= 0x00002000;
-      largeFloat_ = value;
-    }
-    /**
-     * <pre>
-     * Using exponents
-     * </pre>
-     *
-     * <code>optional float large_float = 12 [default = 2e+08];</code>
-     */
-    private void clearLargeFloat() {
-      bitField0_ = (bitField0_ & ~0x00002000);
-      largeFloat_ = 2e+08F;
-    }
-
-    public static final int SMALL_NEGATIVE_FLOAT_FIELD_NUMBER = 13;
-    private float smallNegativeFloat_;
-    /**
-     * <code>optional float small_negative_float = 13 [default = -8e-28];</code>
-     * @return Whether the smallNegativeFloat field is set.
-     */
-    @java.lang.Override
-    public boolean hasSmallNegativeFloat() {
-      return ((bitField0_ & 0x00004000) != 0);
-    }
-    /**
-     * <code>optional float small_negative_float = 13 [default = -8e-28];</code>
-     * @return The smallNegativeFloat.
-     */
-    @java.lang.Override
-    public float getSmallNegativeFloat() {
-      return smallNegativeFloat_;
-    }
-    /**
-     * <code>optional float small_negative_float = 13 [default = -8e-28];</code>
-     * @param value The smallNegativeFloat to set.
-     */
-    private void setSmallNegativeFloat(float value) {
-      bitField0_ |= 0x00004000;
-      smallNegativeFloat_ = value;
-    }
-    /**
-     * <code>optional float small_negative_float = 13 [default = -8e-28];</code>
-     */
-    private void clearSmallNegativeFloat() {
-      bitField0_ = (bitField0_ & ~0x00004000);
-      smallNegativeFloat_ = -8e-28F;
-    }
-
-    public static final int INF_DOUBLE_FIELD_NUMBER = 14;
-    private double infDouble_;
-    /**
-     * <pre>
-     * Text for nonfinite floating-point values.
-     * </pre>
-     *
-     * <code>optional double inf_double = 14 [default = inf];</code>
-     * @return Whether the infDouble field is set.
-     */
-    @java.lang.Override
-    public boolean hasInfDouble() {
-      return ((bitField0_ & 0x00008000) != 0);
-    }
-    /**
-     * <pre>
-     * Text for nonfinite floating-point values.
-     * </pre>
-     *
-     * <code>optional double inf_double = 14 [default = inf];</code>
-     * @return The infDouble.
-     */
-    @java.lang.Override
-    public double getInfDouble() {
-      return infDouble_;
-    }
-    /**
-     * <pre>
-     * Text for nonfinite floating-point values.
-     * </pre>
-     *
-     * <code>optional double inf_double = 14 [default = inf];</code>
-     * @param value The infDouble to set.
-     */
-    private void setInfDouble(double value) {
-      bitField0_ |= 0x00008000;
-      infDouble_ = value;
-    }
-    /**
-     * <pre>
-     * Text for nonfinite floating-point values.
-     * </pre>
-     *
-     * <code>optional double inf_double = 14 [default = inf];</code>
-     */
-    private void clearInfDouble() {
-      bitField0_ = (bitField0_ & ~0x00008000);
-      infDouble_ = Double.POSITIVE_INFINITY;
-    }
-
-    public static final int NEG_INF_DOUBLE_FIELD_NUMBER = 15;
-    private double negInfDouble_;
-    /**
-     * <code>optional double neg_inf_double = 15 [default = -inf];</code>
-     * @return Whether the negInfDouble field is set.
-     */
-    @java.lang.Override
-    public boolean hasNegInfDouble() {
-      return ((bitField0_ & 0x00010000) != 0);
-    }
-    /**
-     * <code>optional double neg_inf_double = 15 [default = -inf];</code>
-     * @return The negInfDouble.
-     */
-    @java.lang.Override
-    public double getNegInfDouble() {
-      return negInfDouble_;
-    }
-    /**
-     * <code>optional double neg_inf_double = 15 [default = -inf];</code>
-     * @param value The negInfDouble to set.
-     */
-    private void setNegInfDouble(double value) {
-      bitField0_ |= 0x00010000;
-      negInfDouble_ = value;
-    }
-    /**
-     * <code>optional double neg_inf_double = 15 [default = -inf];</code>
-     */
-    private void clearNegInfDouble() {
-      bitField0_ = (bitField0_ & ~0x00010000);
-      negInfDouble_ = Double.NEGATIVE_INFINITY;
-    }
-
-    public static final int NAN_DOUBLE_FIELD_NUMBER = 16;
-    private double nanDouble_;
-    /**
-     * <code>optional double nan_double = 16 [default = nan];</code>
-     * @return Whether the nanDouble field is set.
-     */
-    @java.lang.Override
-    public boolean hasNanDouble() {
-      return ((bitField0_ & 0x00020000) != 0);
-    }
-    /**
-     * <code>optional double nan_double = 16 [default = nan];</code>
-     * @return The nanDouble.
-     */
-    @java.lang.Override
-    public double getNanDouble() {
-      return nanDouble_;
-    }
-    /**
-     * <code>optional double nan_double = 16 [default = nan];</code>
-     * @param value The nanDouble to set.
-     */
-    private void setNanDouble(double value) {
-      bitField0_ |= 0x00020000;
-      nanDouble_ = value;
-    }
-    /**
-     * <code>optional double nan_double = 16 [default = nan];</code>
-     */
-    private void clearNanDouble() {
-      bitField0_ = (bitField0_ & ~0x00020000);
-      nanDouble_ = Double.NaN;
-    }
-
-    public static final int INF_FLOAT_FIELD_NUMBER = 17;
-    private float infFloat_;
-    /**
-     * <code>optional float inf_float = 17 [default = inf];</code>
-     * @return Whether the infFloat field is set.
-     */
-    @java.lang.Override
-    public boolean hasInfFloat() {
-      return ((bitField0_ & 0x00040000) != 0);
-    }
-    /**
-     * <code>optional float inf_float = 17 [default = inf];</code>
-     * @return The infFloat.
-     */
-    @java.lang.Override
-    public float getInfFloat() {
-      return infFloat_;
-    }
-    /**
-     * <code>optional float inf_float = 17 [default = inf];</code>
-     * @param value The infFloat to set.
-     */
-    private void setInfFloat(float value) {
-      bitField0_ |= 0x00040000;
-      infFloat_ = value;
-    }
-    /**
-     * <code>optional float inf_float = 17 [default = inf];</code>
-     */
-    private void clearInfFloat() {
-      bitField0_ = (bitField0_ & ~0x00040000);
-      infFloat_ = Float.POSITIVE_INFINITY;
-    }
-
-    public static final int NEG_INF_FLOAT_FIELD_NUMBER = 18;
-    private float negInfFloat_;
-    /**
-     * <code>optional float neg_inf_float = 18 [default = -inf];</code>
-     * @return Whether the negInfFloat field is set.
-     */
-    @java.lang.Override
-    public boolean hasNegInfFloat() {
-      return ((bitField0_ & 0x00080000) != 0);
-    }
-    /**
-     * <code>optional float neg_inf_float = 18 [default = -inf];</code>
-     * @return The negInfFloat.
-     */
-    @java.lang.Override
-    public float getNegInfFloat() {
-      return negInfFloat_;
-    }
-    /**
-     * <code>optional float neg_inf_float = 18 [default = -inf];</code>
-     * @param value The negInfFloat to set.
-     */
-    private void setNegInfFloat(float value) {
-      bitField0_ |= 0x00080000;
-      negInfFloat_ = value;
-    }
-    /**
-     * <code>optional float neg_inf_float = 18 [default = -inf];</code>
-     */
-    private void clearNegInfFloat() {
-      bitField0_ = (bitField0_ & ~0x00080000);
-      negInfFloat_ = Float.NEGATIVE_INFINITY;
-    }
-
-    public static final int NAN_FLOAT_FIELD_NUMBER = 19;
-    private float nanFloat_;
-    /**
-     * <code>optional float nan_float = 19 [default = nan];</code>
-     * @return Whether the nanFloat field is set.
-     */
-    @java.lang.Override
-    public boolean hasNanFloat() {
-      return ((bitField0_ & 0x00100000) != 0);
-    }
-    /**
-     * <code>optional float nan_float = 19 [default = nan];</code>
-     * @return The nanFloat.
-     */
-    @java.lang.Override
-    public float getNanFloat() {
-      return nanFloat_;
-    }
-    /**
-     * <code>optional float nan_float = 19 [default = nan];</code>
-     * @param value The nanFloat to set.
-     */
-    private void setNanFloat(float value) {
-      bitField0_ |= 0x00100000;
-      nanFloat_ = value;
-    }
-    /**
-     * <code>optional float nan_float = 19 [default = nan];</code>
-     */
-    private void clearNanFloat() {
-      bitField0_ = (bitField0_ & ~0x00100000);
-      nanFloat_ = Float.NaN;
-    }
-
-    public static final int CPP_TRIGRAPH_FIELD_NUMBER = 20;
-    private java.lang.String cppTrigraph_;
-    /**
-     * <pre>
-     * Tests for C++ trigraphs.
-     * Trigraphs should be escaped in C++ generated files, but they should not be
-     * escaped for other languages.
-     * Note that in .proto file, "&#92;?" is a valid way to escape ? in string
-     * literals.
-     * </pre>
-     *
-     * <code>optional string cpp_trigraph = 20 [default = "? ? ?? ?? ??? ??/ ??-"];</code>
-     * @return Whether the cppTrigraph field is set.
-     */
-    @java.lang.Override
-    public boolean hasCppTrigraph() {
-      return ((bitField0_ & 0x00200000) != 0);
-    }
-    /**
-     * <pre>
-     * Tests for C++ trigraphs.
-     * Trigraphs should be escaped in C++ generated files, but they should not be
-     * escaped for other languages.
-     * Note that in .proto file, "&#92;?" is a valid way to escape ? in string
-     * literals.
-     * </pre>
-     *
-     * <code>optional string cpp_trigraph = 20 [default = "? ? ?? ?? ??? ??/ ??-"];</code>
-     * @return The cppTrigraph.
-     */
-    @java.lang.Override
-    public java.lang.String getCppTrigraph() {
-      return cppTrigraph_;
-    }
-    /**
-     * <pre>
-     * Tests for C++ trigraphs.
-     * Trigraphs should be escaped in C++ generated files, but they should not be
-     * escaped for other languages.
-     * Note that in .proto file, "&#92;?" is a valid way to escape ? in string
-     * literals.
-     * </pre>
-     *
-     * <code>optional string cpp_trigraph = 20 [default = "? ? ?? ?? ??? ??/ ??-"];</code>
-     * @return The bytes for cppTrigraph.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getCppTrigraphBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(cppTrigraph_);
-    }
-    /**
-     * <pre>
-     * Tests for C++ trigraphs.
-     * Trigraphs should be escaped in C++ generated files, but they should not be
-     * escaped for other languages.
-     * Note that in .proto file, "&#92;?" is a valid way to escape ? in string
-     * literals.
-     * </pre>
-     *
-     * <code>optional string cpp_trigraph = 20 [default = "? ? ?? ?? ??? ??/ ??-"];</code>
-     * @param value The cppTrigraph to set.
-     */
-    private void setCppTrigraph(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00200000;
-      cppTrigraph_ = value;
-    }
-    /**
-     * <pre>
-     * Tests for C++ trigraphs.
-     * Trigraphs should be escaped in C++ generated files, but they should not be
-     * escaped for other languages.
-     * Note that in .proto file, "&#92;?" is a valid way to escape ? in string
-     * literals.
-     * </pre>
-     *
-     * <code>optional string cpp_trigraph = 20 [default = "? ? ?? ?? ??? ??/ ??-"];</code>
-     */
-    private void clearCppTrigraph() {
-      bitField0_ = (bitField0_ & ~0x00200000);
-      cppTrigraph_ = getDefaultInstance().getCppTrigraph();
-    }
-    /**
-     * <pre>
-     * Tests for C++ trigraphs.
-     * Trigraphs should be escaped in C++ generated files, but they should not be
-     * escaped for other languages.
-     * Note that in .proto file, "&#92;?" is a valid way to escape ? in string
-     * literals.
-     * </pre>
-     *
-     * <code>optional string cpp_trigraph = 20 [default = "? ? ?? ?? ??? ??/ ??-"];</code>
-     * @param value The bytes for cppTrigraph to set.
-     */
-    private void setCppTrigraphBytes(
-        com.google.protobuf.ByteString value) {
-      cppTrigraph_ = value.toStringUtf8();
-      bitField0_ |= 0x00200000;
-    }
-
-    public static final int STRING_WITH_ZERO_FIELD_NUMBER = 23;
-    private java.lang.String stringWithZero_;
-    /**
-     * <pre>
-     * String defaults containing the character '&#92;000'
-     * </pre>
-     *
-     * <code>optional string string_with_zero = 23 [default = "hel&#92;000lo"];</code>
-     * @return Whether the stringWithZero field is set.
-     */
-    @java.lang.Override
-    public boolean hasStringWithZero() {
-      return ((bitField0_ & 0x00400000) != 0);
-    }
-    /**
-     * <pre>
-     * String defaults containing the character '&#92;000'
-     * </pre>
-     *
-     * <code>optional string string_with_zero = 23 [default = "hel&#92;000lo"];</code>
-     * @return The stringWithZero.
-     */
-    @java.lang.Override
-    public java.lang.String getStringWithZero() {
-      return stringWithZero_;
-    }
-    /**
-     * <pre>
-     * String defaults containing the character '&#92;000'
-     * </pre>
-     *
-     * <code>optional string string_with_zero = 23 [default = "hel&#92;000lo"];</code>
-     * @return The bytes for stringWithZero.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getStringWithZeroBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(stringWithZero_);
-    }
-    /**
-     * <pre>
-     * String defaults containing the character '&#92;000'
-     * </pre>
-     *
-     * <code>optional string string_with_zero = 23 [default = "hel&#92;000lo"];</code>
-     * @param value The stringWithZero to set.
-     */
-    private void setStringWithZero(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00400000;
-      stringWithZero_ = value;
-    }
-    /**
-     * <pre>
-     * String defaults containing the character '&#92;000'
-     * </pre>
-     *
-     * <code>optional string string_with_zero = 23 [default = "hel&#92;000lo"];</code>
-     */
-    private void clearStringWithZero() {
-      bitField0_ = (bitField0_ & ~0x00400000);
-      stringWithZero_ = getDefaultInstance().getStringWithZero();
-    }
-    /**
-     * <pre>
-     * String defaults containing the character '&#92;000'
-     * </pre>
-     *
-     * <code>optional string string_with_zero = 23 [default = "hel&#92;000lo"];</code>
-     * @param value The bytes for stringWithZero to set.
-     */
-    private void setStringWithZeroBytes(
-        com.google.protobuf.ByteString value) {
-      stringWithZero_ = value.toStringUtf8();
-      bitField0_ |= 0x00400000;
-    }
-
-    public static final int BYTES_WITH_ZERO_FIELD_NUMBER = 24;
-    private static final com.google.protobuf.ByteString BYTESWITHZERO_DEFAULT_VALUE = com.google.protobuf.Internal.bytesDefaultValue("wor\000ld");
-    private com.google.protobuf.ByteString bytesWithZero_;
-    /**
-     * <code>optional bytes bytes_with_zero = 24 [default = "wor&#92;000ld"];</code>
-     * @return Whether the bytesWithZero field is set.
-     */
-    @java.lang.Override
-    public boolean hasBytesWithZero() {
-      return ((bitField0_ & 0x00800000) != 0);
-    }
-    /**
-     * <code>optional bytes bytes_with_zero = 24 [default = "wor&#92;000ld"];</code>
-     * @return The bytesWithZero.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getBytesWithZero() {
-      return bytesWithZero_;
-    }
-    /**
-     * <code>optional bytes bytes_with_zero = 24 [default = "wor&#92;000ld"];</code>
-     * @param value The bytesWithZero to set.
-     */
-    private void setBytesWithZero(com.google.protobuf.ByteString value) {
-      value.getClass();
-  bitField0_ |= 0x00800000;
-      bytesWithZero_ = value;
-    }
-    /**
-     * <code>optional bytes bytes_with_zero = 24 [default = "wor&#92;000ld"];</code>
-     */
-    private void clearBytesWithZero() {
-      bitField0_ = (bitField0_ & ~0x00800000);
-      bytesWithZero_ = getDefaultInstance().getBytesWithZero();
-    }
-
-    public static final int STRING_PIECE_WITH_ZERO_FIELD_NUMBER = 25;
-    private java.lang.String stringPieceWithZero_;
-    /**
-     * <code>optional string string_piece_with_zero = 25 [default = "ab&#92;000c", ctype = STRING_PIECE];</code>
-     * @return Whether the stringPieceWithZero field is set.
-     */
-    @java.lang.Override
-    public boolean hasStringPieceWithZero() {
-      return ((bitField0_ & 0x01000000) != 0);
-    }
-    /**
-     * <code>optional string string_piece_with_zero = 25 [default = "ab&#92;000c", ctype = STRING_PIECE];</code>
-     * @return The stringPieceWithZero.
-     */
-    @java.lang.Override
-    public java.lang.String getStringPieceWithZero() {
-      return stringPieceWithZero_;
-    }
-    /**
-     * <code>optional string string_piece_with_zero = 25 [default = "ab&#92;000c", ctype = STRING_PIECE];</code>
-     * @return The bytes for stringPieceWithZero.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getStringPieceWithZeroBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(stringPieceWithZero_);
-    }
-    /**
-     * <code>optional string string_piece_with_zero = 25 [default = "ab&#92;000c", ctype = STRING_PIECE];</code>
-     * @param value The stringPieceWithZero to set.
-     */
-    private void setStringPieceWithZero(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x01000000;
-      stringPieceWithZero_ = value;
-    }
-    /**
-     * <code>optional string string_piece_with_zero = 25 [default = "ab&#92;000c", ctype = STRING_PIECE];</code>
-     */
-    private void clearStringPieceWithZero() {
-      bitField0_ = (bitField0_ & ~0x01000000);
-      stringPieceWithZero_ = getDefaultInstance().getStringPieceWithZero();
-    }
-    /**
-     * <code>optional string string_piece_with_zero = 25 [default = "ab&#92;000c", ctype = STRING_PIECE];</code>
-     * @param value The bytes for stringPieceWithZero to set.
-     */
-    private void setStringPieceWithZeroBytes(
-        com.google.protobuf.ByteString value) {
-      stringPieceWithZero_ = value.toStringUtf8();
-      bitField0_ |= 0x01000000;
-    }
-
-    public static final int CORD_WITH_ZERO_FIELD_NUMBER = 26;
-    private java.lang.String cordWithZero_;
-    /**
-     * <code>optional string cord_with_zero = 26 [default = "12&#92;0003", ctype = CORD];</code>
-     * @return Whether the cordWithZero field is set.
-     */
-    @java.lang.Override
-    public boolean hasCordWithZero() {
-      return ((bitField0_ & 0x02000000) != 0);
-    }
-    /**
-     * <code>optional string cord_with_zero = 26 [default = "12&#92;0003", ctype = CORD];</code>
-     * @return The cordWithZero.
-     */
-    @java.lang.Override
-    public java.lang.String getCordWithZero() {
-      return cordWithZero_;
-    }
-    /**
-     * <code>optional string cord_with_zero = 26 [default = "12&#92;0003", ctype = CORD];</code>
-     * @return The bytes for cordWithZero.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getCordWithZeroBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(cordWithZero_);
-    }
-    /**
-     * <code>optional string cord_with_zero = 26 [default = "12&#92;0003", ctype = CORD];</code>
-     * @param value The cordWithZero to set.
-     */
-    private void setCordWithZero(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x02000000;
-      cordWithZero_ = value;
-    }
-    /**
-     * <code>optional string cord_with_zero = 26 [default = "12&#92;0003", ctype = CORD];</code>
-     */
-    private void clearCordWithZero() {
-      bitField0_ = (bitField0_ & ~0x02000000);
-      cordWithZero_ = getDefaultInstance().getCordWithZero();
-    }
-    /**
-     * <code>optional string cord_with_zero = 26 [default = "12&#92;0003", ctype = CORD];</code>
-     * @param value The bytes for cordWithZero to set.
-     */
-    private void setCordWithZeroBytes(
-        com.google.protobuf.ByteString value) {
-      cordWithZero_ = value.toStringUtf8();
-      bitField0_ |= 0x02000000;
-    }
-
-    public static final int REPLACEMENT_STRING_FIELD_NUMBER = 27;
-    private java.lang.String replacementString_;
-    /**
-     * <code>optional string replacement_string = 27 [default = "${unknown}"];</code>
-     * @return Whether the replacementString field is set.
-     */
-    @java.lang.Override
-    public boolean hasReplacementString() {
-      return ((bitField0_ & 0x04000000) != 0);
-    }
-    /**
-     * <code>optional string replacement_string = 27 [default = "${unknown}"];</code>
-     * @return The replacementString.
-     */
-    @java.lang.Override
-    public java.lang.String getReplacementString() {
-      return replacementString_;
-    }
-    /**
-     * <code>optional string replacement_string = 27 [default = "${unknown}"];</code>
-     * @return The bytes for replacementString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getReplacementStringBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(replacementString_);
-    }
-    /**
-     * <code>optional string replacement_string = 27 [default = "${unknown}"];</code>
-     * @param value The replacementString to set.
-     */
-    private void setReplacementString(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x04000000;
-      replacementString_ = value;
-    }
-    /**
-     * <code>optional string replacement_string = 27 [default = "${unknown}"];</code>
-     */
-    private void clearReplacementString() {
-      bitField0_ = (bitField0_ & ~0x04000000);
-      replacementString_ = getDefaultInstance().getReplacementString();
-    }
-    /**
-     * <code>optional string replacement_string = 27 [default = "${unknown}"];</code>
-     * @param value The bytes for replacementString to set.
-     */
-    private void setReplacementStringBytes(
-        com.google.protobuf.ByteString value) {
-      replacementString_ = value.toStringUtf8();
-      bitField0_ |= 0x04000000;
-    }
-
-    public static protobuf_unittest.UnittestProto.TestExtremeDefaultValues parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtremeDefaultValues parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtremeDefaultValues parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtremeDefaultValues parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtremeDefaultValues parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtremeDefaultValues parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtremeDefaultValues parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtremeDefaultValues parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtremeDefaultValues parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtremeDefaultValues parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtremeDefaultValues parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtremeDefaultValues parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestExtremeDefaultValues prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestExtremeDefaultValues}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestExtremeDefaultValues, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestExtremeDefaultValues)
-        protobuf_unittest.UnittestProto.TestExtremeDefaultValuesOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestExtremeDefaultValues.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional bytes escaped_bytes = 1 [default = "&#92;000&#92;001&#92;007&#92;010&#92;014&#92;n&#92;r&#92;t&#92;013&#92;&#92;&#92;'&#92;"&#92;376"];</code>
-       * @return Whether the escapedBytes field is set.
-       */
-      @java.lang.Override
-      public boolean hasEscapedBytes() {
-        return instance.hasEscapedBytes();
-      }
-      /**
-       * <code>optional bytes escaped_bytes = 1 [default = "&#92;000&#92;001&#92;007&#92;010&#92;014&#92;n&#92;r&#92;t&#92;013&#92;&#92;&#92;'&#92;"&#92;376"];</code>
-       * @return The escapedBytes.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getEscapedBytes() {
-        return instance.getEscapedBytes();
-      }
-      /**
-       * <code>optional bytes escaped_bytes = 1 [default = "&#92;000&#92;001&#92;007&#92;010&#92;014&#92;n&#92;r&#92;t&#92;013&#92;&#92;&#92;'&#92;"&#92;376"];</code>
-       * @param value The escapedBytes to set.
-       * @return This builder for chaining.
-       */
-      public Builder setEscapedBytes(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setEscapedBytes(value);
-        return this;
-      }
-      /**
-       * <code>optional bytes escaped_bytes = 1 [default = "&#92;000&#92;001&#92;007&#92;010&#92;014&#92;n&#92;r&#92;t&#92;013&#92;&#92;&#92;'&#92;"&#92;376"];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearEscapedBytes() {
-        copyOnWrite();
-        instance.clearEscapedBytes();
-        return this;
-      }
-
-      /**
-       * <code>optional uint32 large_uint32 = 2 [default = 4294967295];</code>
-       * @return Whether the largeUint32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasLargeUint32() {
-        return instance.hasLargeUint32();
-      }
-      /**
-       * <code>optional uint32 large_uint32 = 2 [default = 4294967295];</code>
-       * @return The largeUint32.
-       */
-      @java.lang.Override
-      public int getLargeUint32() {
-        return instance.getLargeUint32();
-      }
-      /**
-       * <code>optional uint32 large_uint32 = 2 [default = 4294967295];</code>
-       * @param value The largeUint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setLargeUint32(int value) {
-        copyOnWrite();
-        instance.setLargeUint32(value);
-        return this;
-      }
-      /**
-       * <code>optional uint32 large_uint32 = 2 [default = 4294967295];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearLargeUint32() {
-        copyOnWrite();
-        instance.clearLargeUint32();
-        return this;
-      }
-
-      /**
-       * <code>optional uint64 large_uint64 = 3 [default = 18446744073709551615];</code>
-       * @return Whether the largeUint64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasLargeUint64() {
-        return instance.hasLargeUint64();
-      }
-      /**
-       * <code>optional uint64 large_uint64 = 3 [default = 18446744073709551615];</code>
-       * @return The largeUint64.
-       */
-      @java.lang.Override
-      public long getLargeUint64() {
-        return instance.getLargeUint64();
-      }
-      /**
-       * <code>optional uint64 large_uint64 = 3 [default = 18446744073709551615];</code>
-       * @param value The largeUint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setLargeUint64(long value) {
-        copyOnWrite();
-        instance.setLargeUint64(value);
-        return this;
-      }
-      /**
-       * <code>optional uint64 large_uint64 = 3 [default = 18446744073709551615];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearLargeUint64() {
-        copyOnWrite();
-        instance.clearLargeUint64();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 small_int32 = 4 [default = -2147483647];</code>
-       * @return Whether the smallInt32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasSmallInt32() {
-        return instance.hasSmallInt32();
-      }
-      /**
-       * <code>optional int32 small_int32 = 4 [default = -2147483647];</code>
-       * @return The smallInt32.
-       */
-      @java.lang.Override
-      public int getSmallInt32() {
-        return instance.getSmallInt32();
-      }
-      /**
-       * <code>optional int32 small_int32 = 4 [default = -2147483647];</code>
-       * @param value The smallInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setSmallInt32(int value) {
-        copyOnWrite();
-        instance.setSmallInt32(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 small_int32 = 4 [default = -2147483647];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearSmallInt32() {
-        copyOnWrite();
-        instance.clearSmallInt32();
-        return this;
-      }
-
-      /**
-       * <code>optional int64 small_int64 = 5 [default = -9223372036854775807];</code>
-       * @return Whether the smallInt64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasSmallInt64() {
-        return instance.hasSmallInt64();
-      }
-      /**
-       * <code>optional int64 small_int64 = 5 [default = -9223372036854775807];</code>
-       * @return The smallInt64.
-       */
-      @java.lang.Override
-      public long getSmallInt64() {
-        return instance.getSmallInt64();
-      }
-      /**
-       * <code>optional int64 small_int64 = 5 [default = -9223372036854775807];</code>
-       * @param value The smallInt64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setSmallInt64(long value) {
-        copyOnWrite();
-        instance.setSmallInt64(value);
-        return this;
-      }
-      /**
-       * <code>optional int64 small_int64 = 5 [default = -9223372036854775807];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearSmallInt64() {
-        copyOnWrite();
-        instance.clearSmallInt64();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 really_small_int32 = 21 [default = -2147483648];</code>
-       * @return Whether the reallySmallInt32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasReallySmallInt32() {
-        return instance.hasReallySmallInt32();
-      }
-      /**
-       * <code>optional int32 really_small_int32 = 21 [default = -2147483648];</code>
-       * @return The reallySmallInt32.
-       */
-      @java.lang.Override
-      public int getReallySmallInt32() {
-        return instance.getReallySmallInt32();
-      }
-      /**
-       * <code>optional int32 really_small_int32 = 21 [default = -2147483648];</code>
-       * @param value The reallySmallInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setReallySmallInt32(int value) {
-        copyOnWrite();
-        instance.setReallySmallInt32(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 really_small_int32 = 21 [default = -2147483648];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearReallySmallInt32() {
-        copyOnWrite();
-        instance.clearReallySmallInt32();
-        return this;
-      }
-
-      /**
-       * <code>optional int64 really_small_int64 = 22 [default = -9223372036854775808];</code>
-       * @return Whether the reallySmallInt64 field is set.
-       */
-      @java.lang.Override
-      public boolean hasReallySmallInt64() {
-        return instance.hasReallySmallInt64();
-      }
-      /**
-       * <code>optional int64 really_small_int64 = 22 [default = -9223372036854775808];</code>
-       * @return The reallySmallInt64.
-       */
-      @java.lang.Override
-      public long getReallySmallInt64() {
-        return instance.getReallySmallInt64();
-      }
-      /**
-       * <code>optional int64 really_small_int64 = 22 [default = -9223372036854775808];</code>
-       * @param value The reallySmallInt64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setReallySmallInt64(long value) {
-        copyOnWrite();
-        instance.setReallySmallInt64(value);
-        return this;
-      }
-      /**
-       * <code>optional int64 really_small_int64 = 22 [default = -9223372036854775808];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearReallySmallInt64() {
-        copyOnWrite();
-        instance.clearReallySmallInt64();
-        return this;
-      }
-
-      /**
-       * <pre>
-       * The default value here is UTF-8 for "&#92;u1234".  (We could also just type
-       * the UTF-8 text directly into this text file rather than escape it, but
-       * lots of people use editors that would be confused by this.)
-       * </pre>
-       *
-       * <code>optional string utf8_string = 6 [default = "&#92;341&#92;210&#92;264"];</code>
-       * @return Whether the utf8String field is set.
-       */
-      @java.lang.Override
-      public boolean hasUtf8String() {
-        return instance.hasUtf8String();
-      }
-      /**
-       * <pre>
-       * The default value here is UTF-8 for "&#92;u1234".  (We could also just type
-       * the UTF-8 text directly into this text file rather than escape it, but
-       * lots of people use editors that would be confused by this.)
-       * </pre>
-       *
-       * <code>optional string utf8_string = 6 [default = "&#92;341&#92;210&#92;264"];</code>
-       * @return The utf8String.
-       */
-      @java.lang.Override
-      public java.lang.String getUtf8String() {
-        return instance.getUtf8String();
-      }
-      /**
-       * <pre>
-       * The default value here is UTF-8 for "&#92;u1234".  (We could also just type
-       * the UTF-8 text directly into this text file rather than escape it, but
-       * lots of people use editors that would be confused by this.)
-       * </pre>
-       *
-       * <code>optional string utf8_string = 6 [default = "&#92;341&#92;210&#92;264"];</code>
-       * @return The bytes for utf8String.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getUtf8StringBytes() {
-        return instance.getUtf8StringBytes();
-      }
-      /**
-       * <pre>
-       * The default value here is UTF-8 for "&#92;u1234".  (We could also just type
-       * the UTF-8 text directly into this text file rather than escape it, but
-       * lots of people use editors that would be confused by this.)
-       * </pre>
-       *
-       * <code>optional string utf8_string = 6 [default = "&#92;341&#92;210&#92;264"];</code>
-       * @param value The utf8String to set.
-       * @return This builder for chaining.
-       */
-      public Builder setUtf8String(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setUtf8String(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * The default value here is UTF-8 for "&#92;u1234".  (We could also just type
-       * the UTF-8 text directly into this text file rather than escape it, but
-       * lots of people use editors that would be confused by this.)
-       * </pre>
-       *
-       * <code>optional string utf8_string = 6 [default = "&#92;341&#92;210&#92;264"];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearUtf8String() {
-        copyOnWrite();
-        instance.clearUtf8String();
-        return this;
-      }
-      /**
-       * <pre>
-       * The default value here is UTF-8 for "&#92;u1234".  (We could also just type
-       * the UTF-8 text directly into this text file rather than escape it, but
-       * lots of people use editors that would be confused by this.)
-       * </pre>
-       *
-       * <code>optional string utf8_string = 6 [default = "&#92;341&#92;210&#92;264"];</code>
-       * @param value The bytes for utf8String to set.
-       * @return This builder for chaining.
-       */
-      public Builder setUtf8StringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setUtf8StringBytes(value);
-        return this;
-      }
-
-      /**
-       * <pre>
-       * Tests for single-precision floating-point values.
-       * </pre>
-       *
-       * <code>optional float zero_float = 7 [default = 0];</code>
-       * @return Whether the zeroFloat field is set.
-       */
-      @java.lang.Override
-      public boolean hasZeroFloat() {
-        return instance.hasZeroFloat();
-      }
-      /**
-       * <pre>
-       * Tests for single-precision floating-point values.
-       * </pre>
-       *
-       * <code>optional float zero_float = 7 [default = 0];</code>
-       * @return The zeroFloat.
-       */
-      @java.lang.Override
-      public float getZeroFloat() {
-        return instance.getZeroFloat();
-      }
-      /**
-       * <pre>
-       * Tests for single-precision floating-point values.
-       * </pre>
-       *
-       * <code>optional float zero_float = 7 [default = 0];</code>
-       * @param value The zeroFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setZeroFloat(float value) {
-        copyOnWrite();
-        instance.setZeroFloat(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Tests for single-precision floating-point values.
-       * </pre>
-       *
-       * <code>optional float zero_float = 7 [default = 0];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearZeroFloat() {
-        copyOnWrite();
-        instance.clearZeroFloat();
-        return this;
-      }
-
-      /**
-       * <code>optional float one_float = 8 [default = 1];</code>
-       * @return Whether the oneFloat field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneFloat() {
-        return instance.hasOneFloat();
-      }
-      /**
-       * <code>optional float one_float = 8 [default = 1];</code>
-       * @return The oneFloat.
-       */
-      @java.lang.Override
-      public float getOneFloat() {
-        return instance.getOneFloat();
-      }
-      /**
-       * <code>optional float one_float = 8 [default = 1];</code>
-       * @param value The oneFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneFloat(float value) {
-        copyOnWrite();
-        instance.setOneFloat(value);
-        return this;
-      }
-      /**
-       * <code>optional float one_float = 8 [default = 1];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneFloat() {
-        copyOnWrite();
-        instance.clearOneFloat();
-        return this;
-      }
-
-      /**
-       * <code>optional float small_float = 9 [default = 1.5];</code>
-       * @return Whether the smallFloat field is set.
-       */
-      @java.lang.Override
-      public boolean hasSmallFloat() {
-        return instance.hasSmallFloat();
-      }
-      /**
-       * <code>optional float small_float = 9 [default = 1.5];</code>
-       * @return The smallFloat.
-       */
-      @java.lang.Override
-      public float getSmallFloat() {
-        return instance.getSmallFloat();
-      }
-      /**
-       * <code>optional float small_float = 9 [default = 1.5];</code>
-       * @param value The smallFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setSmallFloat(float value) {
-        copyOnWrite();
-        instance.setSmallFloat(value);
-        return this;
-      }
-      /**
-       * <code>optional float small_float = 9 [default = 1.5];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearSmallFloat() {
-        copyOnWrite();
-        instance.clearSmallFloat();
-        return this;
-      }
-
-      /**
-       * <code>optional float negative_one_float = 10 [default = -1];</code>
-       * @return Whether the negativeOneFloat field is set.
-       */
-      @java.lang.Override
-      public boolean hasNegativeOneFloat() {
-        return instance.hasNegativeOneFloat();
-      }
-      /**
-       * <code>optional float negative_one_float = 10 [default = -1];</code>
-       * @return The negativeOneFloat.
-       */
-      @java.lang.Override
-      public float getNegativeOneFloat() {
-        return instance.getNegativeOneFloat();
-      }
-      /**
-       * <code>optional float negative_one_float = 10 [default = -1];</code>
-       * @param value The negativeOneFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setNegativeOneFloat(float value) {
-        copyOnWrite();
-        instance.setNegativeOneFloat(value);
-        return this;
-      }
-      /**
-       * <code>optional float negative_one_float = 10 [default = -1];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearNegativeOneFloat() {
-        copyOnWrite();
-        instance.clearNegativeOneFloat();
-        return this;
-      }
-
-      /**
-       * <code>optional float negative_float = 11 [default = -1.5];</code>
-       * @return Whether the negativeFloat field is set.
-       */
-      @java.lang.Override
-      public boolean hasNegativeFloat() {
-        return instance.hasNegativeFloat();
-      }
-      /**
-       * <code>optional float negative_float = 11 [default = -1.5];</code>
-       * @return The negativeFloat.
-       */
-      @java.lang.Override
-      public float getNegativeFloat() {
-        return instance.getNegativeFloat();
-      }
-      /**
-       * <code>optional float negative_float = 11 [default = -1.5];</code>
-       * @param value The negativeFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setNegativeFloat(float value) {
-        copyOnWrite();
-        instance.setNegativeFloat(value);
-        return this;
-      }
-      /**
-       * <code>optional float negative_float = 11 [default = -1.5];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearNegativeFloat() {
-        copyOnWrite();
-        instance.clearNegativeFloat();
-        return this;
-      }
-
-      /**
-       * <pre>
-       * Using exponents
-       * </pre>
-       *
-       * <code>optional float large_float = 12 [default = 2e+08];</code>
-       * @return Whether the largeFloat field is set.
-       */
-      @java.lang.Override
-      public boolean hasLargeFloat() {
-        return instance.hasLargeFloat();
-      }
-      /**
-       * <pre>
-       * Using exponents
-       * </pre>
-       *
-       * <code>optional float large_float = 12 [default = 2e+08];</code>
-       * @return The largeFloat.
-       */
-      @java.lang.Override
-      public float getLargeFloat() {
-        return instance.getLargeFloat();
-      }
-      /**
-       * <pre>
-       * Using exponents
-       * </pre>
-       *
-       * <code>optional float large_float = 12 [default = 2e+08];</code>
-       * @param value The largeFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setLargeFloat(float value) {
-        copyOnWrite();
-        instance.setLargeFloat(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Using exponents
-       * </pre>
-       *
-       * <code>optional float large_float = 12 [default = 2e+08];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearLargeFloat() {
-        copyOnWrite();
-        instance.clearLargeFloat();
-        return this;
-      }
-
-      /**
-       * <code>optional float small_negative_float = 13 [default = -8e-28];</code>
-       * @return Whether the smallNegativeFloat field is set.
-       */
-      @java.lang.Override
-      public boolean hasSmallNegativeFloat() {
-        return instance.hasSmallNegativeFloat();
-      }
-      /**
-       * <code>optional float small_negative_float = 13 [default = -8e-28];</code>
-       * @return The smallNegativeFloat.
-       */
-      @java.lang.Override
-      public float getSmallNegativeFloat() {
-        return instance.getSmallNegativeFloat();
-      }
-      /**
-       * <code>optional float small_negative_float = 13 [default = -8e-28];</code>
-       * @param value The smallNegativeFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setSmallNegativeFloat(float value) {
-        copyOnWrite();
-        instance.setSmallNegativeFloat(value);
-        return this;
-      }
-      /**
-       * <code>optional float small_negative_float = 13 [default = -8e-28];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearSmallNegativeFloat() {
-        copyOnWrite();
-        instance.clearSmallNegativeFloat();
-        return this;
-      }
-
-      /**
-       * <pre>
-       * Text for nonfinite floating-point values.
-       * </pre>
-       *
-       * <code>optional double inf_double = 14 [default = inf];</code>
-       * @return Whether the infDouble field is set.
-       */
-      @java.lang.Override
-      public boolean hasInfDouble() {
-        return instance.hasInfDouble();
-      }
-      /**
-       * <pre>
-       * Text for nonfinite floating-point values.
-       * </pre>
-       *
-       * <code>optional double inf_double = 14 [default = inf];</code>
-       * @return The infDouble.
-       */
-      @java.lang.Override
-      public double getInfDouble() {
-        return instance.getInfDouble();
-      }
-      /**
-       * <pre>
-       * Text for nonfinite floating-point values.
-       * </pre>
-       *
-       * <code>optional double inf_double = 14 [default = inf];</code>
-       * @param value The infDouble to set.
-       * @return This builder for chaining.
-       */
-      public Builder setInfDouble(double value) {
-        copyOnWrite();
-        instance.setInfDouble(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Text for nonfinite floating-point values.
-       * </pre>
-       *
-       * <code>optional double inf_double = 14 [default = inf];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearInfDouble() {
-        copyOnWrite();
-        instance.clearInfDouble();
-        return this;
-      }
-
-      /**
-       * <code>optional double neg_inf_double = 15 [default = -inf];</code>
-       * @return Whether the negInfDouble field is set.
-       */
-      @java.lang.Override
-      public boolean hasNegInfDouble() {
-        return instance.hasNegInfDouble();
-      }
-      /**
-       * <code>optional double neg_inf_double = 15 [default = -inf];</code>
-       * @return The negInfDouble.
-       */
-      @java.lang.Override
-      public double getNegInfDouble() {
-        return instance.getNegInfDouble();
-      }
-      /**
-       * <code>optional double neg_inf_double = 15 [default = -inf];</code>
-       * @param value The negInfDouble to set.
-       * @return This builder for chaining.
-       */
-      public Builder setNegInfDouble(double value) {
-        copyOnWrite();
-        instance.setNegInfDouble(value);
-        return this;
-      }
-      /**
-       * <code>optional double neg_inf_double = 15 [default = -inf];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearNegInfDouble() {
-        copyOnWrite();
-        instance.clearNegInfDouble();
-        return this;
-      }
-
-      /**
-       * <code>optional double nan_double = 16 [default = nan];</code>
-       * @return Whether the nanDouble field is set.
-       */
-      @java.lang.Override
-      public boolean hasNanDouble() {
-        return instance.hasNanDouble();
-      }
-      /**
-       * <code>optional double nan_double = 16 [default = nan];</code>
-       * @return The nanDouble.
-       */
-      @java.lang.Override
-      public double getNanDouble() {
-        return instance.getNanDouble();
-      }
-      /**
-       * <code>optional double nan_double = 16 [default = nan];</code>
-       * @param value The nanDouble to set.
-       * @return This builder for chaining.
-       */
-      public Builder setNanDouble(double value) {
-        copyOnWrite();
-        instance.setNanDouble(value);
-        return this;
-      }
-      /**
-       * <code>optional double nan_double = 16 [default = nan];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearNanDouble() {
-        copyOnWrite();
-        instance.clearNanDouble();
-        return this;
-      }
-
-      /**
-       * <code>optional float inf_float = 17 [default = inf];</code>
-       * @return Whether the infFloat field is set.
-       */
-      @java.lang.Override
-      public boolean hasInfFloat() {
-        return instance.hasInfFloat();
-      }
-      /**
-       * <code>optional float inf_float = 17 [default = inf];</code>
-       * @return The infFloat.
-       */
-      @java.lang.Override
-      public float getInfFloat() {
-        return instance.getInfFloat();
-      }
-      /**
-       * <code>optional float inf_float = 17 [default = inf];</code>
-       * @param value The infFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setInfFloat(float value) {
-        copyOnWrite();
-        instance.setInfFloat(value);
-        return this;
-      }
-      /**
-       * <code>optional float inf_float = 17 [default = inf];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearInfFloat() {
-        copyOnWrite();
-        instance.clearInfFloat();
-        return this;
-      }
-
-      /**
-       * <code>optional float neg_inf_float = 18 [default = -inf];</code>
-       * @return Whether the negInfFloat field is set.
-       */
-      @java.lang.Override
-      public boolean hasNegInfFloat() {
-        return instance.hasNegInfFloat();
-      }
-      /**
-       * <code>optional float neg_inf_float = 18 [default = -inf];</code>
-       * @return The negInfFloat.
-       */
-      @java.lang.Override
-      public float getNegInfFloat() {
-        return instance.getNegInfFloat();
-      }
-      /**
-       * <code>optional float neg_inf_float = 18 [default = -inf];</code>
-       * @param value The negInfFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setNegInfFloat(float value) {
-        copyOnWrite();
-        instance.setNegInfFloat(value);
-        return this;
-      }
-      /**
-       * <code>optional float neg_inf_float = 18 [default = -inf];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearNegInfFloat() {
-        copyOnWrite();
-        instance.clearNegInfFloat();
-        return this;
-      }
-
-      /**
-       * <code>optional float nan_float = 19 [default = nan];</code>
-       * @return Whether the nanFloat field is set.
-       */
-      @java.lang.Override
-      public boolean hasNanFloat() {
-        return instance.hasNanFloat();
-      }
-      /**
-       * <code>optional float nan_float = 19 [default = nan];</code>
-       * @return The nanFloat.
-       */
-      @java.lang.Override
-      public float getNanFloat() {
-        return instance.getNanFloat();
-      }
-      /**
-       * <code>optional float nan_float = 19 [default = nan];</code>
-       * @param value The nanFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setNanFloat(float value) {
-        copyOnWrite();
-        instance.setNanFloat(value);
-        return this;
-      }
-      /**
-       * <code>optional float nan_float = 19 [default = nan];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearNanFloat() {
-        copyOnWrite();
-        instance.clearNanFloat();
-        return this;
-      }
-
-      /**
-       * <pre>
-       * Tests for C++ trigraphs.
-       * Trigraphs should be escaped in C++ generated files, but they should not be
-       * escaped for other languages.
-       * Note that in .proto file, "&#92;?" is a valid way to escape ? in string
-       * literals.
-       * </pre>
-       *
-       * <code>optional string cpp_trigraph = 20 [default = "? ? ?? ?? ??? ??/ ??-"];</code>
-       * @return Whether the cppTrigraph field is set.
-       */
-      @java.lang.Override
-      public boolean hasCppTrigraph() {
-        return instance.hasCppTrigraph();
-      }
-      /**
-       * <pre>
-       * Tests for C++ trigraphs.
-       * Trigraphs should be escaped in C++ generated files, but they should not be
-       * escaped for other languages.
-       * Note that in .proto file, "&#92;?" is a valid way to escape ? in string
-       * literals.
-       * </pre>
-       *
-       * <code>optional string cpp_trigraph = 20 [default = "? ? ?? ?? ??? ??/ ??-"];</code>
-       * @return The cppTrigraph.
-       */
-      @java.lang.Override
-      public java.lang.String getCppTrigraph() {
-        return instance.getCppTrigraph();
-      }
-      /**
-       * <pre>
-       * Tests for C++ trigraphs.
-       * Trigraphs should be escaped in C++ generated files, but they should not be
-       * escaped for other languages.
-       * Note that in .proto file, "&#92;?" is a valid way to escape ? in string
-       * literals.
-       * </pre>
-       *
-       * <code>optional string cpp_trigraph = 20 [default = "? ? ?? ?? ??? ??/ ??-"];</code>
-       * @return The bytes for cppTrigraph.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getCppTrigraphBytes() {
-        return instance.getCppTrigraphBytes();
-      }
-      /**
-       * <pre>
-       * Tests for C++ trigraphs.
-       * Trigraphs should be escaped in C++ generated files, but they should not be
-       * escaped for other languages.
-       * Note that in .proto file, "&#92;?" is a valid way to escape ? in string
-       * literals.
-       * </pre>
-       *
-       * <code>optional string cpp_trigraph = 20 [default = "? ? ?? ?? ??? ??/ ??-"];</code>
-       * @param value The cppTrigraph to set.
-       * @return This builder for chaining.
-       */
-      public Builder setCppTrigraph(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setCppTrigraph(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Tests for C++ trigraphs.
-       * Trigraphs should be escaped in C++ generated files, but they should not be
-       * escaped for other languages.
-       * Note that in .proto file, "&#92;?" is a valid way to escape ? in string
-       * literals.
-       * </pre>
-       *
-       * <code>optional string cpp_trigraph = 20 [default = "? ? ?? ?? ??? ??/ ??-"];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearCppTrigraph() {
-        copyOnWrite();
-        instance.clearCppTrigraph();
-        return this;
-      }
-      /**
-       * <pre>
-       * Tests for C++ trigraphs.
-       * Trigraphs should be escaped in C++ generated files, but they should not be
-       * escaped for other languages.
-       * Note that in .proto file, "&#92;?" is a valid way to escape ? in string
-       * literals.
-       * </pre>
-       *
-       * <code>optional string cpp_trigraph = 20 [default = "? ? ?? ?? ??? ??/ ??-"];</code>
-       * @param value The bytes for cppTrigraph to set.
-       * @return This builder for chaining.
-       */
-      public Builder setCppTrigraphBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setCppTrigraphBytes(value);
-        return this;
-      }
-
-      /**
-       * <pre>
-       * String defaults containing the character '&#92;000'
-       * </pre>
-       *
-       * <code>optional string string_with_zero = 23 [default = "hel&#92;000lo"];</code>
-       * @return Whether the stringWithZero field is set.
-       */
-      @java.lang.Override
-      public boolean hasStringWithZero() {
-        return instance.hasStringWithZero();
-      }
-      /**
-       * <pre>
-       * String defaults containing the character '&#92;000'
-       * </pre>
-       *
-       * <code>optional string string_with_zero = 23 [default = "hel&#92;000lo"];</code>
-       * @return The stringWithZero.
-       */
-      @java.lang.Override
-      public java.lang.String getStringWithZero() {
-        return instance.getStringWithZero();
-      }
-      /**
-       * <pre>
-       * String defaults containing the character '&#92;000'
-       * </pre>
-       *
-       * <code>optional string string_with_zero = 23 [default = "hel&#92;000lo"];</code>
-       * @return The bytes for stringWithZero.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getStringWithZeroBytes() {
-        return instance.getStringWithZeroBytes();
-      }
-      /**
-       * <pre>
-       * String defaults containing the character '&#92;000'
-       * </pre>
-       *
-       * <code>optional string string_with_zero = 23 [default = "hel&#92;000lo"];</code>
-       * @param value The stringWithZero to set.
-       * @return This builder for chaining.
-       */
-      public Builder setStringWithZero(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setStringWithZero(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * String defaults containing the character '&#92;000'
-       * </pre>
-       *
-       * <code>optional string string_with_zero = 23 [default = "hel&#92;000lo"];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearStringWithZero() {
-        copyOnWrite();
-        instance.clearStringWithZero();
-        return this;
-      }
-      /**
-       * <pre>
-       * String defaults containing the character '&#92;000'
-       * </pre>
-       *
-       * <code>optional string string_with_zero = 23 [default = "hel&#92;000lo"];</code>
-       * @param value The bytes for stringWithZero to set.
-       * @return This builder for chaining.
-       */
-      public Builder setStringWithZeroBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setStringWithZeroBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional bytes bytes_with_zero = 24 [default = "wor&#92;000ld"];</code>
-       * @return Whether the bytesWithZero field is set.
-       */
-      @java.lang.Override
-      public boolean hasBytesWithZero() {
-        return instance.hasBytesWithZero();
-      }
-      /**
-       * <code>optional bytes bytes_with_zero = 24 [default = "wor&#92;000ld"];</code>
-       * @return The bytesWithZero.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getBytesWithZero() {
-        return instance.getBytesWithZero();
-      }
-      /**
-       * <code>optional bytes bytes_with_zero = 24 [default = "wor&#92;000ld"];</code>
-       * @param value The bytesWithZero to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBytesWithZero(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setBytesWithZero(value);
-        return this;
-      }
-      /**
-       * <code>optional bytes bytes_with_zero = 24 [default = "wor&#92;000ld"];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearBytesWithZero() {
-        copyOnWrite();
-        instance.clearBytesWithZero();
-        return this;
-      }
-
-      /**
-       * <code>optional string string_piece_with_zero = 25 [default = "ab&#92;000c", ctype = STRING_PIECE];</code>
-       * @return Whether the stringPieceWithZero field is set.
-       */
-      @java.lang.Override
-      public boolean hasStringPieceWithZero() {
-        return instance.hasStringPieceWithZero();
-      }
-      /**
-       * <code>optional string string_piece_with_zero = 25 [default = "ab&#92;000c", ctype = STRING_PIECE];</code>
-       * @return The stringPieceWithZero.
-       */
-      @java.lang.Override
-      public java.lang.String getStringPieceWithZero() {
-        return instance.getStringPieceWithZero();
-      }
-      /**
-       * <code>optional string string_piece_with_zero = 25 [default = "ab&#92;000c", ctype = STRING_PIECE];</code>
-       * @return The bytes for stringPieceWithZero.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getStringPieceWithZeroBytes() {
-        return instance.getStringPieceWithZeroBytes();
-      }
-      /**
-       * <code>optional string string_piece_with_zero = 25 [default = "ab&#92;000c", ctype = STRING_PIECE];</code>
-       * @param value The stringPieceWithZero to set.
-       * @return This builder for chaining.
-       */
-      public Builder setStringPieceWithZero(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setStringPieceWithZero(value);
-        return this;
-      }
-      /**
-       * <code>optional string string_piece_with_zero = 25 [default = "ab&#92;000c", ctype = STRING_PIECE];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearStringPieceWithZero() {
-        copyOnWrite();
-        instance.clearStringPieceWithZero();
-        return this;
-      }
-      /**
-       * <code>optional string string_piece_with_zero = 25 [default = "ab&#92;000c", ctype = STRING_PIECE];</code>
-       * @param value The bytes for stringPieceWithZero to set.
-       * @return This builder for chaining.
-       */
-      public Builder setStringPieceWithZeroBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setStringPieceWithZeroBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional string cord_with_zero = 26 [default = "12&#92;0003", ctype = CORD];</code>
-       * @return Whether the cordWithZero field is set.
-       */
-      @java.lang.Override
-      public boolean hasCordWithZero() {
-        return instance.hasCordWithZero();
-      }
-      /**
-       * <code>optional string cord_with_zero = 26 [default = "12&#92;0003", ctype = CORD];</code>
-       * @return The cordWithZero.
-       */
-      @java.lang.Override
-      public java.lang.String getCordWithZero() {
-        return instance.getCordWithZero();
-      }
-      /**
-       * <code>optional string cord_with_zero = 26 [default = "12&#92;0003", ctype = CORD];</code>
-       * @return The bytes for cordWithZero.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getCordWithZeroBytes() {
-        return instance.getCordWithZeroBytes();
-      }
-      /**
-       * <code>optional string cord_with_zero = 26 [default = "12&#92;0003", ctype = CORD];</code>
-       * @param value The cordWithZero to set.
-       * @return This builder for chaining.
-       */
-      public Builder setCordWithZero(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setCordWithZero(value);
-        return this;
-      }
-      /**
-       * <code>optional string cord_with_zero = 26 [default = "12&#92;0003", ctype = CORD];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearCordWithZero() {
-        copyOnWrite();
-        instance.clearCordWithZero();
-        return this;
-      }
-      /**
-       * <code>optional string cord_with_zero = 26 [default = "12&#92;0003", ctype = CORD];</code>
-       * @param value The bytes for cordWithZero to set.
-       * @return This builder for chaining.
-       */
-      public Builder setCordWithZeroBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setCordWithZeroBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional string replacement_string = 27 [default = "${unknown}"];</code>
-       * @return Whether the replacementString field is set.
-       */
-      @java.lang.Override
-      public boolean hasReplacementString() {
-        return instance.hasReplacementString();
-      }
-      /**
-       * <code>optional string replacement_string = 27 [default = "${unknown}"];</code>
-       * @return The replacementString.
-       */
-      @java.lang.Override
-      public java.lang.String getReplacementString() {
-        return instance.getReplacementString();
-      }
-      /**
-       * <code>optional string replacement_string = 27 [default = "${unknown}"];</code>
-       * @return The bytes for replacementString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getReplacementStringBytes() {
-        return instance.getReplacementStringBytes();
-      }
-      /**
-       * <code>optional string replacement_string = 27 [default = "${unknown}"];</code>
-       * @param value The replacementString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setReplacementString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setReplacementString(value);
-        return this;
-      }
-      /**
-       * <code>optional string replacement_string = 27 [default = "${unknown}"];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearReplacementString() {
-        copyOnWrite();
-        instance.clearReplacementString();
-        return this;
-      }
-      /**
-       * <code>optional string replacement_string = 27 [default = "${unknown}"];</code>
-       * @param value The bytes for replacementString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setReplacementStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setReplacementStringBytes(value);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestExtremeDefaultValues)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestExtremeDefaultValues();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "escapedBytes_",
-              "largeUint32_",
-              "largeUint64_",
-              "smallInt32_",
-              "smallInt64_",
-              "utf8String_",
-              "zeroFloat_",
-              "oneFloat_",
-              "smallFloat_",
-              "negativeOneFloat_",
-              "negativeFloat_",
-              "largeFloat_",
-              "smallNegativeFloat_",
-              "infDouble_",
-              "negInfDouble_",
-              "nanDouble_",
-              "infFloat_",
-              "negInfFloat_",
-              "nanFloat_",
-              "cppTrigraph_",
-              "reallySmallInt32_",
-              "reallySmallInt64_",
-              "stringWithZero_",
-              "bytesWithZero_",
-              "stringPieceWithZero_",
-              "cordWithZero_",
-              "replacementString_",
-            };
-            java.lang.String info =
-                "\u0001\u001b\u0000\u0001\u0001\u001b\u001b\u0000\u0000\u0000\u0001\u100a\u0000\u0002" +
-                "\u100b\u0001\u0003\u1003\u0002\u0004\u1004\u0003\u0005\u1002\u0004\u0006\u1008\u0007" +
-                "\u0007\u1001\b\b\u1001\t\t\u1001\n\n\u1001\u000b\u000b\u1001\f\f\u1001\r\r\u1001" +
-                "\u000e\u000e\u1000\u000f\u000f\u1000\u0010\u0010\u1000\u0011\u0011\u1001\u0012\u0012" +
-                "\u1001\u0013\u0013\u1001\u0014\u0014\u1008\u0015\u0015\u1004\u0005\u0016\u1002\u0006" +
-                "\u0017\u1008\u0016\u0018\u100a\u0017\u0019\u1008\u0018\u001a\u1008\u0019\u001b\u1008" +
-                "\u001a";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestExtremeDefaultValues> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestExtremeDefaultValues.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestExtremeDefaultValues>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestExtremeDefaultValues)
-    private static final protobuf_unittest.UnittestProto.TestExtremeDefaultValues DEFAULT_INSTANCE;
-    static {
-      TestExtremeDefaultValues defaultInstance = new TestExtremeDefaultValues();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestExtremeDefaultValues.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestExtremeDefaultValues getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestExtremeDefaultValues> PARSER;
-
-    public static com.google.protobuf.Parser<TestExtremeDefaultValues> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface SparseEnumMessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.SparseEnumMessage)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional .protobuf_unittest.TestSparseEnum sparse_enum = 1;</code>
-     * @return Whether the sparseEnum field is set.
-     */
-    boolean hasSparseEnum();
-    /**
-     * <code>optional .protobuf_unittest.TestSparseEnum sparse_enum = 1;</code>
-     * @return The sparseEnum.
-     */
-    protobuf_unittest.UnittestProto.TestSparseEnum getSparseEnum();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.SparseEnumMessage}
-   */
-  public  static final class SparseEnumMessage extends
-      com.google.protobuf.GeneratedMessageLite<
-          SparseEnumMessage, SparseEnumMessage.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.SparseEnumMessage)
-      SparseEnumMessageOrBuilder {
-    private SparseEnumMessage() {
-      sparseEnum_ = 123;
-    }
-    private int bitField0_;
-    public static final int SPARSE_ENUM_FIELD_NUMBER = 1;
-    private int sparseEnum_;
-    /**
-     * <code>optional .protobuf_unittest.TestSparseEnum sparse_enum = 1;</code>
-     * @return Whether the sparseEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasSparseEnum() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestSparseEnum sparse_enum = 1;</code>
-     * @return The sparseEnum.
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestSparseEnum getSparseEnum() {
-      protobuf_unittest.UnittestProto.TestSparseEnum result = protobuf_unittest.UnittestProto.TestSparseEnum.forNumber(sparseEnum_);
-      return result == null ? protobuf_unittest.UnittestProto.TestSparseEnum.SPARSE_A : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestSparseEnum sparse_enum = 1;</code>
-     * @param value The sparseEnum to set.
-     */
-    private void setSparseEnum(protobuf_unittest.UnittestProto.TestSparseEnum value) {
-      sparseEnum_ = value.getNumber();
-      bitField0_ |= 0x00000001;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestSparseEnum sparse_enum = 1;</code>
-     */
-    private void clearSparseEnum() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      sparseEnum_ = 123;
-    }
-
-    public static protobuf_unittest.UnittestProto.SparseEnumMessage parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.SparseEnumMessage parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.SparseEnumMessage parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.SparseEnumMessage parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.SparseEnumMessage parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.SparseEnumMessage parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.SparseEnumMessage parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.SparseEnumMessage parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.SparseEnumMessage parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.SparseEnumMessage parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.SparseEnumMessage parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.SparseEnumMessage parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.SparseEnumMessage prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.SparseEnumMessage}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.SparseEnumMessage, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.SparseEnumMessage)
-        protobuf_unittest.UnittestProto.SparseEnumMessageOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.SparseEnumMessage.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional .protobuf_unittest.TestSparseEnum sparse_enum = 1;</code>
-       * @return Whether the sparseEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasSparseEnum() {
-        return instance.hasSparseEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestSparseEnum sparse_enum = 1;</code>
-       * @return The sparseEnum.
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestSparseEnum getSparseEnum() {
-        return instance.getSparseEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestSparseEnum sparse_enum = 1;</code>
-       * @param value The enum numeric value on the wire for sparseEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setSparseEnum(protobuf_unittest.UnittestProto.TestSparseEnum value) {
-        copyOnWrite();
-        instance.setSparseEnum(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestSparseEnum sparse_enum = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearSparseEnum() {
-        copyOnWrite();
-        instance.clearSparseEnum();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.SparseEnumMessage)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.SparseEnumMessage();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "sparseEnum_",
-              protobuf_unittest.UnittestProto.TestSparseEnum.internalGetVerifier(),
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u100c\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.SparseEnumMessage> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.SparseEnumMessage.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.SparseEnumMessage>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.SparseEnumMessage)
-    private static final protobuf_unittest.UnittestProto.SparseEnumMessage DEFAULT_INSTANCE;
-    static {
-      SparseEnumMessage defaultInstance = new SparseEnumMessage();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        SparseEnumMessage.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.SparseEnumMessage getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<SparseEnumMessage> PARSER;
-
-    public static com.google.protobuf.Parser<SparseEnumMessage> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface OneStringOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.OneString)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional string data = 1;</code>
-     * @return Whether the data field is set.
-     */
-    boolean hasData();
-    /**
-     * <code>optional string data = 1;</code>
-     * @return The data.
-     */
-    java.lang.String getData();
-    /**
-     * <code>optional string data = 1;</code>
-     * @return The bytes for data.
-     */
-    com.google.protobuf.ByteString
-        getDataBytes();
-  }
-  /**
-   * <pre>
-   * Test String and Bytes: string is for valid UTF-8 strings
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.OneString}
-   */
-  public  static final class OneString extends
-      com.google.protobuf.GeneratedMessageLite<
-          OneString, OneString.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.OneString)
-      OneStringOrBuilder {
-    private OneString() {
-      data_ = "";
-    }
-    private int bitField0_;
-    public static final int DATA_FIELD_NUMBER = 1;
-    private java.lang.String data_;
-    /**
-     * <code>optional string data = 1;</code>
-     * @return Whether the data field is set.
-     */
-    @java.lang.Override
-    public boolean hasData() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional string data = 1;</code>
-     * @return The data.
-     */
-    @java.lang.Override
-    public java.lang.String getData() {
-      return data_;
-    }
-    /**
-     * <code>optional string data = 1;</code>
-     * @return The bytes for data.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getDataBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(data_);
-    }
-    /**
-     * <code>optional string data = 1;</code>
-     * @param value The data to set.
-     */
-    private void setData(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00000001;
-      data_ = value;
-    }
-    /**
-     * <code>optional string data = 1;</code>
-     */
-    private void clearData() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      data_ = getDefaultInstance().getData();
-    }
-    /**
-     * <code>optional string data = 1;</code>
-     * @param value The bytes for data to set.
-     */
-    private void setDataBytes(
-        com.google.protobuf.ByteString value) {
-      data_ = value.toStringUtf8();
-      bitField0_ |= 0x00000001;
-    }
-
-    public static protobuf_unittest.UnittestProto.OneString parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.OneString parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.OneString parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.OneString parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.OneString parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.OneString parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.OneString parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.OneString parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.OneString parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.OneString parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.OneString parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.OneString parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.OneString prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Test String and Bytes: string is for valid UTF-8 strings
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.OneString}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.OneString, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.OneString)
-        protobuf_unittest.UnittestProto.OneStringOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.OneString.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional string data = 1;</code>
-       * @return Whether the data field is set.
-       */
-      @java.lang.Override
-      public boolean hasData() {
-        return instance.hasData();
-      }
-      /**
-       * <code>optional string data = 1;</code>
-       * @return The data.
-       */
-      @java.lang.Override
-      public java.lang.String getData() {
-        return instance.getData();
-      }
-      /**
-       * <code>optional string data = 1;</code>
-       * @return The bytes for data.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getDataBytes() {
-        return instance.getDataBytes();
-      }
-      /**
-       * <code>optional string data = 1;</code>
-       * @param value The data to set.
-       * @return This builder for chaining.
-       */
-      public Builder setData(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setData(value);
-        return this;
-      }
-      /**
-       * <code>optional string data = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearData() {
-        copyOnWrite();
-        instance.clearData();
-        return this;
-      }
-      /**
-       * <code>optional string data = 1;</code>
-       * @param value The bytes for data to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDataBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setDataBytes(value);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.OneString)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.OneString();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "data_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1008\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.OneString> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.OneString.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.OneString>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.OneString)
-    private static final protobuf_unittest.UnittestProto.OneString DEFAULT_INSTANCE;
-    static {
-      OneString defaultInstance = new OneString();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        OneString.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.OneString getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<OneString> PARSER;
-
-    public static com.google.protobuf.Parser<OneString> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface MoreStringOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.MoreString)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>repeated string data = 1;</code>
-     * @return A list containing the data.
-     */
-    java.util.List<java.lang.String>
-        getDataList();
-    /**
-     * <code>repeated string data = 1;</code>
-     * @return The count of data.
-     */
-    int getDataCount();
-    /**
-     * <code>repeated string data = 1;</code>
-     * @param index The index of the element to return.
-     * @return The data at the given index.
-     */
-    java.lang.String getData(int index);
-    /**
-     * <code>repeated string data = 1;</code>
-     * @param index The index of the element to return.
-     * @return The data at the given index.
-     */
-    com.google.protobuf.ByteString
-        getDataBytes(int index);
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.MoreString}
-   */
-  public  static final class MoreString extends
-      com.google.protobuf.GeneratedMessageLite<
-          MoreString, MoreString.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.MoreString)
-      MoreStringOrBuilder {
-    private MoreString() {
-      data_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    public static final int DATA_FIELD_NUMBER = 1;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> data_;
-    /**
-     * <code>repeated string data = 1;</code>
-     * @return A list containing the data.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getDataList() {
-      return data_;
-    }
-    /**
-     * <code>repeated string data = 1;</code>
-     * @return The count of data.
-     */
-    @java.lang.Override
-    public int getDataCount() {
-      return data_.size();
-    }
-    /**
-     * <code>repeated string data = 1;</code>
-     * @param index The index of the element to return.
-     * @return The data at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getData(int index) {
-      return data_.get(index);
-    }
-    /**
-     * <code>repeated string data = 1;</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the data at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getDataBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          data_.get(index));
-    }
-    private void ensureDataIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          data_;  if (!tmp.isModifiable()) {
-        data_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string data = 1;</code>
-     * @param index The index to set the value at.
-     * @param value The data to set.
-     */
-    private void setData(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureDataIsMutable();
-      data_.set(index, value);
-    }
-    /**
-     * <code>repeated string data = 1;</code>
-     * @param value The data to add.
-     */
-    private void addData(
-        java.lang.String value) {
-      value.getClass();
-  ensureDataIsMutable();
-      data_.add(value);
-    }
-    /**
-     * <code>repeated string data = 1;</code>
-     * @param values The data to add.
-     */
-    private void addAllData(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureDataIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, data_);
-    }
-    /**
-     * <code>repeated string data = 1;</code>
-     */
-    private void clearData() {
-      data_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string data = 1;</code>
-     * @param value The bytes of the data to add.
-     */
-    private void addDataBytes(
-        com.google.protobuf.ByteString value) {
-      ensureDataIsMutable();
-      data_.add(value.toStringUtf8());
-    }
-
-    public static protobuf_unittest.UnittestProto.MoreString parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.MoreString parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.MoreString parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.MoreString parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.MoreString parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.MoreString parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.MoreString parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.MoreString parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.MoreString parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.MoreString parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.MoreString parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.MoreString parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.MoreString prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.MoreString}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.MoreString, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.MoreString)
-        protobuf_unittest.UnittestProto.MoreStringOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.MoreString.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>repeated string data = 1;</code>
-       * @return A list containing the data.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getDataList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getDataList());
-      }
-      /**
-       * <code>repeated string data = 1;</code>
-       * @return The count of data.
-       */
-      @java.lang.Override
-      public int getDataCount() {
-        return instance.getDataCount();
-      }
-      /**
-       * <code>repeated string data = 1;</code>
-       * @param index The index of the element to return.
-       * @return The data at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getData(int index) {
-        return instance.getData(index);
-      }
-      /**
-       * <code>repeated string data = 1;</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the data at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getDataBytes(int index) {
-        return instance.getDataBytes(index);
-      }
-      /**
-       * <code>repeated string data = 1;</code>
-       * @param index The index to set the value at.
-       * @param value The data to set.
-       * @return This builder for chaining.
-       */
-      public Builder setData(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setData(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string data = 1;</code>
-       * @param value The data to add.
-       * @return This builder for chaining.
-       */
-      public Builder addData(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addData(value);
-        return this;
-      }
-      /**
-       * <code>repeated string data = 1;</code>
-       * @param values The data to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllData(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllData(values);
-        return this;
-      }
-      /**
-       * <code>repeated string data = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearData() {
-        copyOnWrite();
-        instance.clearData();
-        return this;
-      }
-      /**
-       * <code>repeated string data = 1;</code>
-       * @param value The bytes of the data to add.
-       * @return This builder for chaining.
-       */
-      public Builder addDataBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addDataBytes(value);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.MoreString)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.MoreString();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "data_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0000\u0001\u0001\u0001\u0000\u0001\u0000\u0001\u001a";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.MoreString> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.MoreString.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.MoreString>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.MoreString)
-    private static final protobuf_unittest.UnittestProto.MoreString DEFAULT_INSTANCE;
-    static {
-      MoreString defaultInstance = new MoreString();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        MoreString.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.MoreString getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<MoreString> PARSER;
-
-    public static com.google.protobuf.Parser<MoreString> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface OneBytesOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.OneBytes)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional bytes data = 1;</code>
-     * @return Whether the data field is set.
-     */
-    boolean hasData();
-    /**
-     * <code>optional bytes data = 1;</code>
-     * @return The data.
-     */
-    com.google.protobuf.ByteString getData();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.OneBytes}
-   */
-  public  static final class OneBytes extends
-      com.google.protobuf.GeneratedMessageLite<
-          OneBytes, OneBytes.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.OneBytes)
-      OneBytesOrBuilder {
-    private OneBytes() {
-      data_ = com.google.protobuf.ByteString.EMPTY;
-    }
-    private int bitField0_;
-    public static final int DATA_FIELD_NUMBER = 1;
-    private com.google.protobuf.ByteString data_;
-    /**
-     * <code>optional bytes data = 1;</code>
-     * @return Whether the data field is set.
-     */
-    @java.lang.Override
-    public boolean hasData() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional bytes data = 1;</code>
-     * @return The data.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getData() {
-      return data_;
-    }
-    /**
-     * <code>optional bytes data = 1;</code>
-     * @param value The data to set.
-     */
-    private void setData(com.google.protobuf.ByteString value) {
-      value.getClass();
-  bitField0_ |= 0x00000001;
-      data_ = value;
-    }
-    /**
-     * <code>optional bytes data = 1;</code>
-     */
-    private void clearData() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      data_ = getDefaultInstance().getData();
-    }
-
-    public static protobuf_unittest.UnittestProto.OneBytes parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.OneBytes parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.OneBytes parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.OneBytes parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.OneBytes parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.OneBytes parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.OneBytes parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.OneBytes parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.OneBytes parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.OneBytes parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.OneBytes parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.OneBytes parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.OneBytes prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.OneBytes}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.OneBytes, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.OneBytes)
-        protobuf_unittest.UnittestProto.OneBytesOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.OneBytes.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional bytes data = 1;</code>
-       * @return Whether the data field is set.
-       */
-      @java.lang.Override
-      public boolean hasData() {
-        return instance.hasData();
-      }
-      /**
-       * <code>optional bytes data = 1;</code>
-       * @return The data.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getData() {
-        return instance.getData();
-      }
-      /**
-       * <code>optional bytes data = 1;</code>
-       * @param value The data to set.
-       * @return This builder for chaining.
-       */
-      public Builder setData(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setData(value);
-        return this;
-      }
-      /**
-       * <code>optional bytes data = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearData() {
-        copyOnWrite();
-        instance.clearData();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.OneBytes)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.OneBytes();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "data_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u100a\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.OneBytes> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.OneBytes.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.OneBytes>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.OneBytes)
-    private static final protobuf_unittest.UnittestProto.OneBytes DEFAULT_INSTANCE;
-    static {
-      OneBytes defaultInstance = new OneBytes();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        OneBytes.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.OneBytes getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<OneBytes> PARSER;
-
-    public static com.google.protobuf.Parser<OneBytes> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface MoreBytesOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.MoreBytes)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>repeated bytes data = 1;</code>
-     * @return A list containing the data.
-     */
-    java.util.List<com.google.protobuf.ByteString> getDataList();
-    /**
-     * <code>repeated bytes data = 1;</code>
-     * @return The count of data.
-     */
-    int getDataCount();
-    /**
-     * <code>repeated bytes data = 1;</code>
-     * @param index The index of the element to return.
-     * @return The data at the given index.
-     */
-    com.google.protobuf.ByteString getData(int index);
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.MoreBytes}
-   */
-  public  static final class MoreBytes extends
-      com.google.protobuf.GeneratedMessageLite<
-          MoreBytes, MoreBytes.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.MoreBytes)
-      MoreBytesOrBuilder {
-    private MoreBytes() {
-      data_ = emptyProtobufList();
-    }
-    public static final int DATA_FIELD_NUMBER = 1;
-    private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.ByteString> data_;
-    /**
-     * <code>repeated bytes data = 1;</code>
-     * @return A list containing the data.
-     */
-    @java.lang.Override
-    public java.util.List<com.google.protobuf.ByteString>
-        getDataList() {
-      return data_;
-    }
-    /**
-     * <code>repeated bytes data = 1;</code>
-     * @return The count of data.
-     */
-    @java.lang.Override
-    public int getDataCount() {
-      return data_.size();
-    }
-    /**
-     * <code>repeated bytes data = 1;</code>
-     * @param index The index of the element to return.
-     * @return The data at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getData(int index) {
-      return data_.get(index);
-    }
-    private void ensureDataIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<com.google.protobuf.ByteString> tmp = data_;
-      if (!tmp.isModifiable()) {
-        data_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated bytes data = 1;</code>
-     * @param index The index to set the value at.
-     * @param value The data to set.
-     */
-    private void setData(
-        int index, com.google.protobuf.ByteString value) {
-      value.getClass();
-  ensureDataIsMutable();
-      data_.set(index, value);
-    }
-    /**
-     * <code>repeated bytes data = 1;</code>
-     * @param value The data to add.
-     */
-    private void addData(com.google.protobuf.ByteString value) {
-      value.getClass();
-  ensureDataIsMutable();
-      data_.add(value);
-    }
-    /**
-     * <code>repeated bytes data = 1;</code>
-     * @param values The data to add.
-     */
-    private void addAllData(
-        java.lang.Iterable<? extends com.google.protobuf.ByteString> values) {
-      ensureDataIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, data_);
-    }
-    /**
-     * <code>repeated bytes data = 1;</code>
-     */
-    private void clearData() {
-      data_ = emptyProtobufList();
-    }
-
-    public static protobuf_unittest.UnittestProto.MoreBytes parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.MoreBytes parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.MoreBytes parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.MoreBytes parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.MoreBytes parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.MoreBytes parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.MoreBytes parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.MoreBytes parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.MoreBytes parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.MoreBytes parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.MoreBytes parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.MoreBytes parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.MoreBytes prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.MoreBytes}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.MoreBytes, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.MoreBytes)
-        protobuf_unittest.UnittestProto.MoreBytesOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.MoreBytes.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>repeated bytes data = 1;</code>
-       * @return A list containing the data.
-       */
-      @java.lang.Override
-      public java.util.List<com.google.protobuf.ByteString>
-          getDataList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getDataList());
-      }
-      /**
-       * <code>repeated bytes data = 1;</code>
-       * @return The count of data.
-       */
-      @java.lang.Override
-      public int getDataCount() {
-        return instance.getDataCount();
-      }
-      /**
-       * <code>repeated bytes data = 1;</code>
-       * @param index The index of the element to return.
-       * @return The data at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getData(int index) {
-        return instance.getData(index);
-      }
-      /**
-       * <code>repeated bytes data = 1;</code>
-       * @param value The data to set.
-       * @return This builder for chaining.
-       */
-      public Builder setData(
-          int index, com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setData(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated bytes data = 1;</code>
-       * @param value The data to add.
-       * @return This builder for chaining.
-       */
-      public Builder addData(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addData(value);
-        return this;
-      }
-      /**
-       * <code>repeated bytes data = 1;</code>
-       * @param values The data to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllData(
-          java.lang.Iterable<? extends com.google.protobuf.ByteString> values) {
-        copyOnWrite();
-        instance.addAllData(values);
-        return this;
-      }
-      /**
-       * <code>repeated bytes data = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearData() {
-        copyOnWrite();
-        instance.clearData();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.MoreBytes)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.MoreBytes();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "data_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0000\u0001\u0001\u0001\u0000\u0001\u0000\u0001\u001c";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.MoreBytes> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.MoreBytes.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.MoreBytes>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.MoreBytes)
-    private static final protobuf_unittest.UnittestProto.MoreBytes DEFAULT_INSTANCE;
-    static {
-      MoreBytes defaultInstance = new MoreBytes();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        MoreBytes.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.MoreBytes getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<MoreBytes> PARSER;
-
-    public static com.google.protobuf.Parser<MoreBytes> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface Int32MessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.Int32Message)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional int32 data = 1;</code>
-     * @return Whether the data field is set.
-     */
-    boolean hasData();
-    /**
-     * <code>optional int32 data = 1;</code>
-     * @return The data.
-     */
-    int getData();
-  }
-  /**
-   * <pre>
-   * Test int32, uint32, int64, uint64, and bool are all compatible
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.Int32Message}
-   */
-  public  static final class Int32Message extends
-      com.google.protobuf.GeneratedMessageLite<
-          Int32Message, Int32Message.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.Int32Message)
-      Int32MessageOrBuilder {
-    private Int32Message() {
-    }
-    private int bitField0_;
-    public static final int DATA_FIELD_NUMBER = 1;
-    private int data_;
-    /**
-     * <code>optional int32 data = 1;</code>
-     * @return Whether the data field is set.
-     */
-    @java.lang.Override
-    public boolean hasData() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 data = 1;</code>
-     * @return The data.
-     */
-    @java.lang.Override
-    public int getData() {
-      return data_;
-    }
-    /**
-     * <code>optional int32 data = 1;</code>
-     * @param value The data to set.
-     */
-    private void setData(int value) {
-      bitField0_ |= 0x00000001;
-      data_ = value;
-    }
-    /**
-     * <code>optional int32 data = 1;</code>
-     */
-    private void clearData() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      data_ = 0;
-    }
-
-    public static protobuf_unittest.UnittestProto.Int32Message parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.Int32Message parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Int32Message parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.Int32Message parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Int32Message parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.Int32Message parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Int32Message parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.Int32Message parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Int32Message parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.Int32Message parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Int32Message parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.Int32Message parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.Int32Message prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Test int32, uint32, int64, uint64, and bool are all compatible
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.Int32Message}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.Int32Message, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.Int32Message)
-        protobuf_unittest.UnittestProto.Int32MessageOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.Int32Message.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int32 data = 1;</code>
-       * @return Whether the data field is set.
-       */
-      @java.lang.Override
-      public boolean hasData() {
-        return instance.hasData();
-      }
-      /**
-       * <code>optional int32 data = 1;</code>
-       * @return The data.
-       */
-      @java.lang.Override
-      public int getData() {
-        return instance.getData();
-      }
-      /**
-       * <code>optional int32 data = 1;</code>
-       * @param value The data to set.
-       * @return This builder for chaining.
-       */
-      public Builder setData(int value) {
-        copyOnWrite();
-        instance.setData(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 data = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearData() {
-        copyOnWrite();
-        instance.clearData();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.Int32Message)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.Int32Message();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "data_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1004\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.Int32Message> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.Int32Message.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.Int32Message>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.Int32Message)
-    private static final protobuf_unittest.UnittestProto.Int32Message DEFAULT_INSTANCE;
-    static {
-      Int32Message defaultInstance = new Int32Message();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        Int32Message.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.Int32Message getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<Int32Message> PARSER;
-
-    public static com.google.protobuf.Parser<Int32Message> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface Uint32MessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.Uint32Message)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional uint32 data = 1;</code>
-     * @return Whether the data field is set.
-     */
-    boolean hasData();
-    /**
-     * <code>optional uint32 data = 1;</code>
-     * @return The data.
-     */
-    int getData();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.Uint32Message}
-   */
-  public  static final class Uint32Message extends
-      com.google.protobuf.GeneratedMessageLite<
-          Uint32Message, Uint32Message.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.Uint32Message)
-      Uint32MessageOrBuilder {
-    private Uint32Message() {
-    }
-    private int bitField0_;
-    public static final int DATA_FIELD_NUMBER = 1;
-    private int data_;
-    /**
-     * <code>optional uint32 data = 1;</code>
-     * @return Whether the data field is set.
-     */
-    @java.lang.Override
-    public boolean hasData() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional uint32 data = 1;</code>
-     * @return The data.
-     */
-    @java.lang.Override
-    public int getData() {
-      return data_;
-    }
-    /**
-     * <code>optional uint32 data = 1;</code>
-     * @param value The data to set.
-     */
-    private void setData(int value) {
-      bitField0_ |= 0x00000001;
-      data_ = value;
-    }
-    /**
-     * <code>optional uint32 data = 1;</code>
-     */
-    private void clearData() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      data_ = 0;
-    }
-
-    public static protobuf_unittest.UnittestProto.Uint32Message parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.Uint32Message parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Uint32Message parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.Uint32Message parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Uint32Message parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.Uint32Message parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Uint32Message parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.Uint32Message parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Uint32Message parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.Uint32Message parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Uint32Message parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.Uint32Message parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.Uint32Message prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.Uint32Message}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.Uint32Message, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.Uint32Message)
-        protobuf_unittest.UnittestProto.Uint32MessageOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.Uint32Message.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional uint32 data = 1;</code>
-       * @return Whether the data field is set.
-       */
-      @java.lang.Override
-      public boolean hasData() {
-        return instance.hasData();
-      }
-      /**
-       * <code>optional uint32 data = 1;</code>
-       * @return The data.
-       */
-      @java.lang.Override
-      public int getData() {
-        return instance.getData();
-      }
-      /**
-       * <code>optional uint32 data = 1;</code>
-       * @param value The data to set.
-       * @return This builder for chaining.
-       */
-      public Builder setData(int value) {
-        copyOnWrite();
-        instance.setData(value);
-        return this;
-      }
-      /**
-       * <code>optional uint32 data = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearData() {
-        copyOnWrite();
-        instance.clearData();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.Uint32Message)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.Uint32Message();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "data_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u100b\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.Uint32Message> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.Uint32Message.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.Uint32Message>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.Uint32Message)
-    private static final protobuf_unittest.UnittestProto.Uint32Message DEFAULT_INSTANCE;
-    static {
-      Uint32Message defaultInstance = new Uint32Message();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        Uint32Message.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.Uint32Message getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<Uint32Message> PARSER;
-
-    public static com.google.protobuf.Parser<Uint32Message> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface Int64MessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.Int64Message)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional int64 data = 1;</code>
-     * @return Whether the data field is set.
-     */
-    boolean hasData();
-    /**
-     * <code>optional int64 data = 1;</code>
-     * @return The data.
-     */
-    long getData();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.Int64Message}
-   */
-  public  static final class Int64Message extends
-      com.google.protobuf.GeneratedMessageLite<
-          Int64Message, Int64Message.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.Int64Message)
-      Int64MessageOrBuilder {
-    private Int64Message() {
-    }
-    private int bitField0_;
-    public static final int DATA_FIELD_NUMBER = 1;
-    private long data_;
-    /**
-     * <code>optional int64 data = 1;</code>
-     * @return Whether the data field is set.
-     */
-    @java.lang.Override
-    public boolean hasData() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int64 data = 1;</code>
-     * @return The data.
-     */
-    @java.lang.Override
-    public long getData() {
-      return data_;
-    }
-    /**
-     * <code>optional int64 data = 1;</code>
-     * @param value The data to set.
-     */
-    private void setData(long value) {
-      bitField0_ |= 0x00000001;
-      data_ = value;
-    }
-    /**
-     * <code>optional int64 data = 1;</code>
-     */
-    private void clearData() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      data_ = 0L;
-    }
-
-    public static protobuf_unittest.UnittestProto.Int64Message parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.Int64Message parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Int64Message parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.Int64Message parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Int64Message parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.Int64Message parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Int64Message parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.Int64Message parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Int64Message parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.Int64Message parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Int64Message parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.Int64Message parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.Int64Message prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.Int64Message}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.Int64Message, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.Int64Message)
-        protobuf_unittest.UnittestProto.Int64MessageOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.Int64Message.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int64 data = 1;</code>
-       * @return Whether the data field is set.
-       */
-      @java.lang.Override
-      public boolean hasData() {
-        return instance.hasData();
-      }
-      /**
-       * <code>optional int64 data = 1;</code>
-       * @return The data.
-       */
-      @java.lang.Override
-      public long getData() {
-        return instance.getData();
-      }
-      /**
-       * <code>optional int64 data = 1;</code>
-       * @param value The data to set.
-       * @return This builder for chaining.
-       */
-      public Builder setData(long value) {
-        copyOnWrite();
-        instance.setData(value);
-        return this;
-      }
-      /**
-       * <code>optional int64 data = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearData() {
-        copyOnWrite();
-        instance.clearData();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.Int64Message)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.Int64Message();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "data_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1002\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.Int64Message> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.Int64Message.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.Int64Message>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.Int64Message)
-    private static final protobuf_unittest.UnittestProto.Int64Message DEFAULT_INSTANCE;
-    static {
-      Int64Message defaultInstance = new Int64Message();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        Int64Message.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.Int64Message getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<Int64Message> PARSER;
-
-    public static com.google.protobuf.Parser<Int64Message> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface Uint64MessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.Uint64Message)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional uint64 data = 1;</code>
-     * @return Whether the data field is set.
-     */
-    boolean hasData();
-    /**
-     * <code>optional uint64 data = 1;</code>
-     * @return The data.
-     */
-    long getData();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.Uint64Message}
-   */
-  public  static final class Uint64Message extends
-      com.google.protobuf.GeneratedMessageLite<
-          Uint64Message, Uint64Message.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.Uint64Message)
-      Uint64MessageOrBuilder {
-    private Uint64Message() {
-    }
-    private int bitField0_;
-    public static final int DATA_FIELD_NUMBER = 1;
-    private long data_;
-    /**
-     * <code>optional uint64 data = 1;</code>
-     * @return Whether the data field is set.
-     */
-    @java.lang.Override
-    public boolean hasData() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional uint64 data = 1;</code>
-     * @return The data.
-     */
-    @java.lang.Override
-    public long getData() {
-      return data_;
-    }
-    /**
-     * <code>optional uint64 data = 1;</code>
-     * @param value The data to set.
-     */
-    private void setData(long value) {
-      bitField0_ |= 0x00000001;
-      data_ = value;
-    }
-    /**
-     * <code>optional uint64 data = 1;</code>
-     */
-    private void clearData() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      data_ = 0L;
-    }
-
-    public static protobuf_unittest.UnittestProto.Uint64Message parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.Uint64Message parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Uint64Message parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.Uint64Message parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Uint64Message parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.Uint64Message parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Uint64Message parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.Uint64Message parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Uint64Message parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.Uint64Message parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.Uint64Message parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.Uint64Message parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.Uint64Message prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.Uint64Message}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.Uint64Message, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.Uint64Message)
-        protobuf_unittest.UnittestProto.Uint64MessageOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.Uint64Message.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional uint64 data = 1;</code>
-       * @return Whether the data field is set.
-       */
-      @java.lang.Override
-      public boolean hasData() {
-        return instance.hasData();
-      }
-      /**
-       * <code>optional uint64 data = 1;</code>
-       * @return The data.
-       */
-      @java.lang.Override
-      public long getData() {
-        return instance.getData();
-      }
-      /**
-       * <code>optional uint64 data = 1;</code>
-       * @param value The data to set.
-       * @return This builder for chaining.
-       */
-      public Builder setData(long value) {
-        copyOnWrite();
-        instance.setData(value);
-        return this;
-      }
-      /**
-       * <code>optional uint64 data = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearData() {
-        copyOnWrite();
-        instance.clearData();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.Uint64Message)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.Uint64Message();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "data_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1003\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.Uint64Message> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.Uint64Message.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.Uint64Message>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.Uint64Message)
-    private static final protobuf_unittest.UnittestProto.Uint64Message DEFAULT_INSTANCE;
-    static {
-      Uint64Message defaultInstance = new Uint64Message();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        Uint64Message.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.Uint64Message getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<Uint64Message> PARSER;
-
-    public static com.google.protobuf.Parser<Uint64Message> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface BoolMessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.BoolMessage)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional bool data = 1;</code>
-     * @return Whether the data field is set.
-     */
-    boolean hasData();
-    /**
-     * <code>optional bool data = 1;</code>
-     * @return The data.
-     */
-    boolean getData();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.BoolMessage}
-   */
-  public  static final class BoolMessage extends
-      com.google.protobuf.GeneratedMessageLite<
-          BoolMessage, BoolMessage.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.BoolMessage)
-      BoolMessageOrBuilder {
-    private BoolMessage() {
-    }
-    private int bitField0_;
-    public static final int DATA_FIELD_NUMBER = 1;
-    private boolean data_;
-    /**
-     * <code>optional bool data = 1;</code>
-     * @return Whether the data field is set.
-     */
-    @java.lang.Override
-    public boolean hasData() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional bool data = 1;</code>
-     * @return The data.
-     */
-    @java.lang.Override
-    public boolean getData() {
-      return data_;
-    }
-    /**
-     * <code>optional bool data = 1;</code>
-     * @param value The data to set.
-     */
-    private void setData(boolean value) {
-      bitField0_ |= 0x00000001;
-      data_ = value;
-    }
-    /**
-     * <code>optional bool data = 1;</code>
-     */
-    private void clearData() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      data_ = false;
-    }
-
-    public static protobuf_unittest.UnittestProto.BoolMessage parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.BoolMessage parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.BoolMessage parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.BoolMessage parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.BoolMessage parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.BoolMessage parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.BoolMessage parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.BoolMessage parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.BoolMessage parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.BoolMessage parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.BoolMessage parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.BoolMessage parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.BoolMessage prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.BoolMessage}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.BoolMessage, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.BoolMessage)
-        protobuf_unittest.UnittestProto.BoolMessageOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.BoolMessage.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional bool data = 1;</code>
-       * @return Whether the data field is set.
-       */
-      @java.lang.Override
-      public boolean hasData() {
-        return instance.hasData();
-      }
-      /**
-       * <code>optional bool data = 1;</code>
-       * @return The data.
-       */
-      @java.lang.Override
-      public boolean getData() {
-        return instance.getData();
-      }
-      /**
-       * <code>optional bool data = 1;</code>
-       * @param value The data to set.
-       * @return This builder for chaining.
-       */
-      public Builder setData(boolean value) {
-        copyOnWrite();
-        instance.setData(value);
-        return this;
-      }
-      /**
-       * <code>optional bool data = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearData() {
-        copyOnWrite();
-        instance.clearData();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.BoolMessage)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.BoolMessage();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "data_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1007\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.BoolMessage> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.BoolMessage.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.BoolMessage>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.BoolMessage)
-    private static final protobuf_unittest.UnittestProto.BoolMessage DEFAULT_INSTANCE;
-    static {
-      BoolMessage defaultInstance = new BoolMessage();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        BoolMessage.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.BoolMessage getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<BoolMessage> PARSER;
-
-    public static com.google.protobuf.Parser<BoolMessage> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestOneofOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestOneof)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>int32 foo_int = 1;</code>
-     * @return Whether the fooInt field is set.
-     */
-    boolean hasFooInt();
-    /**
-     * <code>int32 foo_int = 1;</code>
-     * @return The fooInt.
-     */
-    int getFooInt();
-
-    /**
-     * <code>string foo_string = 2;</code>
-     * @return Whether the fooString field is set.
-     */
-    boolean hasFooString();
-    /**
-     * <code>string foo_string = 2;</code>
-     * @return The fooString.
-     */
-    java.lang.String getFooString();
-    /**
-     * <code>string foo_string = 2;</code>
-     * @return The bytes for fooString.
-     */
-    com.google.protobuf.ByteString
-        getFooStringBytes();
-
-    /**
-     * <code>.protobuf_unittest.TestAllTypes foo_message = 3;</code>
-     * @return Whether the fooMessage field is set.
-     */
-    boolean hasFooMessage();
-    /**
-     * <code>.protobuf_unittest.TestAllTypes foo_message = 3;</code>
-     * @return The fooMessage.
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes getFooMessage();
-
-    /**
-     * <code>group FooGroup = 4 { ... }</code>
-     * @return Whether the foogroup field is set.
-     */
-    boolean hasFooGroup();
-    /**
-     * <code>group FooGroup = 4 { ... }</code>
-     * @return The foogroup.
-     */
-    protobuf_unittest.UnittestProto.TestOneof.FooGroup getFooGroup();
-
-    public protobuf_unittest.UnittestProto.TestOneof.FooCase getFooCase();
-  }
-  /**
-   * <pre>
-   * Test oneofs.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestOneof}
-   */
-  public  static final class TestOneof extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestOneof, TestOneof.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestOneof)
-      TestOneofOrBuilder {
-    private TestOneof() {
-    }
-    public interface FooGroupOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestOneof.FooGroup)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int32 a = 5;</code>
-       * @return Whether the a field is set.
-       */
-      boolean hasA();
-      /**
-       * <code>optional int32 a = 5;</code>
-       * @return The a.
-       */
-      int getA();
-
-      /**
-       * <code>optional string b = 6;</code>
-       * @return Whether the b field is set.
-       */
-      boolean hasB();
-      /**
-       * <code>optional string b = 6;</code>
-       * @return The b.
-       */
-      java.lang.String getB();
-      /**
-       * <code>optional string b = 6;</code>
-       * @return The bytes for b.
-       */
-      com.google.protobuf.ByteString
-          getBBytes();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestOneof.FooGroup}
-     */
-    public  static final class FooGroup extends
-        com.google.protobuf.GeneratedMessageLite<
-            FooGroup, FooGroup.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestOneof.FooGroup)
-        FooGroupOrBuilder {
-      private FooGroup() {
-        b_ = "";
-      }
-      private int bitField0_;
-      public static final int A_FIELD_NUMBER = 5;
-      private int a_;
-      /**
-       * <code>optional int32 a = 5;</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int32 a = 5;</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public int getA() {
-        return a_;
-      }
-      /**
-       * <code>optional int32 a = 5;</code>
-       * @param value The a to set.
-       */
-      private void setA(int value) {
-        bitField0_ |= 0x00000001;
-        a_ = value;
-      }
-      /**
-       * <code>optional int32 a = 5;</code>
-       */
-      private void clearA() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        a_ = 0;
-      }
-
-      public static final int B_FIELD_NUMBER = 6;
-      private java.lang.String b_;
-      /**
-       * <code>optional string b = 6;</code>
-       * @return Whether the b field is set.
-       */
-      @java.lang.Override
-      public boolean hasB() {
-        return ((bitField0_ & 0x00000002) != 0);
-      }
-      /**
-       * <code>optional string b = 6;</code>
-       * @return The b.
-       */
-      @java.lang.Override
-      public java.lang.String getB() {
-        return b_;
-      }
-      /**
-       * <code>optional string b = 6;</code>
-       * @return The bytes for b.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getBBytes() {
-        return com.google.protobuf.ByteString.copyFromUtf8(b_);
-      }
-      /**
-       * <code>optional string b = 6;</code>
-       * @param value The b to set.
-       */
-      private void setB(
-          java.lang.String value) {
-        value.getClass();
-  bitField0_ |= 0x00000002;
-        b_ = value;
-      }
-      /**
-       * <code>optional string b = 6;</code>
-       */
-      private void clearB() {
-        bitField0_ = (bitField0_ & ~0x00000002);
-        b_ = getDefaultInstance().getB();
-      }
-      /**
-       * <code>optional string b = 6;</code>
-       * @param value The bytes for b to set.
-       */
-      private void setBBytes(
-          com.google.protobuf.ByteString value) {
-        b_ = value.toStringUtf8();
-        bitField0_ |= 0x00000002;
-      }
-
-      public static protobuf_unittest.UnittestProto.TestOneof.FooGroup parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof.FooGroup parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof.FooGroup parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof.FooGroup parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof.FooGroup parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof.FooGroup parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof.FooGroup parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof.FooGroup parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof.FooGroup parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof.FooGroup parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof.FooGroup parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof.FooGroup parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestOneof.FooGroup prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestOneof.FooGroup}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestOneof.FooGroup, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestOneof.FooGroup)
-          protobuf_unittest.UnittestProto.TestOneof.FooGroupOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestOneof.FooGroup.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int32 a = 5;</code>
-         * @return Whether the a field is set.
-         */
-        @java.lang.Override
-        public boolean hasA() {
-          return instance.hasA();
-        }
-        /**
-         * <code>optional int32 a = 5;</code>
-         * @return The a.
-         */
-        @java.lang.Override
-        public int getA() {
-          return instance.getA();
-        }
-        /**
-         * <code>optional int32 a = 5;</code>
-         * @param value The a to set.
-         * @return This builder for chaining.
-         */
-        public Builder setA(int value) {
-          copyOnWrite();
-          instance.setA(value);
-          return this;
-        }
-        /**
-         * <code>optional int32 a = 5;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearA() {
-          copyOnWrite();
-          instance.clearA();
-          return this;
-        }
-
-        /**
-         * <code>optional string b = 6;</code>
-         * @return Whether the b field is set.
-         */
-        @java.lang.Override
-        public boolean hasB() {
-          return instance.hasB();
-        }
-        /**
-         * <code>optional string b = 6;</code>
-         * @return The b.
-         */
-        @java.lang.Override
-        public java.lang.String getB() {
-          return instance.getB();
-        }
-        /**
-         * <code>optional string b = 6;</code>
-         * @return The bytes for b.
-         */
-        @java.lang.Override
-        public com.google.protobuf.ByteString
-            getBBytes() {
-          return instance.getBBytes();
-        }
-        /**
-         * <code>optional string b = 6;</code>
-         * @param value The b to set.
-         * @return This builder for chaining.
-         */
-        public Builder setB(
-            java.lang.String value) {
-          copyOnWrite();
-          instance.setB(value);
-          return this;
-        }
-        /**
-         * <code>optional string b = 6;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearB() {
-          copyOnWrite();
-          instance.clearB();
-          return this;
-        }
-        /**
-         * <code>optional string b = 6;</code>
-         * @param value The bytes for b to set.
-         * @return This builder for chaining.
-         */
-        public Builder setBBytes(
-            com.google.protobuf.ByteString value) {
-          copyOnWrite();
-          instance.setBBytes(value);
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestOneof.FooGroup)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestOneof.FooGroup();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "a_",
-                "b_",
-              };
-              java.lang.String info =
-                  "\u0001\u0002\u0000\u0001\u0005\u0006\u0002\u0000\u0000\u0000\u0005\u1004\u0000\u0006" +
-                  "\u1008\u0001";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestOneof.FooGroup> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestOneof.FooGroup.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestOneof.FooGroup>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestOneof.FooGroup)
-      private static final protobuf_unittest.UnittestProto.TestOneof.FooGroup DEFAULT_INSTANCE;
-      static {
-        FooGroup defaultInstance = new FooGroup();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          FooGroup.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestOneof.FooGroup getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<FooGroup> PARSER;
-
-      public static com.google.protobuf.Parser<FooGroup> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int bitField0_;
-    private int fooCase_ = 0;
-    private java.lang.Object foo_;
-    public enum FooCase {
-      FOO_INT(1),
-      FOO_STRING(2),
-      FOO_MESSAGE(3),
-      FOOGROUP(4),
-      FOO_NOT_SET(0);
-      private final int value;
-      private FooCase(int value) {
-        this.value = value;
-      }
-      /**
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static FooCase valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static FooCase forNumber(int value) {
-        switch (value) {
-          case 1: return FOO_INT;
-          case 2: return FOO_STRING;
-          case 3: return FOO_MESSAGE;
-          case 4: return FOOGROUP;
-          case 0: return FOO_NOT_SET;
-          default: return null;
-        }
-      }
-      public int getNumber() {
-        return this.value;
-      }
-    };
-
-    @java.lang.Override
-    public FooCase
-    getFooCase() {
-      return FooCase.forNumber(
-          fooCase_);
-    }
-
-    private void clearFoo() {
-      fooCase_ = 0;
-      foo_ = null;
-    }
-
-    public static final int FOO_INT_FIELD_NUMBER = 1;
-    /**
-     * <code>int32 foo_int = 1;</code>
-     * @return Whether the fooInt field is set.
-     */
-    @java.lang.Override
-    public boolean hasFooInt() {
-      return fooCase_ == 1;
-    }
-    /**
-     * <code>int32 foo_int = 1;</code>
-     * @return The fooInt.
-     */
-    @java.lang.Override
-    public int getFooInt() {
-      if (fooCase_ == 1) {
-        return (java.lang.Integer) foo_;
-      }
-      return 0;
-    }
-    /**
-     * <code>int32 foo_int = 1;</code>
-     * @param value The fooInt to set.
-     */
-    private void setFooInt(int value) {
-      fooCase_ = 1;
-      foo_ = value;
-    }
-    /**
-     * <code>int32 foo_int = 1;</code>
-     */
-    private void clearFooInt() {
-      if (fooCase_ == 1) {
-        fooCase_ = 0;
-        foo_ = null;
-      }
-    }
-
-    public static final int FOO_STRING_FIELD_NUMBER = 2;
-    /**
-     * <code>string foo_string = 2;</code>
-     * @return Whether the fooString field is set.
-     */
-    @java.lang.Override
-    public boolean hasFooString() {
-      return fooCase_ == 2;
-    }
-    /**
-     * <code>string foo_string = 2;</code>
-     * @return The fooString.
-     */
-    @java.lang.Override
-    public java.lang.String getFooString() {
-      java.lang.String ref = "";
-      if (fooCase_ == 2) {
-        ref = (java.lang.String) foo_;
-      }
-      return ref;
-    }
-    /**
-     * <code>string foo_string = 2;</code>
-     * @return The bytes for fooString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getFooStringBytes() {
-      java.lang.String ref = "";
-      if (fooCase_ == 2) {
-        ref = (java.lang.String) foo_;
-      }
-      return com.google.protobuf.ByteString.copyFromUtf8(ref);
-    }
-    /**
-     * <code>string foo_string = 2;</code>
-     * @param value The fooString to set.
-     */
-    private void setFooString(
-        java.lang.String value) {
-      value.getClass();
-  fooCase_ = 2;
-      foo_ = value;
-    }
-    /**
-     * <code>string foo_string = 2;</code>
-     */
-    private void clearFooString() {
-      if (fooCase_ == 2) {
-        fooCase_ = 0;
-        foo_ = null;
-      }
-    }
-    /**
-     * <code>string foo_string = 2;</code>
-     * @param value The bytes for fooString to set.
-     */
-    private void setFooStringBytes(
-        com.google.protobuf.ByteString value) {
-      foo_ = value.toStringUtf8();
-      fooCase_ = 2;
-    }
-
-    public static final int FOO_MESSAGE_FIELD_NUMBER = 3;
-    /**
-     * <code>.protobuf_unittest.TestAllTypes foo_message = 3;</code>
-     */
-    @java.lang.Override
-    public boolean hasFooMessage() {
-      return fooCase_ == 3;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypes foo_message = 3;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes getFooMessage() {
-      if (fooCase_ == 3) {
-         return (protobuf_unittest.UnittestProto.TestAllTypes) foo_;
-      }
-      return protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance();
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypes foo_message = 3;</code>
-     */
-    private void setFooMessage(protobuf_unittest.UnittestProto.TestAllTypes value) {
-      value.getClass();
-  foo_ = value;
-      fooCase_ = 3;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypes foo_message = 3;</code>
-     */
-    private void mergeFooMessage(protobuf_unittest.UnittestProto.TestAllTypes value) {
-      value.getClass();
-  if (fooCase_ == 3 &&
-          foo_ != protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance()) {
-        foo_ = protobuf_unittest.UnittestProto.TestAllTypes.newBuilder((protobuf_unittest.UnittestProto.TestAllTypes) foo_)
-            .mergeFrom(value).buildPartial();
-      } else {
-        foo_ = value;
-      }
-      fooCase_ = 3;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypes foo_message = 3;</code>
-     */
-    private void clearFooMessage() {
-      if (fooCase_ == 3) {
-        fooCase_ = 0;
-        foo_ = null;
-      }
-    }
-
-    public static final int FOOGROUP_FIELD_NUMBER = 4;
-    /**
-     * <code>group FooGroup = 4 { ... }</code>
-     */
-    @java.lang.Override
-    public boolean hasFooGroup() {
-      return fooCase_ == 4;
-    }
-    /**
-     * <code>group FooGroup = 4 { ... }</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestOneof.FooGroup getFooGroup() {
-      if (fooCase_ == 4) {
-         return (protobuf_unittest.UnittestProto.TestOneof.FooGroup) foo_;
-      }
-      return protobuf_unittest.UnittestProto.TestOneof.FooGroup.getDefaultInstance();
-    }
-    /**
-     * <code>group FooGroup = 4 { ... }</code>
-     */
-    private void setFooGroup(protobuf_unittest.UnittestProto.TestOneof.FooGroup value) {
-      value.getClass();
-  foo_ = value;
-      fooCase_ = 4;
-    }
-    /**
-     * <code>group FooGroup = 4 { ... }</code>
-     */
-    private void mergeFooGroup(protobuf_unittest.UnittestProto.TestOneof.FooGroup value) {
-      value.getClass();
-  if (fooCase_ == 4 &&
-          foo_ != protobuf_unittest.UnittestProto.TestOneof.FooGroup.getDefaultInstance()) {
-        foo_ = protobuf_unittest.UnittestProto.TestOneof.FooGroup.newBuilder((protobuf_unittest.UnittestProto.TestOneof.FooGroup) foo_)
-            .mergeFrom(value).buildPartial();
-      } else {
-        foo_ = value;
-      }
-      fooCase_ = 4;
-    }
-    /**
-     * <code>group FooGroup = 4 { ... }</code>
-     */
-    private void clearFooGroup() {
-      if (fooCase_ == 4) {
-        fooCase_ = 0;
-        foo_ = null;
-      }
-    }
-
-    public static protobuf_unittest.UnittestProto.TestOneof parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestOneof prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Test oneofs.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestOneof}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestOneof, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestOneof)
-        protobuf_unittest.UnittestProto.TestOneofOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestOneof.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-      @java.lang.Override
-      public FooCase
-          getFooCase() {
-        return instance.getFooCase();
-      }
-
-      public Builder clearFoo() {
-        copyOnWrite();
-        instance.clearFoo();
-        return this;
-      }
-
-
-      /**
-       * <code>int32 foo_int = 1;</code>
-       * @return Whether the fooInt field is set.
-       */
-      @java.lang.Override
-      public boolean hasFooInt() {
-        return instance.hasFooInt();
-      }
-      /**
-       * <code>int32 foo_int = 1;</code>
-       * @return The fooInt.
-       */
-      @java.lang.Override
-      public int getFooInt() {
-        return instance.getFooInt();
-      }
-      /**
-       * <code>int32 foo_int = 1;</code>
-       * @param value The fooInt to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooInt(int value) {
-        copyOnWrite();
-        instance.setFooInt(value);
-        return this;
-      }
-      /**
-       * <code>int32 foo_int = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFooInt() {
-        copyOnWrite();
-        instance.clearFooInt();
-        return this;
-      }
-
-      /**
-       * <code>string foo_string = 2;</code>
-       * @return Whether the fooString field is set.
-       */
-      @java.lang.Override
-      public boolean hasFooString() {
-        return instance.hasFooString();
-      }
-      /**
-       * <code>string foo_string = 2;</code>
-       * @return The fooString.
-       */
-      @java.lang.Override
-      public java.lang.String getFooString() {
-        return instance.getFooString();
-      }
-      /**
-       * <code>string foo_string = 2;</code>
-       * @return The bytes for fooString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getFooStringBytes() {
-        return instance.getFooStringBytes();
-      }
-      /**
-       * <code>string foo_string = 2;</code>
-       * @param value The fooString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setFooString(value);
-        return this;
-      }
-      /**
-       * <code>string foo_string = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFooString() {
-        copyOnWrite();
-        instance.clearFooString();
-        return this;
-      }
-      /**
-       * <code>string foo_string = 2;</code>
-       * @param value The bytes for fooString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setFooStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>.protobuf_unittest.TestAllTypes foo_message = 3;</code>
-       */
-      @java.lang.Override
-      public boolean hasFooMessage() {
-        return instance.hasFooMessage();
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypes foo_message = 3;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes getFooMessage() {
-        return instance.getFooMessage();
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypes foo_message = 3;</code>
-       */
-      public Builder setFooMessage(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        copyOnWrite();
-        instance.setFooMessage(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypes foo_message = 3;</code>
-       */
-      public Builder setFooMessage(
-          protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-        copyOnWrite();
-        instance.setFooMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypes foo_message = 3;</code>
-       */
-      public Builder mergeFooMessage(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        copyOnWrite();
-        instance.mergeFooMessage(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypes foo_message = 3;</code>
-       */
-      public Builder clearFooMessage() {
-        copyOnWrite();
-        instance.clearFooMessage();
-        return this;
-      }
-
-      /**
-       * <code>group FooGroup = 4 { ... }</code>
-       */
-      @java.lang.Override
-      public boolean hasFooGroup() {
-        return instance.hasFooGroup();
-      }
-      /**
-       * <code>group FooGroup = 4 { ... }</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestOneof.FooGroup getFooGroup() {
-        return instance.getFooGroup();
-      }
-      /**
-       * <code>group FooGroup = 4 { ... }</code>
-       */
-      public Builder setFooGroup(protobuf_unittest.UnittestProto.TestOneof.FooGroup value) {
-        copyOnWrite();
-        instance.setFooGroup(value);
-        return this;
-      }
-      /**
-       * <code>group FooGroup = 4 { ... }</code>
-       */
-      public Builder setFooGroup(
-          protobuf_unittest.UnittestProto.TestOneof.FooGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.setFooGroup(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>group FooGroup = 4 { ... }</code>
-       */
-      public Builder mergeFooGroup(protobuf_unittest.UnittestProto.TestOneof.FooGroup value) {
-        copyOnWrite();
-        instance.mergeFooGroup(value);
-        return this;
-      }
-      /**
-       * <code>group FooGroup = 4 { ... }</code>
-       */
-      public Builder clearFooGroup() {
-        copyOnWrite();
-        instance.clearFooGroup();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestOneof)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestOneof();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "foo_",
-              "fooCase_",
-              "bitField0_",
-              protobuf_unittest.UnittestProto.TestAllTypes.class,
-              protobuf_unittest.UnittestProto.TestOneof.FooGroup.class,
-            };
-            java.lang.String info =
-                "\u0001\u0004\u0001\u0001\u0001\u0004\u0004\u0000\u0000\u0000\u0001\u1037\u0000\u0002" +
-                "\u103b\u0000\u0003\u103c\u0000\u0004\u1044\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestOneof> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestOneof.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestOneof>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestOneof)
-    private static final protobuf_unittest.UnittestProto.TestOneof DEFAULT_INSTANCE;
-    static {
-      TestOneof defaultInstance = new TestOneof();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestOneof.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestOneof getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestOneof> PARSER;
-
-    public static com.google.protobuf.Parser<TestOneof> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestOneofBackwardsCompatibleOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestOneofBackwardsCompatible)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional int32 foo_int = 1;</code>
-     * @return Whether the fooInt field is set.
-     */
-    boolean hasFooInt();
-    /**
-     * <code>optional int32 foo_int = 1;</code>
-     * @return The fooInt.
-     */
-    int getFooInt();
-
-    /**
-     * <code>optional string foo_string = 2;</code>
-     * @return Whether the fooString field is set.
-     */
-    boolean hasFooString();
-    /**
-     * <code>optional string foo_string = 2;</code>
-     * @return The fooString.
-     */
-    java.lang.String getFooString();
-    /**
-     * <code>optional string foo_string = 2;</code>
-     * @return The bytes for fooString.
-     */
-    com.google.protobuf.ByteString
-        getFooStringBytes();
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes foo_message = 3;</code>
-     * @return Whether the fooMessage field is set.
-     */
-    boolean hasFooMessage();
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes foo_message = 3;</code>
-     * @return The fooMessage.
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes getFooMessage();
-
-    /**
-     * <code>optional group FooGroup = 4 { ... }</code>
-     * @return Whether the foogroup field is set.
-     */
-    boolean hasFooGroup();
-    /**
-     * <code>optional group FooGroup = 4 { ... }</code>
-     * @return The foogroup.
-     */
-    protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup getFooGroup();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestOneofBackwardsCompatible}
-   */
-  public  static final class TestOneofBackwardsCompatible extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestOneofBackwardsCompatible, TestOneofBackwardsCompatible.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestOneofBackwardsCompatible)
-      TestOneofBackwardsCompatibleOrBuilder {
-    private TestOneofBackwardsCompatible() {
-      fooString_ = "";
-    }
-    public interface FooGroupOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestOneofBackwardsCompatible.FooGroup)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int32 a = 5;</code>
-       * @return Whether the a field is set.
-       */
-      boolean hasA();
-      /**
-       * <code>optional int32 a = 5;</code>
-       * @return The a.
-       */
-      int getA();
-
-      /**
-       * <code>optional string b = 6;</code>
-       * @return Whether the b field is set.
-       */
-      boolean hasB();
-      /**
-       * <code>optional string b = 6;</code>
-       * @return The b.
-       */
-      java.lang.String getB();
-      /**
-       * <code>optional string b = 6;</code>
-       * @return The bytes for b.
-       */
-      com.google.protobuf.ByteString
-          getBBytes();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestOneofBackwardsCompatible.FooGroup}
-     */
-    public  static final class FooGroup extends
-        com.google.protobuf.GeneratedMessageLite<
-            FooGroup, FooGroup.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestOneofBackwardsCompatible.FooGroup)
-        FooGroupOrBuilder {
-      private FooGroup() {
-        b_ = "";
-      }
-      private int bitField0_;
-      public static final int A_FIELD_NUMBER = 5;
-      private int a_;
-      /**
-       * <code>optional int32 a = 5;</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int32 a = 5;</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public int getA() {
-        return a_;
-      }
-      /**
-       * <code>optional int32 a = 5;</code>
-       * @param value The a to set.
-       */
-      private void setA(int value) {
-        bitField0_ |= 0x00000001;
-        a_ = value;
-      }
-      /**
-       * <code>optional int32 a = 5;</code>
-       */
-      private void clearA() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        a_ = 0;
-      }
-
-      public static final int B_FIELD_NUMBER = 6;
-      private java.lang.String b_;
-      /**
-       * <code>optional string b = 6;</code>
-       * @return Whether the b field is set.
-       */
-      @java.lang.Override
-      public boolean hasB() {
-        return ((bitField0_ & 0x00000002) != 0);
-      }
-      /**
-       * <code>optional string b = 6;</code>
-       * @return The b.
-       */
-      @java.lang.Override
-      public java.lang.String getB() {
-        return b_;
-      }
-      /**
-       * <code>optional string b = 6;</code>
-       * @return The bytes for b.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getBBytes() {
-        return com.google.protobuf.ByteString.copyFromUtf8(b_);
-      }
-      /**
-       * <code>optional string b = 6;</code>
-       * @param value The b to set.
-       */
-      private void setB(
-          java.lang.String value) {
-        value.getClass();
-  bitField0_ |= 0x00000002;
-        b_ = value;
-      }
-      /**
-       * <code>optional string b = 6;</code>
-       */
-      private void clearB() {
-        bitField0_ = (bitField0_ & ~0x00000002);
-        b_ = getDefaultInstance().getB();
-      }
-      /**
-       * <code>optional string b = 6;</code>
-       * @param value The bytes for b to set.
-       */
-      private void setBBytes(
-          com.google.protobuf.ByteString value) {
-        b_ = value.toStringUtf8();
-        bitField0_ |= 0x00000002;
-      }
-
-      public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestOneofBackwardsCompatible.FooGroup}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestOneofBackwardsCompatible.FooGroup)
-          protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroupOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int32 a = 5;</code>
-         * @return Whether the a field is set.
-         */
-        @java.lang.Override
-        public boolean hasA() {
-          return instance.hasA();
-        }
-        /**
-         * <code>optional int32 a = 5;</code>
-         * @return The a.
-         */
-        @java.lang.Override
-        public int getA() {
-          return instance.getA();
-        }
-        /**
-         * <code>optional int32 a = 5;</code>
-         * @param value The a to set.
-         * @return This builder for chaining.
-         */
-        public Builder setA(int value) {
-          copyOnWrite();
-          instance.setA(value);
-          return this;
-        }
-        /**
-         * <code>optional int32 a = 5;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearA() {
-          copyOnWrite();
-          instance.clearA();
-          return this;
-        }
-
-        /**
-         * <code>optional string b = 6;</code>
-         * @return Whether the b field is set.
-         */
-        @java.lang.Override
-        public boolean hasB() {
-          return instance.hasB();
-        }
-        /**
-         * <code>optional string b = 6;</code>
-         * @return The b.
-         */
-        @java.lang.Override
-        public java.lang.String getB() {
-          return instance.getB();
-        }
-        /**
-         * <code>optional string b = 6;</code>
-         * @return The bytes for b.
-         */
-        @java.lang.Override
-        public com.google.protobuf.ByteString
-            getBBytes() {
-          return instance.getBBytes();
-        }
-        /**
-         * <code>optional string b = 6;</code>
-         * @param value The b to set.
-         * @return This builder for chaining.
-         */
-        public Builder setB(
-            java.lang.String value) {
-          copyOnWrite();
-          instance.setB(value);
-          return this;
-        }
-        /**
-         * <code>optional string b = 6;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearB() {
-          copyOnWrite();
-          instance.clearB();
-          return this;
-        }
-        /**
-         * <code>optional string b = 6;</code>
-         * @param value The bytes for b to set.
-         * @return This builder for chaining.
-         */
-        public Builder setBBytes(
-            com.google.protobuf.ByteString value) {
-          copyOnWrite();
-          instance.setBBytes(value);
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestOneofBackwardsCompatible.FooGroup)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "a_",
-                "b_",
-              };
-              java.lang.String info =
-                  "\u0001\u0002\u0000\u0001\u0005\u0006\u0002\u0000\u0000\u0000\u0005\u1004\u0000\u0006" +
-                  "\u1008\u0001";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestOneofBackwardsCompatible.FooGroup)
-      private static final protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup DEFAULT_INSTANCE;
-      static {
-        FooGroup defaultInstance = new FooGroup();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          FooGroup.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<FooGroup> PARSER;
-
-      public static com.google.protobuf.Parser<FooGroup> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int bitField0_;
-    public static final int FOO_INT_FIELD_NUMBER = 1;
-    private int fooInt_;
-    /**
-     * <code>optional int32 foo_int = 1;</code>
-     * @return Whether the fooInt field is set.
-     */
-    @java.lang.Override
-    public boolean hasFooInt() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 foo_int = 1;</code>
-     * @return The fooInt.
-     */
-    @java.lang.Override
-    public int getFooInt() {
-      return fooInt_;
-    }
-    /**
-     * <code>optional int32 foo_int = 1;</code>
-     * @param value The fooInt to set.
-     */
-    private void setFooInt(int value) {
-      bitField0_ |= 0x00000001;
-      fooInt_ = value;
-    }
-    /**
-     * <code>optional int32 foo_int = 1;</code>
-     */
-    private void clearFooInt() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      fooInt_ = 0;
-    }
-
-    public static final int FOO_STRING_FIELD_NUMBER = 2;
-    private java.lang.String fooString_;
-    /**
-     * <code>optional string foo_string = 2;</code>
-     * @return Whether the fooString field is set.
-     */
-    @java.lang.Override
-    public boolean hasFooString() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional string foo_string = 2;</code>
-     * @return The fooString.
-     */
-    @java.lang.Override
-    public java.lang.String getFooString() {
-      return fooString_;
-    }
-    /**
-     * <code>optional string foo_string = 2;</code>
-     * @return The bytes for fooString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getFooStringBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(fooString_);
-    }
-    /**
-     * <code>optional string foo_string = 2;</code>
-     * @param value The fooString to set.
-     */
-    private void setFooString(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00000002;
-      fooString_ = value;
-    }
-    /**
-     * <code>optional string foo_string = 2;</code>
-     */
-    private void clearFooString() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      fooString_ = getDefaultInstance().getFooString();
-    }
-    /**
-     * <code>optional string foo_string = 2;</code>
-     * @param value The bytes for fooString to set.
-     */
-    private void setFooStringBytes(
-        com.google.protobuf.ByteString value) {
-      fooString_ = value.toStringUtf8();
-      bitField0_ |= 0x00000002;
-    }
-
-    public static final int FOO_MESSAGE_FIELD_NUMBER = 3;
-    private protobuf_unittest.UnittestProto.TestAllTypes fooMessage_;
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes foo_message = 3;</code>
-     */
-    @java.lang.Override
-    public boolean hasFooMessage() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes foo_message = 3;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes getFooMessage() {
-      return fooMessage_ == null ? protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance() : fooMessage_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes foo_message = 3;</code>
-     */
-    private void setFooMessage(protobuf_unittest.UnittestProto.TestAllTypes value) {
-      value.getClass();
-  fooMessage_ = value;
-      bitField0_ |= 0x00000004;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes foo_message = 3;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeFooMessage(protobuf_unittest.UnittestProto.TestAllTypes value) {
-      value.getClass();
-  if (fooMessage_ != null &&
-          fooMessage_ != protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance()) {
-        fooMessage_ =
-          protobuf_unittest.UnittestProto.TestAllTypes.newBuilder(fooMessage_).mergeFrom(value).buildPartial();
-      } else {
-        fooMessage_ = value;
-      }
-      bitField0_ |= 0x00000004;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes foo_message = 3;</code>
-     */
-    private void clearFooMessage() {  fooMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x00000004);
-    }
-
-    public static final int FOOGROUP_FIELD_NUMBER = 4;
-    private protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup fooGroup_;
-    /**
-     * <code>optional group FooGroup = 4 { ... }</code>
-     */
-    @java.lang.Override
-    public boolean hasFooGroup() {
-      return ((bitField0_ & 0x00000008) != 0);
-    }
-    /**
-     * <code>optional group FooGroup = 4 { ... }</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup getFooGroup() {
-      return fooGroup_ == null ? protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup.getDefaultInstance() : fooGroup_;
-    }
-    /**
-     * <code>optional group FooGroup = 4 { ... }</code>
-     */
-    private void setFooGroup(protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup value) {
-      value.getClass();
-  fooGroup_ = value;
-      bitField0_ |= 0x00000008;
-      }
-    /**
-     * <code>optional group FooGroup = 4 { ... }</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeFooGroup(protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup value) {
-      value.getClass();
-  if (fooGroup_ != null &&
-          fooGroup_ != protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup.getDefaultInstance()) {
-        fooGroup_ =
-          protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup.newBuilder(fooGroup_).mergeFrom(value).buildPartial();
-      } else {
-        fooGroup_ = value;
-      }
-      bitField0_ |= 0x00000008;
-    }
-    /**
-     * <code>optional group FooGroup = 4 { ... }</code>
-     */
-    private void clearFooGroup() {  fooGroup_ = null;
-      bitField0_ = (bitField0_ & ~0x00000008);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestOneofBackwardsCompatible}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestOneofBackwardsCompatible)
-        protobuf_unittest.UnittestProto.TestOneofBackwardsCompatibleOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int32 foo_int = 1;</code>
-       * @return Whether the fooInt field is set.
-       */
-      @java.lang.Override
-      public boolean hasFooInt() {
-        return instance.hasFooInt();
-      }
-      /**
-       * <code>optional int32 foo_int = 1;</code>
-       * @return The fooInt.
-       */
-      @java.lang.Override
-      public int getFooInt() {
-        return instance.getFooInt();
-      }
-      /**
-       * <code>optional int32 foo_int = 1;</code>
-       * @param value The fooInt to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooInt(int value) {
-        copyOnWrite();
-        instance.setFooInt(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 foo_int = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFooInt() {
-        copyOnWrite();
-        instance.clearFooInt();
-        return this;
-      }
-
-      /**
-       * <code>optional string foo_string = 2;</code>
-       * @return Whether the fooString field is set.
-       */
-      @java.lang.Override
-      public boolean hasFooString() {
-        return instance.hasFooString();
-      }
-      /**
-       * <code>optional string foo_string = 2;</code>
-       * @return The fooString.
-       */
-      @java.lang.Override
-      public java.lang.String getFooString() {
-        return instance.getFooString();
-      }
-      /**
-       * <code>optional string foo_string = 2;</code>
-       * @return The bytes for fooString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getFooStringBytes() {
-        return instance.getFooStringBytes();
-      }
-      /**
-       * <code>optional string foo_string = 2;</code>
-       * @param value The fooString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setFooString(value);
-        return this;
-      }
-      /**
-       * <code>optional string foo_string = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFooString() {
-        copyOnWrite();
-        instance.clearFooString();
-        return this;
-      }
-      /**
-       * <code>optional string foo_string = 2;</code>
-       * @param value The bytes for fooString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setFooStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes foo_message = 3;</code>
-       */
-      @java.lang.Override
-      public boolean hasFooMessage() {
-        return instance.hasFooMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes foo_message = 3;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes getFooMessage() {
-        return instance.getFooMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes foo_message = 3;</code>
-       */
-      public Builder setFooMessage(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        copyOnWrite();
-        instance.setFooMessage(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes foo_message = 3;</code>
-       */
-      public Builder setFooMessage(
-          protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-        copyOnWrite();
-        instance.setFooMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes foo_message = 3;</code>
-       */
-      public Builder mergeFooMessage(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        copyOnWrite();
-        instance.mergeFooMessage(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes foo_message = 3;</code>
-       */
-      public Builder clearFooMessage() {  copyOnWrite();
-        instance.clearFooMessage();
-        return this;
-      }
-
-      /**
-       * <code>optional group FooGroup = 4 { ... }</code>
-       */
-      @java.lang.Override
-      public boolean hasFooGroup() {
-        return instance.hasFooGroup();
-      }
-      /**
-       * <code>optional group FooGroup = 4 { ... }</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup getFooGroup() {
-        return instance.getFooGroup();
-      }
-      /**
-       * <code>optional group FooGroup = 4 { ... }</code>
-       */
-      public Builder setFooGroup(protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup value) {
-        copyOnWrite();
-        instance.setFooGroup(value);
-        return this;
-        }
-      /**
-       * <code>optional group FooGroup = 4 { ... }</code>
-       */
-      public Builder setFooGroup(
-          protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.setFooGroup(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional group FooGroup = 4 { ... }</code>
-       */
-      public Builder mergeFooGroup(protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.FooGroup value) {
-        copyOnWrite();
-        instance.mergeFooGroup(value);
-        return this;
-      }
-      /**
-       * <code>optional group FooGroup = 4 { ... }</code>
-       */
-      public Builder clearFooGroup() {  copyOnWrite();
-        instance.clearFooGroup();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestOneofBackwardsCompatible)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "fooInt_",
-              "fooString_",
-              "fooMessage_",
-              "fooGroup_",
-            };
-            java.lang.String info =
-                "\u0001\u0004\u0000\u0001\u0001\u0004\u0004\u0000\u0000\u0000\u0001\u1004\u0000\u0002" +
-                "\u1008\u0001\u0003\u1009\u0002\u0004\u1011\u0003";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestOneofBackwardsCompatible)
-    private static final protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible DEFAULT_INSTANCE;
-    static {
-      TestOneofBackwardsCompatible defaultInstance = new TestOneofBackwardsCompatible();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestOneofBackwardsCompatible.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestOneofBackwardsCompatible> PARSER;
-
-    public static com.google.protobuf.Parser<TestOneofBackwardsCompatible> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestOneof2OrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestOneof2)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>int32 foo_int = 1;</code>
-     * @return Whether the fooInt field is set.
-     */
-    boolean hasFooInt();
-    /**
-     * <code>int32 foo_int = 1;</code>
-     * @return The fooInt.
-     */
-    int getFooInt();
-
-    /**
-     * <code>string foo_string = 2;</code>
-     * @return Whether the fooString field is set.
-     */
-    boolean hasFooString();
-    /**
-     * <code>string foo_string = 2;</code>
-     * @return The fooString.
-     */
-    java.lang.String getFooString();
-    /**
-     * <code>string foo_string = 2;</code>
-     * @return The bytes for fooString.
-     */
-    com.google.protobuf.ByteString
-        getFooStringBytes();
-
-    /**
-     * <code>string foo_cord = 3 [ctype = CORD];</code>
-     * @return Whether the fooCord field is set.
-     */
-    boolean hasFooCord();
-    /**
-     * <code>string foo_cord = 3 [ctype = CORD];</code>
-     * @return The fooCord.
-     */
-    java.lang.String getFooCord();
-    /**
-     * <code>string foo_cord = 3 [ctype = CORD];</code>
-     * @return The bytes for fooCord.
-     */
-    com.google.protobuf.ByteString
-        getFooCordBytes();
-
-    /**
-     * <code>string foo_string_piece = 4 [ctype = STRING_PIECE];</code>
-     * @return Whether the fooStringPiece field is set.
-     */
-    boolean hasFooStringPiece();
-    /**
-     * <code>string foo_string_piece = 4 [ctype = STRING_PIECE];</code>
-     * @return The fooStringPiece.
-     */
-    java.lang.String getFooStringPiece();
-    /**
-     * <code>string foo_string_piece = 4 [ctype = STRING_PIECE];</code>
-     * @return The bytes for fooStringPiece.
-     */
-    com.google.protobuf.ByteString
-        getFooStringPieceBytes();
-
-    /**
-     * <code>bytes foo_bytes = 5;</code>
-     * @return Whether the fooBytes field is set.
-     */
-    boolean hasFooBytes();
-    /**
-     * <code>bytes foo_bytes = 5;</code>
-     * @return The fooBytes.
-     */
-    com.google.protobuf.ByteString getFooBytes();
-
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-     * @return Whether the fooEnum field is set.
-     */
-    boolean hasFooEnum();
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-     * @return The fooEnum.
-     */
-    protobuf_unittest.UnittestProto.TestOneof2.NestedEnum getFooEnum();
-
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_message = 7;</code>
-     * @return Whether the fooMessage field is set.
-     */
-    boolean hasFooMessage();
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_message = 7;</code>
-     * @return The fooMessage.
-     */
-    protobuf_unittest.UnittestProto.TestOneof2.NestedMessage getFooMessage();
-
-    /**
-     * <code>group FooGroup = 8 { ... }</code>
-     * @return Whether the foogroup field is set.
-     */
-    boolean hasFooGroup();
-    /**
-     * <code>group FooGroup = 8 { ... }</code>
-     * @return The foogroup.
-     */
-    protobuf_unittest.UnittestProto.TestOneof2.FooGroup getFooGroup();
-
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_lazy_message = 11 [lazy = true];</code>
-     * @return Whether the fooLazyMessage field is set.
-     */
-    boolean hasFooLazyMessage();
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_lazy_message = 11 [lazy = true];</code>
-     * @return The fooLazyMessage.
-     */
-    protobuf_unittest.UnittestProto.TestOneof2.NestedMessage getFooLazyMessage();
-
-    /**
-     * <code>int32 bar_int = 12 [default = 5];</code>
-     * @return Whether the barInt field is set.
-     */
-    boolean hasBarInt();
-    /**
-     * <code>int32 bar_int = 12 [default = 5];</code>
-     * @return The barInt.
-     */
-    int getBarInt();
-
-    /**
-     * <code>string bar_string = 13 [default = "STRING"];</code>
-     * @return Whether the barString field is set.
-     */
-    boolean hasBarString();
-    /**
-     * <code>string bar_string = 13 [default = "STRING"];</code>
-     * @return The barString.
-     */
-    java.lang.String getBarString();
-    /**
-     * <code>string bar_string = 13 [default = "STRING"];</code>
-     * @return The bytes for barString.
-     */
-    com.google.protobuf.ByteString
-        getBarStringBytes();
-
-    /**
-     * <code>string bar_cord = 14 [default = "CORD", ctype = CORD];</code>
-     * @return Whether the barCord field is set.
-     */
-    boolean hasBarCord();
-    /**
-     * <code>string bar_cord = 14 [default = "CORD", ctype = CORD];</code>
-     * @return The barCord.
-     */
-    java.lang.String getBarCord();
-    /**
-     * <code>string bar_cord = 14 [default = "CORD", ctype = CORD];</code>
-     * @return The bytes for barCord.
-     */
-    com.google.protobuf.ByteString
-        getBarCordBytes();
-
-    /**
-     * <code>string bar_string_piece = 15 [default = "SPIECE", ctype = STRING_PIECE];</code>
-     * @return Whether the barStringPiece field is set.
-     */
-    boolean hasBarStringPiece();
-    /**
-     * <code>string bar_string_piece = 15 [default = "SPIECE", ctype = STRING_PIECE];</code>
-     * @return The barStringPiece.
-     */
-    java.lang.String getBarStringPiece();
-    /**
-     * <code>string bar_string_piece = 15 [default = "SPIECE", ctype = STRING_PIECE];</code>
-     * @return The bytes for barStringPiece.
-     */
-    com.google.protobuf.ByteString
-        getBarStringPieceBytes();
-
-    /**
-     * <code>bytes bar_bytes = 16 [default = "BYTES"];</code>
-     * @return Whether the barBytes field is set.
-     */
-    boolean hasBarBytes();
-    /**
-     * <code>bytes bar_bytes = 16 [default = "BYTES"];</code>
-     * @return The barBytes.
-     */
-    com.google.protobuf.ByteString getBarBytes();
-
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedEnum bar_enum = 17 [default = BAR];</code>
-     * @return Whether the barEnum field is set.
-     */
-    boolean hasBarEnum();
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedEnum bar_enum = 17 [default = BAR];</code>
-     * @return The barEnum.
-     */
-    protobuf_unittest.UnittestProto.TestOneof2.NestedEnum getBarEnum();
-
-    /**
-     * <code>optional int32 baz_int = 18;</code>
-     * @return Whether the bazInt field is set.
-     */
-    boolean hasBazInt();
-    /**
-     * <code>optional int32 baz_int = 18;</code>
-     * @return The bazInt.
-     */
-    int getBazInt();
-
-    /**
-     * <code>optional string baz_string = 19 [default = "BAZ"];</code>
-     * @return Whether the bazString field is set.
-     */
-    boolean hasBazString();
-    /**
-     * <code>optional string baz_string = 19 [default = "BAZ"];</code>
-     * @return The bazString.
-     */
-    java.lang.String getBazString();
-    /**
-     * <code>optional string baz_string = 19 [default = "BAZ"];</code>
-     * @return The bytes for bazString.
-     */
-    com.google.protobuf.ByteString
-        getBazStringBytes();
-
-    public protobuf_unittest.UnittestProto.TestOneof2.FooCase getFooCase();
-
-    public protobuf_unittest.UnittestProto.TestOneof2.BarCase getBarCase();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestOneof2}
-   */
-  public  static final class TestOneof2 extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestOneof2, TestOneof2.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestOneof2)
-      TestOneof2OrBuilder {
-    private TestOneof2() {
-      bazString_ = "BAZ";
-    }
-    /**
-     * Protobuf enum {@code protobuf_unittest.TestOneof2.NestedEnum}
-     */
-    public enum NestedEnum
-        implements com.google.protobuf.Internal.EnumLite {
-      /**
-       * <code>FOO = 1;</code>
-       */
-      FOO(1),
-      /**
-       * <code>BAR = 2;</code>
-       */
-      BAR(2),
-      /**
-       * <code>BAZ = 3;</code>
-       */
-      BAZ(3),
-      ;
-
-      /**
-       * <code>FOO = 1;</code>
-       */
-      public static final int FOO_VALUE = 1;
-      /**
-       * <code>BAR = 2;</code>
-       */
-      public static final int BAR_VALUE = 2;
-      /**
-       * <code>BAZ = 3;</code>
-       */
-      public static final int BAZ_VALUE = 3;
-
-
-      @java.lang.Override
-      public final int getNumber() {
-        return value;
-      }
-
-      /**
-       * @param value The number of the enum to look for.
-       * @return The enum associated with the given number.
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static NestedEnum valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static NestedEnum forNumber(int value) {
-        switch (value) {
-          case 1: return FOO;
-          case 2: return BAR;
-          case 3: return BAZ;
-          default: return null;
-        }
-      }
-
-      public static com.google.protobuf.Internal.EnumLiteMap<NestedEnum>
-          internalGetValueMap() {
-        return internalValueMap;
-      }
-      private static final com.google.protobuf.Internal.EnumLiteMap<
-          NestedEnum> internalValueMap =
-            new com.google.protobuf.Internal.EnumLiteMap<NestedEnum>() {
-              @java.lang.Override
-              public NestedEnum findValueByNumber(int number) {
-                return NestedEnum.forNumber(number);
-              }
-            };
-
-      public static com.google.protobuf.Internal.EnumVerifier 
-          internalGetVerifier() {
-        return NestedEnumVerifier.INSTANCE;
-      }
-
-      private static final class NestedEnumVerifier implements 
-           com.google.protobuf.Internal.EnumVerifier { 
-              static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new NestedEnumVerifier();
-              @java.lang.Override
-              public boolean isInRange(int number) {
-                return NestedEnum.forNumber(number) != null;
-              }
-            };
-
-      private final int value;
-
-      private NestedEnum(int value) {
-        this.value = value;
-      }
-
-      // @@protoc_insertion_point(enum_scope:protobuf_unittest.TestOneof2.NestedEnum)
-    }
-
-    public interface FooGroupOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestOneof2.FooGroup)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int32 a = 9;</code>
-       * @return Whether the a field is set.
-       */
-      boolean hasA();
-      /**
-       * <code>optional int32 a = 9;</code>
-       * @return The a.
-       */
-      int getA();
-
-      /**
-       * <code>optional string b = 10;</code>
-       * @return Whether the b field is set.
-       */
-      boolean hasB();
-      /**
-       * <code>optional string b = 10;</code>
-       * @return The b.
-       */
-      java.lang.String getB();
-      /**
-       * <code>optional string b = 10;</code>
-       * @return The bytes for b.
-       */
-      com.google.protobuf.ByteString
-          getBBytes();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestOneof2.FooGroup}
-     */
-    public  static final class FooGroup extends
-        com.google.protobuf.GeneratedMessageLite<
-            FooGroup, FooGroup.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestOneof2.FooGroup)
-        FooGroupOrBuilder {
-      private FooGroup() {
-        b_ = "";
-      }
-      private int bitField0_;
-      public static final int A_FIELD_NUMBER = 9;
-      private int a_;
-      /**
-       * <code>optional int32 a = 9;</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int32 a = 9;</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public int getA() {
-        return a_;
-      }
-      /**
-       * <code>optional int32 a = 9;</code>
-       * @param value The a to set.
-       */
-      private void setA(int value) {
-        bitField0_ |= 0x00000001;
-        a_ = value;
-      }
-      /**
-       * <code>optional int32 a = 9;</code>
-       */
-      private void clearA() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        a_ = 0;
-      }
-
-      public static final int B_FIELD_NUMBER = 10;
-      private java.lang.String b_;
-      /**
-       * <code>optional string b = 10;</code>
-       * @return Whether the b field is set.
-       */
-      @java.lang.Override
-      public boolean hasB() {
-        return ((bitField0_ & 0x00000002) != 0);
-      }
-      /**
-       * <code>optional string b = 10;</code>
-       * @return The b.
-       */
-      @java.lang.Override
-      public java.lang.String getB() {
-        return b_;
-      }
-      /**
-       * <code>optional string b = 10;</code>
-       * @return The bytes for b.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getBBytes() {
-        return com.google.protobuf.ByteString.copyFromUtf8(b_);
-      }
-      /**
-       * <code>optional string b = 10;</code>
-       * @param value The b to set.
-       */
-      private void setB(
-          java.lang.String value) {
-        value.getClass();
-  bitField0_ |= 0x00000002;
-        b_ = value;
-      }
-      /**
-       * <code>optional string b = 10;</code>
-       */
-      private void clearB() {
-        bitField0_ = (bitField0_ & ~0x00000002);
-        b_ = getDefaultInstance().getB();
-      }
-      /**
-       * <code>optional string b = 10;</code>
-       * @param value The bytes for b to set.
-       */
-      private void setBBytes(
-          com.google.protobuf.ByteString value) {
-        b_ = value.toStringUtf8();
-        bitField0_ |= 0x00000002;
-      }
-
-      public static protobuf_unittest.UnittestProto.TestOneof2.FooGroup parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.FooGroup parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.FooGroup parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.FooGroup parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.FooGroup parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.FooGroup parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.FooGroup parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.FooGroup parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.FooGroup parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.FooGroup parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.FooGroup parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.FooGroup parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestOneof2.FooGroup prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestOneof2.FooGroup}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestOneof2.FooGroup, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestOneof2.FooGroup)
-          protobuf_unittest.UnittestProto.TestOneof2.FooGroupOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestOneof2.FooGroup.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int32 a = 9;</code>
-         * @return Whether the a field is set.
-         */
-        @java.lang.Override
-        public boolean hasA() {
-          return instance.hasA();
-        }
-        /**
-         * <code>optional int32 a = 9;</code>
-         * @return The a.
-         */
-        @java.lang.Override
-        public int getA() {
-          return instance.getA();
-        }
-        /**
-         * <code>optional int32 a = 9;</code>
-         * @param value The a to set.
-         * @return This builder for chaining.
-         */
-        public Builder setA(int value) {
-          copyOnWrite();
-          instance.setA(value);
-          return this;
-        }
-        /**
-         * <code>optional int32 a = 9;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearA() {
-          copyOnWrite();
-          instance.clearA();
-          return this;
-        }
-
-        /**
-         * <code>optional string b = 10;</code>
-         * @return Whether the b field is set.
-         */
-        @java.lang.Override
-        public boolean hasB() {
-          return instance.hasB();
-        }
-        /**
-         * <code>optional string b = 10;</code>
-         * @return The b.
-         */
-        @java.lang.Override
-        public java.lang.String getB() {
-          return instance.getB();
-        }
-        /**
-         * <code>optional string b = 10;</code>
-         * @return The bytes for b.
-         */
-        @java.lang.Override
-        public com.google.protobuf.ByteString
-            getBBytes() {
-          return instance.getBBytes();
-        }
-        /**
-         * <code>optional string b = 10;</code>
-         * @param value The b to set.
-         * @return This builder for chaining.
-         */
-        public Builder setB(
-            java.lang.String value) {
-          copyOnWrite();
-          instance.setB(value);
-          return this;
-        }
-        /**
-         * <code>optional string b = 10;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearB() {
-          copyOnWrite();
-          instance.clearB();
-          return this;
-        }
-        /**
-         * <code>optional string b = 10;</code>
-         * @param value The bytes for b to set.
-         * @return This builder for chaining.
-         */
-        public Builder setBBytes(
-            com.google.protobuf.ByteString value) {
-          copyOnWrite();
-          instance.setBBytes(value);
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestOneof2.FooGroup)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestOneof2.FooGroup();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "a_",
-                "b_",
-              };
-              java.lang.String info =
-                  "\u0001\u0002\u0000\u0001\t\n\u0002\u0000\u0000\u0000\t\u1004\u0000\n\u1008\u0001" +
-                  "";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestOneof2.FooGroup> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestOneof2.FooGroup.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestOneof2.FooGroup>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestOneof2.FooGroup)
-      private static final protobuf_unittest.UnittestProto.TestOneof2.FooGroup DEFAULT_INSTANCE;
-      static {
-        FooGroup defaultInstance = new FooGroup();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          FooGroup.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestOneof2.FooGroup getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<FooGroup> PARSER;
-
-      public static com.google.protobuf.Parser<FooGroup> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    public interface NestedMessageOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestOneof2.NestedMessage)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int64 qux_int = 1;</code>
-       * @return Whether the quxInt field is set.
-       */
-      boolean hasQuxInt();
-      /**
-       * <code>optional int64 qux_int = 1;</code>
-       * @return The quxInt.
-       */
-      long getQuxInt();
-
-      /**
-       * <code>repeated int32 corge_int = 2;</code>
-       * @return A list containing the corgeInt.
-       */
-      java.util.List<java.lang.Integer> getCorgeIntList();
-      /**
-       * <code>repeated int32 corge_int = 2;</code>
-       * @return The count of corgeInt.
-       */
-      int getCorgeIntCount();
-      /**
-       * <code>repeated int32 corge_int = 2;</code>
-       * @param index The index of the element to return.
-       * @return The corgeInt at the given index.
-       */
-      int getCorgeInt(int index);
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestOneof2.NestedMessage}
-     */
-    public  static final class NestedMessage extends
-        com.google.protobuf.GeneratedMessageLite<
-            NestedMessage, NestedMessage.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestOneof2.NestedMessage)
-        NestedMessageOrBuilder {
-      private NestedMessage() {
-        corgeInt_ = emptyIntList();
-      }
-      private int bitField0_;
-      public static final int QUX_INT_FIELD_NUMBER = 1;
-      private long quxInt_;
-      /**
-       * <code>optional int64 qux_int = 1;</code>
-       * @return Whether the quxInt field is set.
-       */
-      @java.lang.Override
-      public boolean hasQuxInt() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int64 qux_int = 1;</code>
-       * @return The quxInt.
-       */
-      @java.lang.Override
-      public long getQuxInt() {
-        return quxInt_;
-      }
-      /**
-       * <code>optional int64 qux_int = 1;</code>
-       * @param value The quxInt to set.
-       */
-      private void setQuxInt(long value) {
-        bitField0_ |= 0x00000001;
-        quxInt_ = value;
-      }
-      /**
-       * <code>optional int64 qux_int = 1;</code>
-       */
-      private void clearQuxInt() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        quxInt_ = 0L;
-      }
-
-      public static final int CORGE_INT_FIELD_NUMBER = 2;
-      private com.google.protobuf.Internal.IntList corgeInt_;
-      /**
-       * <code>repeated int32 corge_int = 2;</code>
-       * @return A list containing the corgeInt.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getCorgeIntList() {
-        return corgeInt_;
-      }
-      /**
-       * <code>repeated int32 corge_int = 2;</code>
-       * @return The count of corgeInt.
-       */
-      @java.lang.Override
-      public int getCorgeIntCount() {
-        return corgeInt_.size();
-      }
-      /**
-       * <code>repeated int32 corge_int = 2;</code>
-       * @param index The index of the element to return.
-       * @return The corgeInt at the given index.
-       */
-      @java.lang.Override
-      public int getCorgeInt(int index) {
-        return corgeInt_.getInt(index);
-      }
-      private void ensureCorgeIntIsMutable() {
-        com.google.protobuf.Internal.IntList tmp = corgeInt_;
-        if (!tmp.isModifiable()) {
-          corgeInt_ =
-              com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-         }
-      }
-      /**
-       * <code>repeated int32 corge_int = 2;</code>
-       * @param index The index to set the value at.
-       * @param value The corgeInt to set.
-       */
-      private void setCorgeInt(
-          int index, int value) {
-        ensureCorgeIntIsMutable();
-        corgeInt_.setInt(index, value);
-      }
-      /**
-       * <code>repeated int32 corge_int = 2;</code>
-       * @param value The corgeInt to add.
-       */
-      private void addCorgeInt(int value) {
-        ensureCorgeIntIsMutable();
-        corgeInt_.addInt(value);
-      }
-      /**
-       * <code>repeated int32 corge_int = 2;</code>
-       * @param values The corgeInt to add.
-       */
-      private void addAllCorgeInt(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        ensureCorgeIntIsMutable();
-        com.google.protobuf.AbstractMessageLite.addAll(
-            values, corgeInt_);
-      }
-      /**
-       * <code>repeated int32 corge_int = 2;</code>
-       */
-      private void clearCorgeInt() {
-        corgeInt_ = emptyIntList();
-      }
-
-      public static protobuf_unittest.UnittestProto.TestOneof2.NestedMessage parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.NestedMessage parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.NestedMessage parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.NestedMessage parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.NestedMessage parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.NestedMessage parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.NestedMessage parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.NestedMessage parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestOneof2.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestOneof2.NestedMessage prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestOneof2.NestedMessage}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestOneof2.NestedMessage, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestOneof2.NestedMessage)
-          protobuf_unittest.UnittestProto.TestOneof2.NestedMessageOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestOneof2.NestedMessage.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int64 qux_int = 1;</code>
-         * @return Whether the quxInt field is set.
-         */
-        @java.lang.Override
-        public boolean hasQuxInt() {
-          return instance.hasQuxInt();
-        }
-        /**
-         * <code>optional int64 qux_int = 1;</code>
-         * @return The quxInt.
-         */
-        @java.lang.Override
-        public long getQuxInt() {
-          return instance.getQuxInt();
-        }
-        /**
-         * <code>optional int64 qux_int = 1;</code>
-         * @param value The quxInt to set.
-         * @return This builder for chaining.
-         */
-        public Builder setQuxInt(long value) {
-          copyOnWrite();
-          instance.setQuxInt(value);
-          return this;
-        }
-        /**
-         * <code>optional int64 qux_int = 1;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearQuxInt() {
-          copyOnWrite();
-          instance.clearQuxInt();
-          return this;
-        }
-
-        /**
-         * <code>repeated int32 corge_int = 2;</code>
-         * @return A list containing the corgeInt.
-         */
-        @java.lang.Override
-        public java.util.List<java.lang.Integer>
-            getCorgeIntList() {
-          return java.util.Collections.unmodifiableList(
-              instance.getCorgeIntList());
-        }
-        /**
-         * <code>repeated int32 corge_int = 2;</code>
-         * @return The count of corgeInt.
-         */
-        @java.lang.Override
-        public int getCorgeIntCount() {
-          return instance.getCorgeIntCount();
-        }
-        /**
-         * <code>repeated int32 corge_int = 2;</code>
-         * @param index The index of the element to return.
-         * @return The corgeInt at the given index.
-         */
-        @java.lang.Override
-        public int getCorgeInt(int index) {
-          return instance.getCorgeInt(index);
-        }
-        /**
-         * <code>repeated int32 corge_int = 2;</code>
-         * @param value The corgeInt to set.
-         * @return This builder for chaining.
-         */
-        public Builder setCorgeInt(
-            int index, int value) {
-          copyOnWrite();
-          instance.setCorgeInt(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated int32 corge_int = 2;</code>
-         * @param value The corgeInt to add.
-         * @return This builder for chaining.
-         */
-        public Builder addCorgeInt(int value) {
-          copyOnWrite();
-          instance.addCorgeInt(value);
-          return this;
-        }
-        /**
-         * <code>repeated int32 corge_int = 2;</code>
-         * @param values The corgeInt to add.
-         * @return This builder for chaining.
-         */
-        public Builder addAllCorgeInt(
-            java.lang.Iterable<? extends java.lang.Integer> values) {
-          copyOnWrite();
-          instance.addAllCorgeInt(values);
-          return this;
-        }
-        /**
-         * <code>repeated int32 corge_int = 2;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearCorgeInt() {
-          copyOnWrite();
-          instance.clearCorgeInt();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestOneof2.NestedMessage)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestOneof2.NestedMessage();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "quxInt_",
-                "corgeInt_",
-              };
-              java.lang.String info =
-                  "\u0001\u0002\u0000\u0001\u0001\u0002\u0002\u0000\u0001\u0000\u0001\u1002\u0000\u0002" +
-                  "\u0016";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestOneof2.NestedMessage> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestOneof2.NestedMessage.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestOneof2.NestedMessage>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestOneof2.NestedMessage)
-      private static final protobuf_unittest.UnittestProto.TestOneof2.NestedMessage DEFAULT_INSTANCE;
-      static {
-        NestedMessage defaultInstance = new NestedMessage();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          NestedMessage.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestOneof2.NestedMessage getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<NestedMessage> PARSER;
-
-      public static com.google.protobuf.Parser<NestedMessage> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int bitField0_;
-    private int fooCase_ = 0;
-    private java.lang.Object foo_;
-    public enum FooCase {
-      FOO_INT(1),
-      FOO_STRING(2),
-      FOO_CORD(3),
-      FOO_STRING_PIECE(4),
-      FOO_BYTES(5),
-      FOO_ENUM(6),
-      FOO_MESSAGE(7),
-      FOOGROUP(8),
-      FOO_LAZY_MESSAGE(11),
-      FOO_NOT_SET(0);
-      private final int value;
-      private FooCase(int value) {
-        this.value = value;
-      }
-      /**
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static FooCase valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static FooCase forNumber(int value) {
-        switch (value) {
-          case 1: return FOO_INT;
-          case 2: return FOO_STRING;
-          case 3: return FOO_CORD;
-          case 4: return FOO_STRING_PIECE;
-          case 5: return FOO_BYTES;
-          case 6: return FOO_ENUM;
-          case 7: return FOO_MESSAGE;
-          case 8: return FOOGROUP;
-          case 11: return FOO_LAZY_MESSAGE;
-          case 0: return FOO_NOT_SET;
-          default: return null;
-        }
-      }
-      public int getNumber() {
-        return this.value;
-      }
-    };
-
-    @java.lang.Override
-    public FooCase
-    getFooCase() {
-      return FooCase.forNumber(
-          fooCase_);
-    }
-
-    private void clearFoo() {
-      fooCase_ = 0;
-      foo_ = null;
-    }
-
-    private int barCase_ = 0;
-    private java.lang.Object bar_;
-    public enum BarCase {
-      BAR_INT(12),
-      BAR_STRING(13),
-      BAR_CORD(14),
-      BAR_STRING_PIECE(15),
-      BAR_BYTES(16),
-      BAR_ENUM(17),
-      BAR_NOT_SET(0);
-      private final int value;
-      private BarCase(int value) {
-        this.value = value;
-      }
-      /**
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static BarCase valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static BarCase forNumber(int value) {
-        switch (value) {
-          case 12: return BAR_INT;
-          case 13: return BAR_STRING;
-          case 14: return BAR_CORD;
-          case 15: return BAR_STRING_PIECE;
-          case 16: return BAR_BYTES;
-          case 17: return BAR_ENUM;
-          case 0: return BAR_NOT_SET;
-          default: return null;
-        }
-      }
-      public int getNumber() {
-        return this.value;
-      }
-    };
-
-    @java.lang.Override
-    public BarCase
-    getBarCase() {
-      return BarCase.forNumber(
-          barCase_);
-    }
-
-    private void clearBar() {
-      barCase_ = 0;
-      bar_ = null;
-    }
-
-    public static final int FOO_INT_FIELD_NUMBER = 1;
-    /**
-     * <code>int32 foo_int = 1;</code>
-     * @return Whether the fooInt field is set.
-     */
-    @java.lang.Override
-    public boolean hasFooInt() {
-      return fooCase_ == 1;
-    }
-    /**
-     * <code>int32 foo_int = 1;</code>
-     * @return The fooInt.
-     */
-    @java.lang.Override
-    public int getFooInt() {
-      if (fooCase_ == 1) {
-        return (java.lang.Integer) foo_;
-      }
-      return 0;
-    }
-    /**
-     * <code>int32 foo_int = 1;</code>
-     * @param value The fooInt to set.
-     */
-    private void setFooInt(int value) {
-      fooCase_ = 1;
-      foo_ = value;
-    }
-    /**
-     * <code>int32 foo_int = 1;</code>
-     */
-    private void clearFooInt() {
-      if (fooCase_ == 1) {
-        fooCase_ = 0;
-        foo_ = null;
-      }
-    }
-
-    public static final int FOO_STRING_FIELD_NUMBER = 2;
-    /**
-     * <code>string foo_string = 2;</code>
-     * @return Whether the fooString field is set.
-     */
-    @java.lang.Override
-    public boolean hasFooString() {
-      return fooCase_ == 2;
-    }
-    /**
-     * <code>string foo_string = 2;</code>
-     * @return The fooString.
-     */
-    @java.lang.Override
-    public java.lang.String getFooString() {
-      java.lang.String ref = "";
-      if (fooCase_ == 2) {
-        ref = (java.lang.String) foo_;
-      }
-      return ref;
-    }
-    /**
-     * <code>string foo_string = 2;</code>
-     * @return The bytes for fooString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getFooStringBytes() {
-      java.lang.String ref = "";
-      if (fooCase_ == 2) {
-        ref = (java.lang.String) foo_;
-      }
-      return com.google.protobuf.ByteString.copyFromUtf8(ref);
-    }
-    /**
-     * <code>string foo_string = 2;</code>
-     * @param value The fooString to set.
-     */
-    private void setFooString(
-        java.lang.String value) {
-      value.getClass();
-  fooCase_ = 2;
-      foo_ = value;
-    }
-    /**
-     * <code>string foo_string = 2;</code>
-     */
-    private void clearFooString() {
-      if (fooCase_ == 2) {
-        fooCase_ = 0;
-        foo_ = null;
-      }
-    }
-    /**
-     * <code>string foo_string = 2;</code>
-     * @param value The bytes for fooString to set.
-     */
-    private void setFooStringBytes(
-        com.google.protobuf.ByteString value) {
-      foo_ = value.toStringUtf8();
-      fooCase_ = 2;
-    }
-
-    public static final int FOO_CORD_FIELD_NUMBER = 3;
-    /**
-     * <code>string foo_cord = 3 [ctype = CORD];</code>
-     * @return Whether the fooCord field is set.
-     */
-    @java.lang.Override
-    public boolean hasFooCord() {
-      return fooCase_ == 3;
-    }
-    /**
-     * <code>string foo_cord = 3 [ctype = CORD];</code>
-     * @return The fooCord.
-     */
-    @java.lang.Override
-    public java.lang.String getFooCord() {
-      java.lang.String ref = "";
-      if (fooCase_ == 3) {
-        ref = (java.lang.String) foo_;
-      }
-      return ref;
-    }
-    /**
-     * <code>string foo_cord = 3 [ctype = CORD];</code>
-     * @return The bytes for fooCord.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getFooCordBytes() {
-      java.lang.String ref = "";
-      if (fooCase_ == 3) {
-        ref = (java.lang.String) foo_;
-      }
-      return com.google.protobuf.ByteString.copyFromUtf8(ref);
-    }
-    /**
-     * <code>string foo_cord = 3 [ctype = CORD];</code>
-     * @param value The fooCord to set.
-     */
-    private void setFooCord(
-        java.lang.String value) {
-      value.getClass();
-  fooCase_ = 3;
-      foo_ = value;
-    }
-    /**
-     * <code>string foo_cord = 3 [ctype = CORD];</code>
-     */
-    private void clearFooCord() {
-      if (fooCase_ == 3) {
-        fooCase_ = 0;
-        foo_ = null;
-      }
-    }
-    /**
-     * <code>string foo_cord = 3 [ctype = CORD];</code>
-     * @param value The bytes for fooCord to set.
-     */
-    private void setFooCordBytes(
-        com.google.protobuf.ByteString value) {
-      foo_ = value.toStringUtf8();
-      fooCase_ = 3;
-    }
-
-    public static final int FOO_STRING_PIECE_FIELD_NUMBER = 4;
-    /**
-     * <code>string foo_string_piece = 4 [ctype = STRING_PIECE];</code>
-     * @return Whether the fooStringPiece field is set.
-     */
-    @java.lang.Override
-    public boolean hasFooStringPiece() {
-      return fooCase_ == 4;
-    }
-    /**
-     * <code>string foo_string_piece = 4 [ctype = STRING_PIECE];</code>
-     * @return The fooStringPiece.
-     */
-    @java.lang.Override
-    public java.lang.String getFooStringPiece() {
-      java.lang.String ref = "";
-      if (fooCase_ == 4) {
-        ref = (java.lang.String) foo_;
-      }
-      return ref;
-    }
-    /**
-     * <code>string foo_string_piece = 4 [ctype = STRING_PIECE];</code>
-     * @return The bytes for fooStringPiece.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getFooStringPieceBytes() {
-      java.lang.String ref = "";
-      if (fooCase_ == 4) {
-        ref = (java.lang.String) foo_;
-      }
-      return com.google.protobuf.ByteString.copyFromUtf8(ref);
-    }
-    /**
-     * <code>string foo_string_piece = 4 [ctype = STRING_PIECE];</code>
-     * @param value The fooStringPiece to set.
-     */
-    private void setFooStringPiece(
-        java.lang.String value) {
-      value.getClass();
-  fooCase_ = 4;
-      foo_ = value;
-    }
-    /**
-     * <code>string foo_string_piece = 4 [ctype = STRING_PIECE];</code>
-     */
-    private void clearFooStringPiece() {
-      if (fooCase_ == 4) {
-        fooCase_ = 0;
-        foo_ = null;
-      }
-    }
-    /**
-     * <code>string foo_string_piece = 4 [ctype = STRING_PIECE];</code>
-     * @param value The bytes for fooStringPiece to set.
-     */
-    private void setFooStringPieceBytes(
-        com.google.protobuf.ByteString value) {
-      foo_ = value.toStringUtf8();
-      fooCase_ = 4;
-    }
-
-    public static final int FOO_BYTES_FIELD_NUMBER = 5;
-    /**
-     * <code>bytes foo_bytes = 5;</code>
-     * @return Whether the fooBytes field is set.
-     */
-    @java.lang.Override
-    public boolean hasFooBytes() {
-      return fooCase_ == 5;
-    }
-    /**
-     * <code>bytes foo_bytes = 5;</code>
-     * @return The fooBytes.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getFooBytes() {
-      if (fooCase_ == 5) {
-        return (com.google.protobuf.ByteString) foo_;
-      }
-      return com.google.protobuf.ByteString.EMPTY;
-    }
-    /**
-     * <code>bytes foo_bytes = 5;</code>
-     * @param value The fooBytes to set.
-     */
-    private void setFooBytes(com.google.protobuf.ByteString value) {
-      value.getClass();
-  fooCase_ = 5;
-      foo_ = value;
-    }
-    /**
-     * <code>bytes foo_bytes = 5;</code>
-     */
-    private void clearFooBytes() {
-      if (fooCase_ == 5) {
-        fooCase_ = 0;
-        foo_ = null;
-      }
-    }
-
-    public static final int FOO_ENUM_FIELD_NUMBER = 6;
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-     * @return Whether the fooEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasFooEnum() {
-      return fooCase_ == 6;
-    }
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-     * @return The fooEnum.
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestOneof2.NestedEnum getFooEnum() {
-      if (fooCase_ == 6) {
-        protobuf_unittest.UnittestProto.TestOneof2.NestedEnum result = protobuf_unittest.UnittestProto.TestOneof2.NestedEnum.forNumber((java.lang.Integer) foo_);
-        return result == null ? protobuf_unittest.UnittestProto.TestOneof2.NestedEnum.FOO : result;
-      }
-      return protobuf_unittest.UnittestProto.TestOneof2.NestedEnum.FOO;
-    }
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-     * @param value The fooEnum to set.
-     */
-    private void setFooEnum(protobuf_unittest.UnittestProto.TestOneof2.NestedEnum value) {
-      foo_ = value.getNumber();
-      fooCase_ = 6;
-    }
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-     */
-    private void clearFooEnum() {
-      if (fooCase_ == 6) {
-        fooCase_ = 0;
-        foo_ = null;
-      }
-    }
-
-    public static final int FOO_MESSAGE_FIELD_NUMBER = 7;
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_message = 7;</code>
-     */
-    @java.lang.Override
-    public boolean hasFooMessage() {
-      return fooCase_ == 7;
-    }
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_message = 7;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestOneof2.NestedMessage getFooMessage() {
-      if (fooCase_ == 7) {
-         return (protobuf_unittest.UnittestProto.TestOneof2.NestedMessage) foo_;
-      }
-      return protobuf_unittest.UnittestProto.TestOneof2.NestedMessage.getDefaultInstance();
-    }
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_message = 7;</code>
-     */
-    private void setFooMessage(protobuf_unittest.UnittestProto.TestOneof2.NestedMessage value) {
-      value.getClass();
-  foo_ = value;
-      fooCase_ = 7;
-    }
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_message = 7;</code>
-     */
-    private void mergeFooMessage(protobuf_unittest.UnittestProto.TestOneof2.NestedMessage value) {
-      value.getClass();
-  if (fooCase_ == 7 &&
-          foo_ != protobuf_unittest.UnittestProto.TestOneof2.NestedMessage.getDefaultInstance()) {
-        foo_ = protobuf_unittest.UnittestProto.TestOneof2.NestedMessage.newBuilder((protobuf_unittest.UnittestProto.TestOneof2.NestedMessage) foo_)
-            .mergeFrom(value).buildPartial();
-      } else {
-        foo_ = value;
-      }
-      fooCase_ = 7;
-    }
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_message = 7;</code>
-     */
-    private void clearFooMessage() {
-      if (fooCase_ == 7) {
-        fooCase_ = 0;
-        foo_ = null;
-      }
-    }
-
-    public static final int FOOGROUP_FIELD_NUMBER = 8;
-    /**
-     * <code>group FooGroup = 8 { ... }</code>
-     */
-    @java.lang.Override
-    public boolean hasFooGroup() {
-      return fooCase_ == 8;
-    }
-    /**
-     * <code>group FooGroup = 8 { ... }</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestOneof2.FooGroup getFooGroup() {
-      if (fooCase_ == 8) {
-         return (protobuf_unittest.UnittestProto.TestOneof2.FooGroup) foo_;
-      }
-      return protobuf_unittest.UnittestProto.TestOneof2.FooGroup.getDefaultInstance();
-    }
-    /**
-     * <code>group FooGroup = 8 { ... }</code>
-     */
-    private void setFooGroup(protobuf_unittest.UnittestProto.TestOneof2.FooGroup value) {
-      value.getClass();
-  foo_ = value;
-      fooCase_ = 8;
-    }
-    /**
-     * <code>group FooGroup = 8 { ... }</code>
-     */
-    private void mergeFooGroup(protobuf_unittest.UnittestProto.TestOneof2.FooGroup value) {
-      value.getClass();
-  if (fooCase_ == 8 &&
-          foo_ != protobuf_unittest.UnittestProto.TestOneof2.FooGroup.getDefaultInstance()) {
-        foo_ = protobuf_unittest.UnittestProto.TestOneof2.FooGroup.newBuilder((protobuf_unittest.UnittestProto.TestOneof2.FooGroup) foo_)
-            .mergeFrom(value).buildPartial();
-      } else {
-        foo_ = value;
-      }
-      fooCase_ = 8;
-    }
-    /**
-     * <code>group FooGroup = 8 { ... }</code>
-     */
-    private void clearFooGroup() {
-      if (fooCase_ == 8) {
-        fooCase_ = 0;
-        foo_ = null;
-      }
-    }
-
-    public static final int FOO_LAZY_MESSAGE_FIELD_NUMBER = 11;
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_lazy_message = 11 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public boolean hasFooLazyMessage() {
-      return fooCase_ == 11;
-    }
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_lazy_message = 11 [lazy = true];</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestOneof2.NestedMessage getFooLazyMessage() {
-      if (fooCase_ == 11) {
-         return (protobuf_unittest.UnittestProto.TestOneof2.NestedMessage) foo_;
-      }
-      return protobuf_unittest.UnittestProto.TestOneof2.NestedMessage.getDefaultInstance();
-    }
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_lazy_message = 11 [lazy = true];</code>
-     */
-    private void setFooLazyMessage(protobuf_unittest.UnittestProto.TestOneof2.NestedMessage value) {
-      value.getClass();
-  foo_ = value;
-      fooCase_ = 11;
-    }
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_lazy_message = 11 [lazy = true];</code>
-     */
-    private void mergeFooLazyMessage(protobuf_unittest.UnittestProto.TestOneof2.NestedMessage value) {
-      value.getClass();
-  if (fooCase_ == 11 &&
-          foo_ != protobuf_unittest.UnittestProto.TestOneof2.NestedMessage.getDefaultInstance()) {
-        foo_ = protobuf_unittest.UnittestProto.TestOneof2.NestedMessage.newBuilder((protobuf_unittest.UnittestProto.TestOneof2.NestedMessage) foo_)
-            .mergeFrom(value).buildPartial();
-      } else {
-        foo_ = value;
-      }
-      fooCase_ = 11;
-    }
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_lazy_message = 11 [lazy = true];</code>
-     */
-    private void clearFooLazyMessage() {
-      if (fooCase_ == 11) {
-        fooCase_ = 0;
-        foo_ = null;
-      }
-    }
-
-    public static final int BAR_INT_FIELD_NUMBER = 12;
-    /**
-     * <code>int32 bar_int = 12 [default = 5];</code>
-     * @return Whether the barInt field is set.
-     */
-    @java.lang.Override
-    public boolean hasBarInt() {
-      return barCase_ == 12;
-    }
-    /**
-     * <code>int32 bar_int = 12 [default = 5];</code>
-     * @return The barInt.
-     */
-    @java.lang.Override
-    public int getBarInt() {
-      if (barCase_ == 12) {
-        return (java.lang.Integer) bar_;
-      }
-      return 5;
-    }
-    /**
-     * <code>int32 bar_int = 12 [default = 5];</code>
-     * @param value The barInt to set.
-     */
-    private void setBarInt(int value) {
-      barCase_ = 12;
-      bar_ = value;
-    }
-    /**
-     * <code>int32 bar_int = 12 [default = 5];</code>
-     */
-    private void clearBarInt() {
-      if (barCase_ == 12) {
-        barCase_ = 0;
-        bar_ = null;
-      }
-    }
-
-    public static final int BAR_STRING_FIELD_NUMBER = 13;
-    /**
-     * <code>string bar_string = 13 [default = "STRING"];</code>
-     * @return Whether the barString field is set.
-     */
-    @java.lang.Override
-    public boolean hasBarString() {
-      return barCase_ == 13;
-    }
-    /**
-     * <code>string bar_string = 13 [default = "STRING"];</code>
-     * @return The barString.
-     */
-    @java.lang.Override
-    public java.lang.String getBarString() {
-      java.lang.String ref = "STRING";
-      if (barCase_ == 13) {
-        ref = (java.lang.String) bar_;
-      }
-      return ref;
-    }
-    /**
-     * <code>string bar_string = 13 [default = "STRING"];</code>
-     * @return The bytes for barString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getBarStringBytes() {
-      java.lang.String ref = "STRING";
-      if (barCase_ == 13) {
-        ref = (java.lang.String) bar_;
-      }
-      return com.google.protobuf.ByteString.copyFromUtf8(ref);
-    }
-    /**
-     * <code>string bar_string = 13 [default = "STRING"];</code>
-     * @param value The barString to set.
-     */
-    private void setBarString(
-        java.lang.String value) {
-      value.getClass();
-  barCase_ = 13;
-      bar_ = value;
-    }
-    /**
-     * <code>string bar_string = 13 [default = "STRING"];</code>
-     */
-    private void clearBarString() {
-      if (barCase_ == 13) {
-        barCase_ = 0;
-        bar_ = null;
-      }
-    }
-    /**
-     * <code>string bar_string = 13 [default = "STRING"];</code>
-     * @param value The bytes for barString to set.
-     */
-    private void setBarStringBytes(
-        com.google.protobuf.ByteString value) {
-      bar_ = value.toStringUtf8();
-      barCase_ = 13;
-    }
-
-    public static final int BAR_CORD_FIELD_NUMBER = 14;
-    /**
-     * <code>string bar_cord = 14 [default = "CORD", ctype = CORD];</code>
-     * @return Whether the barCord field is set.
-     */
-    @java.lang.Override
-    public boolean hasBarCord() {
-      return barCase_ == 14;
-    }
-    /**
-     * <code>string bar_cord = 14 [default = "CORD", ctype = CORD];</code>
-     * @return The barCord.
-     */
-    @java.lang.Override
-    public java.lang.String getBarCord() {
-      java.lang.String ref = "CORD";
-      if (barCase_ == 14) {
-        ref = (java.lang.String) bar_;
-      }
-      return ref;
-    }
-    /**
-     * <code>string bar_cord = 14 [default = "CORD", ctype = CORD];</code>
-     * @return The bytes for barCord.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getBarCordBytes() {
-      java.lang.String ref = "CORD";
-      if (barCase_ == 14) {
-        ref = (java.lang.String) bar_;
-      }
-      return com.google.protobuf.ByteString.copyFromUtf8(ref);
-    }
-    /**
-     * <code>string bar_cord = 14 [default = "CORD", ctype = CORD];</code>
-     * @param value The barCord to set.
-     */
-    private void setBarCord(
-        java.lang.String value) {
-      value.getClass();
-  barCase_ = 14;
-      bar_ = value;
-    }
-    /**
-     * <code>string bar_cord = 14 [default = "CORD", ctype = CORD];</code>
-     */
-    private void clearBarCord() {
-      if (barCase_ == 14) {
-        barCase_ = 0;
-        bar_ = null;
-      }
-    }
-    /**
-     * <code>string bar_cord = 14 [default = "CORD", ctype = CORD];</code>
-     * @param value The bytes for barCord to set.
-     */
-    private void setBarCordBytes(
-        com.google.protobuf.ByteString value) {
-      bar_ = value.toStringUtf8();
-      barCase_ = 14;
-    }
-
-    public static final int BAR_STRING_PIECE_FIELD_NUMBER = 15;
-    /**
-     * <code>string bar_string_piece = 15 [default = "SPIECE", ctype = STRING_PIECE];</code>
-     * @return Whether the barStringPiece field is set.
-     */
-    @java.lang.Override
-    public boolean hasBarStringPiece() {
-      return barCase_ == 15;
-    }
-    /**
-     * <code>string bar_string_piece = 15 [default = "SPIECE", ctype = STRING_PIECE];</code>
-     * @return The barStringPiece.
-     */
-    @java.lang.Override
-    public java.lang.String getBarStringPiece() {
-      java.lang.String ref = "SPIECE";
-      if (barCase_ == 15) {
-        ref = (java.lang.String) bar_;
-      }
-      return ref;
-    }
-    /**
-     * <code>string bar_string_piece = 15 [default = "SPIECE", ctype = STRING_PIECE];</code>
-     * @return The bytes for barStringPiece.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getBarStringPieceBytes() {
-      java.lang.String ref = "SPIECE";
-      if (barCase_ == 15) {
-        ref = (java.lang.String) bar_;
-      }
-      return com.google.protobuf.ByteString.copyFromUtf8(ref);
-    }
-    /**
-     * <code>string bar_string_piece = 15 [default = "SPIECE", ctype = STRING_PIECE];</code>
-     * @param value The barStringPiece to set.
-     */
-    private void setBarStringPiece(
-        java.lang.String value) {
-      value.getClass();
-  barCase_ = 15;
-      bar_ = value;
-    }
-    /**
-     * <code>string bar_string_piece = 15 [default = "SPIECE", ctype = STRING_PIECE];</code>
-     */
-    private void clearBarStringPiece() {
-      if (barCase_ == 15) {
-        barCase_ = 0;
-        bar_ = null;
-      }
-    }
-    /**
-     * <code>string bar_string_piece = 15 [default = "SPIECE", ctype = STRING_PIECE];</code>
-     * @param value The bytes for barStringPiece to set.
-     */
-    private void setBarStringPieceBytes(
-        com.google.protobuf.ByteString value) {
-      bar_ = value.toStringUtf8();
-      barCase_ = 15;
-    }
-
-    public static final int BAR_BYTES_FIELD_NUMBER = 16;
-    /**
-     * <code>bytes bar_bytes = 16 [default = "BYTES"];</code>
-     * @return Whether the barBytes field is set.
-     */
-    @java.lang.Override
-    public boolean hasBarBytes() {
-      return barCase_ == 16;
-    }
-    /**
-     * <code>bytes bar_bytes = 16 [default = "BYTES"];</code>
-     * @return The barBytes.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getBarBytes() {
-      if (barCase_ == 16) {
-        return (com.google.protobuf.ByteString) bar_;
-      }
-      return com.google.protobuf.Internal.bytesDefaultValue("BYTES");
-    }
-    /**
-     * <code>bytes bar_bytes = 16 [default = "BYTES"];</code>
-     * @param value The barBytes to set.
-     */
-    private void setBarBytes(com.google.protobuf.ByteString value) {
-      value.getClass();
-  barCase_ = 16;
-      bar_ = value;
-    }
-    /**
-     * <code>bytes bar_bytes = 16 [default = "BYTES"];</code>
-     */
-    private void clearBarBytes() {
-      if (barCase_ == 16) {
-        barCase_ = 0;
-        bar_ = null;
-      }
-    }
-
-    public static final int BAR_ENUM_FIELD_NUMBER = 17;
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedEnum bar_enum = 17 [default = BAR];</code>
-     * @return Whether the barEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasBarEnum() {
-      return barCase_ == 17;
-    }
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedEnum bar_enum = 17 [default = BAR];</code>
-     * @return The barEnum.
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestOneof2.NestedEnum getBarEnum() {
-      if (barCase_ == 17) {
-        protobuf_unittest.UnittestProto.TestOneof2.NestedEnum result = protobuf_unittest.UnittestProto.TestOneof2.NestedEnum.forNumber((java.lang.Integer) bar_);
-        return result == null ? protobuf_unittest.UnittestProto.TestOneof2.NestedEnum.BAR : result;
-      }
-      return protobuf_unittest.UnittestProto.TestOneof2.NestedEnum.BAR;
-    }
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedEnum bar_enum = 17 [default = BAR];</code>
-     * @param value The barEnum to set.
-     */
-    private void setBarEnum(protobuf_unittest.UnittestProto.TestOneof2.NestedEnum value) {
-      bar_ = value.getNumber();
-      barCase_ = 17;
-    }
-    /**
-     * <code>.protobuf_unittest.TestOneof2.NestedEnum bar_enum = 17 [default = BAR];</code>
-     */
-    private void clearBarEnum() {
-      if (barCase_ == 17) {
-        barCase_ = 0;
-        bar_ = null;
-      }
-    }
-
-    public static final int BAZ_INT_FIELD_NUMBER = 18;
-    private int bazInt_;
-    /**
-     * <code>optional int32 baz_int = 18;</code>
-     * @return Whether the bazInt field is set.
-     */
-    @java.lang.Override
-    public boolean hasBazInt() {
-      return ((bitField0_ & 0x00008000) != 0);
-    }
-    /**
-     * <code>optional int32 baz_int = 18;</code>
-     * @return The bazInt.
-     */
-    @java.lang.Override
-    public int getBazInt() {
-      return bazInt_;
-    }
-    /**
-     * <code>optional int32 baz_int = 18;</code>
-     * @param value The bazInt to set.
-     */
-    private void setBazInt(int value) {
-      bitField0_ |= 0x00008000;
-      bazInt_ = value;
-    }
-    /**
-     * <code>optional int32 baz_int = 18;</code>
-     */
-    private void clearBazInt() {
-      bitField0_ = (bitField0_ & ~0x00008000);
-      bazInt_ = 0;
-    }
-
-    public static final int BAZ_STRING_FIELD_NUMBER = 19;
-    private java.lang.String bazString_;
-    /**
-     * <code>optional string baz_string = 19 [default = "BAZ"];</code>
-     * @return Whether the bazString field is set.
-     */
-    @java.lang.Override
-    public boolean hasBazString() {
-      return ((bitField0_ & 0x00010000) != 0);
-    }
-    /**
-     * <code>optional string baz_string = 19 [default = "BAZ"];</code>
-     * @return The bazString.
-     */
-    @java.lang.Override
-    public java.lang.String getBazString() {
-      return bazString_;
-    }
-    /**
-     * <code>optional string baz_string = 19 [default = "BAZ"];</code>
-     * @return The bytes for bazString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getBazStringBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(bazString_);
-    }
-    /**
-     * <code>optional string baz_string = 19 [default = "BAZ"];</code>
-     * @param value The bazString to set.
-     */
-    private void setBazString(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00010000;
-      bazString_ = value;
-    }
-    /**
-     * <code>optional string baz_string = 19 [default = "BAZ"];</code>
-     */
-    private void clearBazString() {
-      bitField0_ = (bitField0_ & ~0x00010000);
-      bazString_ = getDefaultInstance().getBazString();
-    }
-    /**
-     * <code>optional string baz_string = 19 [default = "BAZ"];</code>
-     * @param value The bytes for bazString to set.
-     */
-    private void setBazStringBytes(
-        com.google.protobuf.ByteString value) {
-      bazString_ = value.toStringUtf8();
-      bitField0_ |= 0x00010000;
-    }
-
-    public static protobuf_unittest.UnittestProto.TestOneof2 parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof2 parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof2 parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof2 parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof2 parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof2 parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof2 parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof2 parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof2 parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof2 parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof2 parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestOneof2 parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestOneof2 prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestOneof2}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestOneof2, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestOneof2)
-        protobuf_unittest.UnittestProto.TestOneof2OrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestOneof2.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-      @java.lang.Override
-      public FooCase
-          getFooCase() {
-        return instance.getFooCase();
-      }
-
-      public Builder clearFoo() {
-        copyOnWrite();
-        instance.clearFoo();
-        return this;
-      }
-
-      @java.lang.Override
-      public BarCase
-          getBarCase() {
-        return instance.getBarCase();
-      }
-
-      public Builder clearBar() {
-        copyOnWrite();
-        instance.clearBar();
-        return this;
-      }
-
-
-      /**
-       * <code>int32 foo_int = 1;</code>
-       * @return Whether the fooInt field is set.
-       */
-      @java.lang.Override
-      public boolean hasFooInt() {
-        return instance.hasFooInt();
-      }
-      /**
-       * <code>int32 foo_int = 1;</code>
-       * @return The fooInt.
-       */
-      @java.lang.Override
-      public int getFooInt() {
-        return instance.getFooInt();
-      }
-      /**
-       * <code>int32 foo_int = 1;</code>
-       * @param value The fooInt to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooInt(int value) {
-        copyOnWrite();
-        instance.setFooInt(value);
-        return this;
-      }
-      /**
-       * <code>int32 foo_int = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFooInt() {
-        copyOnWrite();
-        instance.clearFooInt();
-        return this;
-      }
-
-      /**
-       * <code>string foo_string = 2;</code>
-       * @return Whether the fooString field is set.
-       */
-      @java.lang.Override
-      public boolean hasFooString() {
-        return instance.hasFooString();
-      }
-      /**
-       * <code>string foo_string = 2;</code>
-       * @return The fooString.
-       */
-      @java.lang.Override
-      public java.lang.String getFooString() {
-        return instance.getFooString();
-      }
-      /**
-       * <code>string foo_string = 2;</code>
-       * @return The bytes for fooString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getFooStringBytes() {
-        return instance.getFooStringBytes();
-      }
-      /**
-       * <code>string foo_string = 2;</code>
-       * @param value The fooString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setFooString(value);
-        return this;
-      }
-      /**
-       * <code>string foo_string = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFooString() {
-        copyOnWrite();
-        instance.clearFooString();
-        return this;
-      }
-      /**
-       * <code>string foo_string = 2;</code>
-       * @param value The bytes for fooString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setFooStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>string foo_cord = 3 [ctype = CORD];</code>
-       * @return Whether the fooCord field is set.
-       */
-      @java.lang.Override
-      public boolean hasFooCord() {
-        return instance.hasFooCord();
-      }
-      /**
-       * <code>string foo_cord = 3 [ctype = CORD];</code>
-       * @return The fooCord.
-       */
-      @java.lang.Override
-      public java.lang.String getFooCord() {
-        return instance.getFooCord();
-      }
-      /**
-       * <code>string foo_cord = 3 [ctype = CORD];</code>
-       * @return The bytes for fooCord.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getFooCordBytes() {
-        return instance.getFooCordBytes();
-      }
-      /**
-       * <code>string foo_cord = 3 [ctype = CORD];</code>
-       * @param value The fooCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooCord(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setFooCord(value);
-        return this;
-      }
-      /**
-       * <code>string foo_cord = 3 [ctype = CORD];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFooCord() {
-        copyOnWrite();
-        instance.clearFooCord();
-        return this;
-      }
-      /**
-       * <code>string foo_cord = 3 [ctype = CORD];</code>
-       * @param value The bytes for fooCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooCordBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setFooCordBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>string foo_string_piece = 4 [ctype = STRING_PIECE];</code>
-       * @return Whether the fooStringPiece field is set.
-       */
-      @java.lang.Override
-      public boolean hasFooStringPiece() {
-        return instance.hasFooStringPiece();
-      }
-      /**
-       * <code>string foo_string_piece = 4 [ctype = STRING_PIECE];</code>
-       * @return The fooStringPiece.
-       */
-      @java.lang.Override
-      public java.lang.String getFooStringPiece() {
-        return instance.getFooStringPiece();
-      }
-      /**
-       * <code>string foo_string_piece = 4 [ctype = STRING_PIECE];</code>
-       * @return The bytes for fooStringPiece.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getFooStringPieceBytes() {
-        return instance.getFooStringPieceBytes();
-      }
-      /**
-       * <code>string foo_string_piece = 4 [ctype = STRING_PIECE];</code>
-       * @param value The fooStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooStringPiece(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setFooStringPiece(value);
-        return this;
-      }
-      /**
-       * <code>string foo_string_piece = 4 [ctype = STRING_PIECE];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFooStringPiece() {
-        copyOnWrite();
-        instance.clearFooStringPiece();
-        return this;
-      }
-      /**
-       * <code>string foo_string_piece = 4 [ctype = STRING_PIECE];</code>
-       * @param value The bytes for fooStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooStringPieceBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setFooStringPieceBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>bytes foo_bytes = 5;</code>
-       * @return Whether the fooBytes field is set.
-       */
-      @java.lang.Override
-      public boolean hasFooBytes() {
-        return instance.hasFooBytes();
-      }
-      /**
-       * <code>bytes foo_bytes = 5;</code>
-       * @return The fooBytes.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getFooBytes() {
-        return instance.getFooBytes();
-      }
-      /**
-       * <code>bytes foo_bytes = 5;</code>
-       * @param value The fooBytes to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooBytes(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setFooBytes(value);
-        return this;
-      }
-      /**
-       * <code>bytes foo_bytes = 5;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFooBytes() {
-        copyOnWrite();
-        instance.clearFooBytes();
-        return this;
-      }
-
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-       * @return Whether the fooEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasFooEnum() {
-        return instance.hasFooEnum();
-      }
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-       * @return The fooEnum.
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestOneof2.NestedEnum getFooEnum() {
-        return instance.getFooEnum();
-      }
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-       * @param value The fooEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooEnum(protobuf_unittest.UnittestProto.TestOneof2.NestedEnum value) {
-        copyOnWrite();
-        instance.setFooEnum(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedEnum foo_enum = 6;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFooEnum() {
-        copyOnWrite();
-        instance.clearFooEnum();
-        return this;
-      }
-
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_message = 7;</code>
-       */
-      @java.lang.Override
-      public boolean hasFooMessage() {
-        return instance.hasFooMessage();
-      }
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_message = 7;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestOneof2.NestedMessage getFooMessage() {
-        return instance.getFooMessage();
-      }
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_message = 7;</code>
-       */
-      public Builder setFooMessage(protobuf_unittest.UnittestProto.TestOneof2.NestedMessage value) {
-        copyOnWrite();
-        instance.setFooMessage(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_message = 7;</code>
-       */
-      public Builder setFooMessage(
-          protobuf_unittest.UnittestProto.TestOneof2.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setFooMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_message = 7;</code>
-       */
-      public Builder mergeFooMessage(protobuf_unittest.UnittestProto.TestOneof2.NestedMessage value) {
-        copyOnWrite();
-        instance.mergeFooMessage(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_message = 7;</code>
-       */
-      public Builder clearFooMessage() {
-        copyOnWrite();
-        instance.clearFooMessage();
-        return this;
-      }
-
-      /**
-       * <code>group FooGroup = 8 { ... }</code>
-       */
-      @java.lang.Override
-      public boolean hasFooGroup() {
-        return instance.hasFooGroup();
-      }
-      /**
-       * <code>group FooGroup = 8 { ... }</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestOneof2.FooGroup getFooGroup() {
-        return instance.getFooGroup();
-      }
-      /**
-       * <code>group FooGroup = 8 { ... }</code>
-       */
-      public Builder setFooGroup(protobuf_unittest.UnittestProto.TestOneof2.FooGroup value) {
-        copyOnWrite();
-        instance.setFooGroup(value);
-        return this;
-      }
-      /**
-       * <code>group FooGroup = 8 { ... }</code>
-       */
-      public Builder setFooGroup(
-          protobuf_unittest.UnittestProto.TestOneof2.FooGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.setFooGroup(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>group FooGroup = 8 { ... }</code>
-       */
-      public Builder mergeFooGroup(protobuf_unittest.UnittestProto.TestOneof2.FooGroup value) {
-        copyOnWrite();
-        instance.mergeFooGroup(value);
-        return this;
-      }
-      /**
-       * <code>group FooGroup = 8 { ... }</code>
-       */
-      public Builder clearFooGroup() {
-        copyOnWrite();
-        instance.clearFooGroup();
-        return this;
-      }
-
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_lazy_message = 11 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public boolean hasFooLazyMessage() {
-        return instance.hasFooLazyMessage();
-      }
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_lazy_message = 11 [lazy = true];</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestOneof2.NestedMessage getFooLazyMessage() {
-        return instance.getFooLazyMessage();
-      }
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_lazy_message = 11 [lazy = true];</code>
-       */
-      public Builder setFooLazyMessage(protobuf_unittest.UnittestProto.TestOneof2.NestedMessage value) {
-        copyOnWrite();
-        instance.setFooLazyMessage(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_lazy_message = 11 [lazy = true];</code>
-       */
-      public Builder setFooLazyMessage(
-          protobuf_unittest.UnittestProto.TestOneof2.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setFooLazyMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_lazy_message = 11 [lazy = true];</code>
-       */
-      public Builder mergeFooLazyMessage(protobuf_unittest.UnittestProto.TestOneof2.NestedMessage value) {
-        copyOnWrite();
-        instance.mergeFooLazyMessage(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedMessage foo_lazy_message = 11 [lazy = true];</code>
-       */
-      public Builder clearFooLazyMessage() {
-        copyOnWrite();
-        instance.clearFooLazyMessage();
-        return this;
-      }
-
-      /**
-       * <code>int32 bar_int = 12 [default = 5];</code>
-       * @return Whether the barInt field is set.
-       */
-      @java.lang.Override
-      public boolean hasBarInt() {
-        return instance.hasBarInt();
-      }
-      /**
-       * <code>int32 bar_int = 12 [default = 5];</code>
-       * @return The barInt.
-       */
-      @java.lang.Override
-      public int getBarInt() {
-        return instance.getBarInt();
-      }
-      /**
-       * <code>int32 bar_int = 12 [default = 5];</code>
-       * @param value The barInt to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBarInt(int value) {
-        copyOnWrite();
-        instance.setBarInt(value);
-        return this;
-      }
-      /**
-       * <code>int32 bar_int = 12 [default = 5];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearBarInt() {
-        copyOnWrite();
-        instance.clearBarInt();
-        return this;
-      }
-
-      /**
-       * <code>string bar_string = 13 [default = "STRING"];</code>
-       * @return Whether the barString field is set.
-       */
-      @java.lang.Override
-      public boolean hasBarString() {
-        return instance.hasBarString();
-      }
-      /**
-       * <code>string bar_string = 13 [default = "STRING"];</code>
-       * @return The barString.
-       */
-      @java.lang.Override
-      public java.lang.String getBarString() {
-        return instance.getBarString();
-      }
-      /**
-       * <code>string bar_string = 13 [default = "STRING"];</code>
-       * @return The bytes for barString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getBarStringBytes() {
-        return instance.getBarStringBytes();
-      }
-      /**
-       * <code>string bar_string = 13 [default = "STRING"];</code>
-       * @param value The barString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBarString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setBarString(value);
-        return this;
-      }
-      /**
-       * <code>string bar_string = 13 [default = "STRING"];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearBarString() {
-        copyOnWrite();
-        instance.clearBarString();
-        return this;
-      }
-      /**
-       * <code>string bar_string = 13 [default = "STRING"];</code>
-       * @param value The bytes for barString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBarStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setBarStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>string bar_cord = 14 [default = "CORD", ctype = CORD];</code>
-       * @return Whether the barCord field is set.
-       */
-      @java.lang.Override
-      public boolean hasBarCord() {
-        return instance.hasBarCord();
-      }
-      /**
-       * <code>string bar_cord = 14 [default = "CORD", ctype = CORD];</code>
-       * @return The barCord.
-       */
-      @java.lang.Override
-      public java.lang.String getBarCord() {
-        return instance.getBarCord();
-      }
-      /**
-       * <code>string bar_cord = 14 [default = "CORD", ctype = CORD];</code>
-       * @return The bytes for barCord.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getBarCordBytes() {
-        return instance.getBarCordBytes();
-      }
-      /**
-       * <code>string bar_cord = 14 [default = "CORD", ctype = CORD];</code>
-       * @param value The barCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBarCord(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setBarCord(value);
-        return this;
-      }
-      /**
-       * <code>string bar_cord = 14 [default = "CORD", ctype = CORD];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearBarCord() {
-        copyOnWrite();
-        instance.clearBarCord();
-        return this;
-      }
-      /**
-       * <code>string bar_cord = 14 [default = "CORD", ctype = CORD];</code>
-       * @param value The bytes for barCord to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBarCordBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setBarCordBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>string bar_string_piece = 15 [default = "SPIECE", ctype = STRING_PIECE];</code>
-       * @return Whether the barStringPiece field is set.
-       */
-      @java.lang.Override
-      public boolean hasBarStringPiece() {
-        return instance.hasBarStringPiece();
-      }
-      /**
-       * <code>string bar_string_piece = 15 [default = "SPIECE", ctype = STRING_PIECE];</code>
-       * @return The barStringPiece.
-       */
-      @java.lang.Override
-      public java.lang.String getBarStringPiece() {
-        return instance.getBarStringPiece();
-      }
-      /**
-       * <code>string bar_string_piece = 15 [default = "SPIECE", ctype = STRING_PIECE];</code>
-       * @return The bytes for barStringPiece.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getBarStringPieceBytes() {
-        return instance.getBarStringPieceBytes();
-      }
-      /**
-       * <code>string bar_string_piece = 15 [default = "SPIECE", ctype = STRING_PIECE];</code>
-       * @param value The barStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBarStringPiece(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setBarStringPiece(value);
-        return this;
-      }
-      /**
-       * <code>string bar_string_piece = 15 [default = "SPIECE", ctype = STRING_PIECE];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearBarStringPiece() {
-        copyOnWrite();
-        instance.clearBarStringPiece();
-        return this;
-      }
-      /**
-       * <code>string bar_string_piece = 15 [default = "SPIECE", ctype = STRING_PIECE];</code>
-       * @param value The bytes for barStringPiece to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBarStringPieceBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setBarStringPieceBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>bytes bar_bytes = 16 [default = "BYTES"];</code>
-       * @return Whether the barBytes field is set.
-       */
-      @java.lang.Override
-      public boolean hasBarBytes() {
-        return instance.hasBarBytes();
-      }
-      /**
-       * <code>bytes bar_bytes = 16 [default = "BYTES"];</code>
-       * @return The barBytes.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getBarBytes() {
-        return instance.getBarBytes();
-      }
-      /**
-       * <code>bytes bar_bytes = 16 [default = "BYTES"];</code>
-       * @param value The barBytes to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBarBytes(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setBarBytes(value);
-        return this;
-      }
-      /**
-       * <code>bytes bar_bytes = 16 [default = "BYTES"];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearBarBytes() {
-        copyOnWrite();
-        instance.clearBarBytes();
-        return this;
-      }
-
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedEnum bar_enum = 17 [default = BAR];</code>
-       * @return Whether the barEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasBarEnum() {
-        return instance.hasBarEnum();
-      }
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedEnum bar_enum = 17 [default = BAR];</code>
-       * @return The barEnum.
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestOneof2.NestedEnum getBarEnum() {
-        return instance.getBarEnum();
-      }
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedEnum bar_enum = 17 [default = BAR];</code>
-       * @param value The barEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBarEnum(protobuf_unittest.UnittestProto.TestOneof2.NestedEnum value) {
-        copyOnWrite();
-        instance.setBarEnum(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestOneof2.NestedEnum bar_enum = 17 [default = BAR];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearBarEnum() {
-        copyOnWrite();
-        instance.clearBarEnum();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 baz_int = 18;</code>
-       * @return Whether the bazInt field is set.
-       */
-      @java.lang.Override
-      public boolean hasBazInt() {
-        return instance.hasBazInt();
-      }
-      /**
-       * <code>optional int32 baz_int = 18;</code>
-       * @return The bazInt.
-       */
-      @java.lang.Override
-      public int getBazInt() {
-        return instance.getBazInt();
-      }
-      /**
-       * <code>optional int32 baz_int = 18;</code>
-       * @param value The bazInt to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBazInt(int value) {
-        copyOnWrite();
-        instance.setBazInt(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 baz_int = 18;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearBazInt() {
-        copyOnWrite();
-        instance.clearBazInt();
-        return this;
-      }
-
-      /**
-       * <code>optional string baz_string = 19 [default = "BAZ"];</code>
-       * @return Whether the bazString field is set.
-       */
-      @java.lang.Override
-      public boolean hasBazString() {
-        return instance.hasBazString();
-      }
-      /**
-       * <code>optional string baz_string = 19 [default = "BAZ"];</code>
-       * @return The bazString.
-       */
-      @java.lang.Override
-      public java.lang.String getBazString() {
-        return instance.getBazString();
-      }
-      /**
-       * <code>optional string baz_string = 19 [default = "BAZ"];</code>
-       * @return The bytes for bazString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getBazStringBytes() {
-        return instance.getBazStringBytes();
-      }
-      /**
-       * <code>optional string baz_string = 19 [default = "BAZ"];</code>
-       * @param value The bazString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBazString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setBazString(value);
-        return this;
-      }
-      /**
-       * <code>optional string baz_string = 19 [default = "BAZ"];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearBazString() {
-        copyOnWrite();
-        instance.clearBazString();
-        return this;
-      }
-      /**
-       * <code>optional string baz_string = 19 [default = "BAZ"];</code>
-       * @param value The bytes for bazString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBazStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setBazStringBytes(value);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestOneof2)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestOneof2();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "foo_",
-              "fooCase_",
-              "bar_",
-              "barCase_",
-              "bitField0_",
-              protobuf_unittest.UnittestProto.TestOneof2.NestedEnum.internalGetVerifier(),
-              protobuf_unittest.UnittestProto.TestOneof2.NestedMessage.class,
-              protobuf_unittest.UnittestProto.TestOneof2.FooGroup.class,
-              protobuf_unittest.UnittestProto.TestOneof2.NestedMessage.class,
-              protobuf_unittest.UnittestProto.TestOneof2.NestedEnum.internalGetVerifier(),
-              "bazInt_",
-              "bazString_",
-            };
-            java.lang.String info =
-                "\u0001\u0011\u0002\u0001\u0001\u0013\u0011\u0000\u0000\u0000\u0001\u1037\u0000\u0002" +
-                "\u103b\u0000\u0003\u103b\u0000\u0004\u103b\u0000\u0005\u103d\u0000\u0006\u103f\u0000" +
-                "\u0007\u103c\u0000\b\u1044\u0000\u000b\u103c\u0000\f\u1037\u0001\r\u103b\u0001\u000e" +
-                "\u103b\u0001\u000f\u103b\u0001\u0010\u103d\u0001\u0011\u103f\u0001\u0012\u1004\u000f" +
-                "\u0013\u1008\u0010";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestOneof2> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestOneof2.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestOneof2>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestOneof2)
-    private static final protobuf_unittest.UnittestProto.TestOneof2 DEFAULT_INSTANCE;
-    static {
-      TestOneof2 defaultInstance = new TestOneof2();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestOneof2.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestOneof2 getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestOneof2> PARSER;
-
-    public static com.google.protobuf.Parser<TestOneof2> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestRequiredOneofOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestRequiredOneof)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>int32 foo_int = 1;</code>
-     * @return Whether the fooInt field is set.
-     */
-    boolean hasFooInt();
-    /**
-     * <code>int32 foo_int = 1;</code>
-     * @return The fooInt.
-     */
-    int getFooInt();
-
-    /**
-     * <code>string foo_string = 2;</code>
-     * @return Whether the fooString field is set.
-     */
-    boolean hasFooString();
-    /**
-     * <code>string foo_string = 2;</code>
-     * @return The fooString.
-     */
-    java.lang.String getFooString();
-    /**
-     * <code>string foo_string = 2;</code>
-     * @return The bytes for fooString.
-     */
-    com.google.protobuf.ByteString
-        getFooStringBytes();
-
-    /**
-     * <code>.protobuf_unittest.TestRequiredOneof.NestedMessage foo_message = 3;</code>
-     * @return Whether the fooMessage field is set.
-     */
-    boolean hasFooMessage();
-    /**
-     * <code>.protobuf_unittest.TestRequiredOneof.NestedMessage foo_message = 3;</code>
-     * @return The fooMessage.
-     */
-    protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage getFooMessage();
-
-    public protobuf_unittest.UnittestProto.TestRequiredOneof.FooCase getFooCase();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestRequiredOneof}
-   */
-  public  static final class TestRequiredOneof extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestRequiredOneof, TestRequiredOneof.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestRequiredOneof)
-      TestRequiredOneofOrBuilder {
-    private TestRequiredOneof() {
-    }
-    public interface NestedMessageOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestRequiredOneof.NestedMessage)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>required double required_double = 1;</code>
-       * @return Whether the requiredDouble field is set.
-       */
-      boolean hasRequiredDouble();
-      /**
-       * <code>required double required_double = 1;</code>
-       * @return The requiredDouble.
-       */
-      double getRequiredDouble();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestRequiredOneof.NestedMessage}
-     */
-    public  static final class NestedMessage extends
-        com.google.protobuf.GeneratedMessageLite<
-            NestedMessage, NestedMessage.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestRequiredOneof.NestedMessage)
-        NestedMessageOrBuilder {
-      private NestedMessage() {
-      }
-      private int bitField0_;
-      public static final int REQUIRED_DOUBLE_FIELD_NUMBER = 1;
-      private double requiredDouble_;
-      /**
-       * <code>required double required_double = 1;</code>
-       * @return Whether the requiredDouble field is set.
-       */
-      @java.lang.Override
-      public boolean hasRequiredDouble() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>required double required_double = 1;</code>
-       * @return The requiredDouble.
-       */
-      @java.lang.Override
-      public double getRequiredDouble() {
-        return requiredDouble_;
-      }
-      /**
-       * <code>required double required_double = 1;</code>
-       * @param value The requiredDouble to set.
-       */
-      private void setRequiredDouble(double value) {
-        bitField0_ |= 0x00000001;
-        requiredDouble_ = value;
-      }
-      /**
-       * <code>required double required_double = 1;</code>
-       */
-      private void clearRequiredDouble() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        requiredDouble_ = 0D;
-      }
-
-      public static protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestRequiredOneof.NestedMessage}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestRequiredOneof.NestedMessage)
-          protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessageOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>required double required_double = 1;</code>
-         * @return Whether the requiredDouble field is set.
-         */
-        @java.lang.Override
-        public boolean hasRequiredDouble() {
-          return instance.hasRequiredDouble();
-        }
-        /**
-         * <code>required double required_double = 1;</code>
-         * @return The requiredDouble.
-         */
-        @java.lang.Override
-        public double getRequiredDouble() {
-          return instance.getRequiredDouble();
-        }
-        /**
-         * <code>required double required_double = 1;</code>
-         * @param value The requiredDouble to set.
-         * @return This builder for chaining.
-         */
-        public Builder setRequiredDouble(double value) {
-          copyOnWrite();
-          instance.setRequiredDouble(value);
-          return this;
-        }
-        /**
-         * <code>required double required_double = 1;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearRequiredDouble() {
-          copyOnWrite();
-          instance.clearRequiredDouble();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestRequiredOneof.NestedMessage)
-      }
-      private byte memoizedIsInitialized = 2;
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "requiredDouble_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0001\u0001\u1500\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return memoizedIsInitialized;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestRequiredOneof.NestedMessage)
-      private static final protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage DEFAULT_INSTANCE;
-      static {
-        NestedMessage defaultInstance = new NestedMessage();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          NestedMessage.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<NestedMessage> PARSER;
-
-      public static com.google.protobuf.Parser<NestedMessage> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int bitField0_;
-    private int fooCase_ = 0;
-    private java.lang.Object foo_;
-    public enum FooCase {
-      FOO_INT(1),
-      FOO_STRING(2),
-      FOO_MESSAGE(3),
-      FOO_NOT_SET(0);
-      private final int value;
-      private FooCase(int value) {
-        this.value = value;
-      }
-      /**
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static FooCase valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static FooCase forNumber(int value) {
-        switch (value) {
-          case 1: return FOO_INT;
-          case 2: return FOO_STRING;
-          case 3: return FOO_MESSAGE;
-          case 0: return FOO_NOT_SET;
-          default: return null;
-        }
-      }
-      public int getNumber() {
-        return this.value;
-      }
-    };
-
-    @java.lang.Override
-    public FooCase
-    getFooCase() {
-      return FooCase.forNumber(
-          fooCase_);
-    }
-
-    private void clearFoo() {
-      fooCase_ = 0;
-      foo_ = null;
-    }
-
-    public static final int FOO_INT_FIELD_NUMBER = 1;
-    /**
-     * <code>int32 foo_int = 1;</code>
-     * @return Whether the fooInt field is set.
-     */
-    @java.lang.Override
-    public boolean hasFooInt() {
-      return fooCase_ == 1;
-    }
-    /**
-     * <code>int32 foo_int = 1;</code>
-     * @return The fooInt.
-     */
-    @java.lang.Override
-    public int getFooInt() {
-      if (fooCase_ == 1) {
-        return (java.lang.Integer) foo_;
-      }
-      return 0;
-    }
-    /**
-     * <code>int32 foo_int = 1;</code>
-     * @param value The fooInt to set.
-     */
-    private void setFooInt(int value) {
-      fooCase_ = 1;
-      foo_ = value;
-    }
-    /**
-     * <code>int32 foo_int = 1;</code>
-     */
-    private void clearFooInt() {
-      if (fooCase_ == 1) {
-        fooCase_ = 0;
-        foo_ = null;
-      }
-    }
-
-    public static final int FOO_STRING_FIELD_NUMBER = 2;
-    /**
-     * <code>string foo_string = 2;</code>
-     * @return Whether the fooString field is set.
-     */
-    @java.lang.Override
-    public boolean hasFooString() {
-      return fooCase_ == 2;
-    }
-    /**
-     * <code>string foo_string = 2;</code>
-     * @return The fooString.
-     */
-    @java.lang.Override
-    public java.lang.String getFooString() {
-      java.lang.String ref = "";
-      if (fooCase_ == 2) {
-        ref = (java.lang.String) foo_;
-      }
-      return ref;
-    }
-    /**
-     * <code>string foo_string = 2;</code>
-     * @return The bytes for fooString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getFooStringBytes() {
-      java.lang.String ref = "";
-      if (fooCase_ == 2) {
-        ref = (java.lang.String) foo_;
-      }
-      return com.google.protobuf.ByteString.copyFromUtf8(ref);
-    }
-    /**
-     * <code>string foo_string = 2;</code>
-     * @param value The fooString to set.
-     */
-    private void setFooString(
-        java.lang.String value) {
-      value.getClass();
-  fooCase_ = 2;
-      foo_ = value;
-    }
-    /**
-     * <code>string foo_string = 2;</code>
-     */
-    private void clearFooString() {
-      if (fooCase_ == 2) {
-        fooCase_ = 0;
-        foo_ = null;
-      }
-    }
-    /**
-     * <code>string foo_string = 2;</code>
-     * @param value The bytes for fooString to set.
-     */
-    private void setFooStringBytes(
-        com.google.protobuf.ByteString value) {
-      foo_ = value.toStringUtf8();
-      fooCase_ = 2;
-    }
-
-    public static final int FOO_MESSAGE_FIELD_NUMBER = 3;
-    /**
-     * <code>.protobuf_unittest.TestRequiredOneof.NestedMessage foo_message = 3;</code>
-     */
-    @java.lang.Override
-    public boolean hasFooMessage() {
-      return fooCase_ == 3;
-    }
-    /**
-     * <code>.protobuf_unittest.TestRequiredOneof.NestedMessage foo_message = 3;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage getFooMessage() {
-      if (fooCase_ == 3) {
-         return (protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage) foo_;
-      }
-      return protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage.getDefaultInstance();
-    }
-    /**
-     * <code>.protobuf_unittest.TestRequiredOneof.NestedMessage foo_message = 3;</code>
-     */
-    private void setFooMessage(protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage value) {
-      value.getClass();
-  foo_ = value;
-      fooCase_ = 3;
-    }
-    /**
-     * <code>.protobuf_unittest.TestRequiredOneof.NestedMessage foo_message = 3;</code>
-     */
-    private void mergeFooMessage(protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage value) {
-      value.getClass();
-  if (fooCase_ == 3 &&
-          foo_ != protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage.getDefaultInstance()) {
-        foo_ = protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage.newBuilder((protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage) foo_)
-            .mergeFrom(value).buildPartial();
-      } else {
-        foo_ = value;
-      }
-      fooCase_ = 3;
-    }
-    /**
-     * <code>.protobuf_unittest.TestRequiredOneof.NestedMessage foo_message = 3;</code>
-     */
-    private void clearFooMessage() {
-      if (fooCase_ == 3) {
-        fooCase_ = 0;
-        foo_ = null;
-      }
-    }
-
-    public static protobuf_unittest.UnittestProto.TestRequiredOneof parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredOneof parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredOneof parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredOneof parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredOneof parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredOneof parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredOneof parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredOneof parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredOneof parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredOneof parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredOneof parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestRequiredOneof parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestRequiredOneof prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestRequiredOneof}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestRequiredOneof, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestRequiredOneof)
-        protobuf_unittest.UnittestProto.TestRequiredOneofOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestRequiredOneof.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-      @java.lang.Override
-      public FooCase
-          getFooCase() {
-        return instance.getFooCase();
-      }
-
-      public Builder clearFoo() {
-        copyOnWrite();
-        instance.clearFoo();
-        return this;
-      }
-
-
-      /**
-       * <code>int32 foo_int = 1;</code>
-       * @return Whether the fooInt field is set.
-       */
-      @java.lang.Override
-      public boolean hasFooInt() {
-        return instance.hasFooInt();
-      }
-      /**
-       * <code>int32 foo_int = 1;</code>
-       * @return The fooInt.
-       */
-      @java.lang.Override
-      public int getFooInt() {
-        return instance.getFooInt();
-      }
-      /**
-       * <code>int32 foo_int = 1;</code>
-       * @param value The fooInt to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooInt(int value) {
-        copyOnWrite();
-        instance.setFooInt(value);
-        return this;
-      }
-      /**
-       * <code>int32 foo_int = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFooInt() {
-        copyOnWrite();
-        instance.clearFooInt();
-        return this;
-      }
-
-      /**
-       * <code>string foo_string = 2;</code>
-       * @return Whether the fooString field is set.
-       */
-      @java.lang.Override
-      public boolean hasFooString() {
-        return instance.hasFooString();
-      }
-      /**
-       * <code>string foo_string = 2;</code>
-       * @return The fooString.
-       */
-      @java.lang.Override
-      public java.lang.String getFooString() {
-        return instance.getFooString();
-      }
-      /**
-       * <code>string foo_string = 2;</code>
-       * @return The bytes for fooString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getFooStringBytes() {
-        return instance.getFooStringBytes();
-      }
-      /**
-       * <code>string foo_string = 2;</code>
-       * @param value The fooString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setFooString(value);
-        return this;
-      }
-      /**
-       * <code>string foo_string = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFooString() {
-        copyOnWrite();
-        instance.clearFooString();
-        return this;
-      }
-      /**
-       * <code>string foo_string = 2;</code>
-       * @param value The bytes for fooString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setFooStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>.protobuf_unittest.TestRequiredOneof.NestedMessage foo_message = 3;</code>
-       */
-      @java.lang.Override
-      public boolean hasFooMessage() {
-        return instance.hasFooMessage();
-      }
-      /**
-       * <code>.protobuf_unittest.TestRequiredOneof.NestedMessage foo_message = 3;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage getFooMessage() {
-        return instance.getFooMessage();
-      }
-      /**
-       * <code>.protobuf_unittest.TestRequiredOneof.NestedMessage foo_message = 3;</code>
-       */
-      public Builder setFooMessage(protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage value) {
-        copyOnWrite();
-        instance.setFooMessage(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestRequiredOneof.NestedMessage foo_message = 3;</code>
-       */
-      public Builder setFooMessage(
-          protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setFooMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestRequiredOneof.NestedMessage foo_message = 3;</code>
-       */
-      public Builder mergeFooMessage(protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage value) {
-        copyOnWrite();
-        instance.mergeFooMessage(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestRequiredOneof.NestedMessage foo_message = 3;</code>
-       */
-      public Builder clearFooMessage() {
-        copyOnWrite();
-        instance.clearFooMessage();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestRequiredOneof)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestRequiredOneof();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "foo_",
-              "fooCase_",
-              "bitField0_",
-              protobuf_unittest.UnittestProto.TestRequiredOneof.NestedMessage.class,
-            };
-            java.lang.String info =
-                "\u0001\u0003\u0001\u0001\u0001\u0003\u0003\u0000\u0000\u0001\u0001\u1037\u0000\u0002" +
-                "\u103b\u0000\u0003\u143c\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestRequiredOneof> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestRequiredOneof.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestRequiredOneof>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestRequiredOneof)
-    private static final protobuf_unittest.UnittestProto.TestRequiredOneof DEFAULT_INSTANCE;
-    static {
-      TestRequiredOneof defaultInstance = new TestRequiredOneof();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestRequiredOneof.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestRequiredOneof getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestRequiredOneof> PARSER;
-
-    public static com.google.protobuf.Parser<TestRequiredOneof> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestPackedTypesOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestPackedTypes)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @return A list containing the packedInt32.
-     */
-    java.util.List<java.lang.Integer> getPackedInt32List();
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @return The count of packedInt32.
-     */
-    int getPackedInt32Count();
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedInt32 at the given index.
-     */
-    int getPackedInt32(int index);
-
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @return A list containing the packedInt64.
-     */
-    java.util.List<java.lang.Long> getPackedInt64List();
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @return The count of packedInt64.
-     */
-    int getPackedInt64Count();
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedInt64 at the given index.
-     */
-    long getPackedInt64(int index);
-
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @return A list containing the packedUint32.
-     */
-    java.util.List<java.lang.Integer> getPackedUint32List();
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @return The count of packedUint32.
-     */
-    int getPackedUint32Count();
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedUint32 at the given index.
-     */
-    int getPackedUint32(int index);
-
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @return A list containing the packedUint64.
-     */
-    java.util.List<java.lang.Long> getPackedUint64List();
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @return The count of packedUint64.
-     */
-    int getPackedUint64Count();
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedUint64 at the given index.
-     */
-    long getPackedUint64(int index);
-
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @return A list containing the packedSint32.
-     */
-    java.util.List<java.lang.Integer> getPackedSint32List();
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @return The count of packedSint32.
-     */
-    int getPackedSint32Count();
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSint32 at the given index.
-     */
-    int getPackedSint32(int index);
-
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @return A list containing the packedSint64.
-     */
-    java.util.List<java.lang.Long> getPackedSint64List();
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @return The count of packedSint64.
-     */
-    int getPackedSint64Count();
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSint64 at the given index.
-     */
-    long getPackedSint64(int index);
-
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @return A list containing the packedFixed32.
-     */
-    java.util.List<java.lang.Integer> getPackedFixed32List();
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @return The count of packedFixed32.
-     */
-    int getPackedFixed32Count();
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedFixed32 at the given index.
-     */
-    int getPackedFixed32(int index);
-
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @return A list containing the packedFixed64.
-     */
-    java.util.List<java.lang.Long> getPackedFixed64List();
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @return The count of packedFixed64.
-     */
-    int getPackedFixed64Count();
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedFixed64 at the given index.
-     */
-    long getPackedFixed64(int index);
-
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @return A list containing the packedSfixed32.
-     */
-    java.util.List<java.lang.Integer> getPackedSfixed32List();
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @return The count of packedSfixed32.
-     */
-    int getPackedSfixed32Count();
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSfixed32 at the given index.
-     */
-    int getPackedSfixed32(int index);
-
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @return A list containing the packedSfixed64.
-     */
-    java.util.List<java.lang.Long> getPackedSfixed64List();
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @return The count of packedSfixed64.
-     */
-    int getPackedSfixed64Count();
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSfixed64 at the given index.
-     */
-    long getPackedSfixed64(int index);
-
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @return A list containing the packedFloat.
-     */
-    java.util.List<java.lang.Float> getPackedFloatList();
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @return The count of packedFloat.
-     */
-    int getPackedFloatCount();
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedFloat at the given index.
-     */
-    float getPackedFloat(int index);
-
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @return A list containing the packedDouble.
-     */
-    java.util.List<java.lang.Double> getPackedDoubleList();
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @return The count of packedDouble.
-     */
-    int getPackedDoubleCount();
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedDouble at the given index.
-     */
-    double getPackedDouble(int index);
-
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @return A list containing the packedBool.
-     */
-    java.util.List<java.lang.Boolean> getPackedBoolList();
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @return The count of packedBool.
-     */
-    int getPackedBoolCount();
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedBool at the given index.
-     */
-    boolean getPackedBool(int index);
-
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @return A list containing the packedEnum.
-     */
-    java.util.List<protobuf_unittest.UnittestProto.ForeignEnum> getPackedEnumList();
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @return The count of packedEnum.
-     */
-    int getPackedEnumCount();
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedEnum at the given index.
-     */
-    protobuf_unittest.UnittestProto.ForeignEnum getPackedEnum(int index);
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestPackedTypes}
-   */
-  public  static final class TestPackedTypes extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestPackedTypes, TestPackedTypes.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestPackedTypes)
-      TestPackedTypesOrBuilder {
-    private TestPackedTypes() {
-      packedInt32_ = emptyIntList();
-      packedInt64_ = emptyLongList();
-      packedUint32_ = emptyIntList();
-      packedUint64_ = emptyLongList();
-      packedSint32_ = emptyIntList();
-      packedSint64_ = emptyLongList();
-      packedFixed32_ = emptyIntList();
-      packedFixed64_ = emptyLongList();
-      packedSfixed32_ = emptyIntList();
-      packedSfixed64_ = emptyLongList();
-      packedFloat_ = emptyFloatList();
-      packedDouble_ = emptyDoubleList();
-      packedBool_ = emptyBooleanList();
-      packedEnum_ = emptyIntList();
-    }
-    public static final int PACKED_INT32_FIELD_NUMBER = 90;
-    private com.google.protobuf.Internal.IntList packedInt32_;
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @return A list containing the packedInt32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getPackedInt32List() {
-      return packedInt32_;
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @return The count of packedInt32.
-     */
-    @java.lang.Override
-    public int getPackedInt32Count() {
-      return packedInt32_.size();
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedInt32 at the given index.
-     */
-    @java.lang.Override
-    public int getPackedInt32(int index) {
-      return packedInt32_.getInt(index);
-    }
-    private int packedInt32MemoizedSerializedSize = -1;
-    private void ensurePackedInt32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedInt32_;
-      if (!tmp.isModifiable()) {
-        packedInt32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedInt32 to set.
-     */
-    private void setPackedInt32(
-        int index, int value) {
-      ensurePackedInt32IsMutable();
-      packedInt32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param value The packedInt32 to add.
-     */
-    private void addPackedInt32(int value) {
-      ensurePackedInt32IsMutable();
-      packedInt32_.addInt(value);
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     * @param values The packedInt32 to add.
-     */
-    private void addAllPackedInt32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensurePackedInt32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedInt32_);
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-     */
-    private void clearPackedInt32() {
-      packedInt32_ = emptyIntList();
-    }
-
-    public static final int PACKED_INT64_FIELD_NUMBER = 91;
-    private com.google.protobuf.Internal.LongList packedInt64_;
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @return A list containing the packedInt64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getPackedInt64List() {
-      return packedInt64_;
-    }
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @return The count of packedInt64.
-     */
-    @java.lang.Override
-    public int getPackedInt64Count() {
-      return packedInt64_.size();
-    }
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedInt64 at the given index.
-     */
-    @java.lang.Override
-    public long getPackedInt64(int index) {
-      return packedInt64_.getLong(index);
-    }
-    private int packedInt64MemoizedSerializedSize = -1;
-    private void ensurePackedInt64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = packedInt64_;
-      if (!tmp.isModifiable()) {
-        packedInt64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedInt64 to set.
-     */
-    private void setPackedInt64(
-        int index, long value) {
-      ensurePackedInt64IsMutable();
-      packedInt64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param value The packedInt64 to add.
-     */
-    private void addPackedInt64(long value) {
-      ensurePackedInt64IsMutable();
-      packedInt64_.addLong(value);
-    }
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     * @param values The packedInt64 to add.
-     */
-    private void addAllPackedInt64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensurePackedInt64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedInt64_);
-    }
-    /**
-     * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-     */
-    private void clearPackedInt64() {
-      packedInt64_ = emptyLongList();
-    }
-
-    public static final int PACKED_UINT32_FIELD_NUMBER = 92;
-    private com.google.protobuf.Internal.IntList packedUint32_;
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @return A list containing the packedUint32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getPackedUint32List() {
-      return packedUint32_;
-    }
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @return The count of packedUint32.
-     */
-    @java.lang.Override
-    public int getPackedUint32Count() {
-      return packedUint32_.size();
-    }
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedUint32 at the given index.
-     */
-    @java.lang.Override
-    public int getPackedUint32(int index) {
-      return packedUint32_.getInt(index);
-    }
-    private int packedUint32MemoizedSerializedSize = -1;
-    private void ensurePackedUint32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedUint32_;
-      if (!tmp.isModifiable()) {
-        packedUint32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedUint32 to set.
-     */
-    private void setPackedUint32(
-        int index, int value) {
-      ensurePackedUint32IsMutable();
-      packedUint32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param value The packedUint32 to add.
-     */
-    private void addPackedUint32(int value) {
-      ensurePackedUint32IsMutable();
-      packedUint32_.addInt(value);
-    }
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     * @param values The packedUint32 to add.
-     */
-    private void addAllPackedUint32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensurePackedUint32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedUint32_);
-    }
-    /**
-     * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-     */
-    private void clearPackedUint32() {
-      packedUint32_ = emptyIntList();
-    }
-
-    public static final int PACKED_UINT64_FIELD_NUMBER = 93;
-    private com.google.protobuf.Internal.LongList packedUint64_;
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @return A list containing the packedUint64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getPackedUint64List() {
-      return packedUint64_;
-    }
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @return The count of packedUint64.
-     */
-    @java.lang.Override
-    public int getPackedUint64Count() {
-      return packedUint64_.size();
-    }
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedUint64 at the given index.
-     */
-    @java.lang.Override
-    public long getPackedUint64(int index) {
-      return packedUint64_.getLong(index);
-    }
-    private int packedUint64MemoizedSerializedSize = -1;
-    private void ensurePackedUint64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = packedUint64_;
-      if (!tmp.isModifiable()) {
-        packedUint64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedUint64 to set.
-     */
-    private void setPackedUint64(
-        int index, long value) {
-      ensurePackedUint64IsMutable();
-      packedUint64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param value The packedUint64 to add.
-     */
-    private void addPackedUint64(long value) {
-      ensurePackedUint64IsMutable();
-      packedUint64_.addLong(value);
-    }
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     * @param values The packedUint64 to add.
-     */
-    private void addAllPackedUint64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensurePackedUint64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedUint64_);
-    }
-    /**
-     * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-     */
-    private void clearPackedUint64() {
-      packedUint64_ = emptyLongList();
-    }
-
-    public static final int PACKED_SINT32_FIELD_NUMBER = 94;
-    private com.google.protobuf.Internal.IntList packedSint32_;
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @return A list containing the packedSint32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getPackedSint32List() {
-      return packedSint32_;
-    }
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @return The count of packedSint32.
-     */
-    @java.lang.Override
-    public int getPackedSint32Count() {
-      return packedSint32_.size();
-    }
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSint32 at the given index.
-     */
-    @java.lang.Override
-    public int getPackedSint32(int index) {
-      return packedSint32_.getInt(index);
-    }
-    private int packedSint32MemoizedSerializedSize = -1;
-    private void ensurePackedSint32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedSint32_;
-      if (!tmp.isModifiable()) {
-        packedSint32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSint32 to set.
-     */
-    private void setPackedSint32(
-        int index, int value) {
-      ensurePackedSint32IsMutable();
-      packedSint32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param value The packedSint32 to add.
-     */
-    private void addPackedSint32(int value) {
-      ensurePackedSint32IsMutable();
-      packedSint32_.addInt(value);
-    }
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     * @param values The packedSint32 to add.
-     */
-    private void addAllPackedSint32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensurePackedSint32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedSint32_);
-    }
-    /**
-     * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-     */
-    private void clearPackedSint32() {
-      packedSint32_ = emptyIntList();
-    }
-
-    public static final int PACKED_SINT64_FIELD_NUMBER = 95;
-    private com.google.protobuf.Internal.LongList packedSint64_;
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @return A list containing the packedSint64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getPackedSint64List() {
-      return packedSint64_;
-    }
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @return The count of packedSint64.
-     */
-    @java.lang.Override
-    public int getPackedSint64Count() {
-      return packedSint64_.size();
-    }
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSint64 at the given index.
-     */
-    @java.lang.Override
-    public long getPackedSint64(int index) {
-      return packedSint64_.getLong(index);
-    }
-    private int packedSint64MemoizedSerializedSize = -1;
-    private void ensurePackedSint64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = packedSint64_;
-      if (!tmp.isModifiable()) {
-        packedSint64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSint64 to set.
-     */
-    private void setPackedSint64(
-        int index, long value) {
-      ensurePackedSint64IsMutable();
-      packedSint64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param value The packedSint64 to add.
-     */
-    private void addPackedSint64(long value) {
-      ensurePackedSint64IsMutable();
-      packedSint64_.addLong(value);
-    }
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     * @param values The packedSint64 to add.
-     */
-    private void addAllPackedSint64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensurePackedSint64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedSint64_);
-    }
-    /**
-     * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-     */
-    private void clearPackedSint64() {
-      packedSint64_ = emptyLongList();
-    }
-
-    public static final int PACKED_FIXED32_FIELD_NUMBER = 96;
-    private com.google.protobuf.Internal.IntList packedFixed32_;
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @return A list containing the packedFixed32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getPackedFixed32List() {
-      return packedFixed32_;
-    }
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @return The count of packedFixed32.
-     */
-    @java.lang.Override
-    public int getPackedFixed32Count() {
-      return packedFixed32_.size();
-    }
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedFixed32 at the given index.
-     */
-    @java.lang.Override
-    public int getPackedFixed32(int index) {
-      return packedFixed32_.getInt(index);
-    }
-    private int packedFixed32MemoizedSerializedSize = -1;
-    private void ensurePackedFixed32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedFixed32_;
-      if (!tmp.isModifiable()) {
-        packedFixed32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedFixed32 to set.
-     */
-    private void setPackedFixed32(
-        int index, int value) {
-      ensurePackedFixed32IsMutable();
-      packedFixed32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param value The packedFixed32 to add.
-     */
-    private void addPackedFixed32(int value) {
-      ensurePackedFixed32IsMutable();
-      packedFixed32_.addInt(value);
-    }
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     * @param values The packedFixed32 to add.
-     */
-    private void addAllPackedFixed32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensurePackedFixed32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedFixed32_);
-    }
-    /**
-     * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-     */
-    private void clearPackedFixed32() {
-      packedFixed32_ = emptyIntList();
-    }
-
-    public static final int PACKED_FIXED64_FIELD_NUMBER = 97;
-    private com.google.protobuf.Internal.LongList packedFixed64_;
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @return A list containing the packedFixed64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getPackedFixed64List() {
-      return packedFixed64_;
-    }
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @return The count of packedFixed64.
-     */
-    @java.lang.Override
-    public int getPackedFixed64Count() {
-      return packedFixed64_.size();
-    }
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedFixed64 at the given index.
-     */
-    @java.lang.Override
-    public long getPackedFixed64(int index) {
-      return packedFixed64_.getLong(index);
-    }
-    private int packedFixed64MemoizedSerializedSize = -1;
-    private void ensurePackedFixed64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = packedFixed64_;
-      if (!tmp.isModifiable()) {
-        packedFixed64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedFixed64 to set.
-     */
-    private void setPackedFixed64(
-        int index, long value) {
-      ensurePackedFixed64IsMutable();
-      packedFixed64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param value The packedFixed64 to add.
-     */
-    private void addPackedFixed64(long value) {
-      ensurePackedFixed64IsMutable();
-      packedFixed64_.addLong(value);
-    }
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     * @param values The packedFixed64 to add.
-     */
-    private void addAllPackedFixed64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensurePackedFixed64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedFixed64_);
-    }
-    /**
-     * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-     */
-    private void clearPackedFixed64() {
-      packedFixed64_ = emptyLongList();
-    }
-
-    public static final int PACKED_SFIXED32_FIELD_NUMBER = 98;
-    private com.google.protobuf.Internal.IntList packedSfixed32_;
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @return A list containing the packedSfixed32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getPackedSfixed32List() {
-      return packedSfixed32_;
-    }
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @return The count of packedSfixed32.
-     */
-    @java.lang.Override
-    public int getPackedSfixed32Count() {
-      return packedSfixed32_.size();
-    }
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSfixed32 at the given index.
-     */
-    @java.lang.Override
-    public int getPackedSfixed32(int index) {
-      return packedSfixed32_.getInt(index);
-    }
-    private int packedSfixed32MemoizedSerializedSize = -1;
-    private void ensurePackedSfixed32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedSfixed32_;
-      if (!tmp.isModifiable()) {
-        packedSfixed32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSfixed32 to set.
-     */
-    private void setPackedSfixed32(
-        int index, int value) {
-      ensurePackedSfixed32IsMutable();
-      packedSfixed32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param value The packedSfixed32 to add.
-     */
-    private void addPackedSfixed32(int value) {
-      ensurePackedSfixed32IsMutable();
-      packedSfixed32_.addInt(value);
-    }
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     * @param values The packedSfixed32 to add.
-     */
-    private void addAllPackedSfixed32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensurePackedSfixed32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedSfixed32_);
-    }
-    /**
-     * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-     */
-    private void clearPackedSfixed32() {
-      packedSfixed32_ = emptyIntList();
-    }
-
-    public static final int PACKED_SFIXED64_FIELD_NUMBER = 99;
-    private com.google.protobuf.Internal.LongList packedSfixed64_;
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @return A list containing the packedSfixed64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getPackedSfixed64List() {
-      return packedSfixed64_;
-    }
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @return The count of packedSfixed64.
-     */
-    @java.lang.Override
-    public int getPackedSfixed64Count() {
-      return packedSfixed64_.size();
-    }
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedSfixed64 at the given index.
-     */
-    @java.lang.Override
-    public long getPackedSfixed64(int index) {
-      return packedSfixed64_.getLong(index);
-    }
-    private int packedSfixed64MemoizedSerializedSize = -1;
-    private void ensurePackedSfixed64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = packedSfixed64_;
-      if (!tmp.isModifiable()) {
-        packedSfixed64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedSfixed64 to set.
-     */
-    private void setPackedSfixed64(
-        int index, long value) {
-      ensurePackedSfixed64IsMutable();
-      packedSfixed64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param value The packedSfixed64 to add.
-     */
-    private void addPackedSfixed64(long value) {
-      ensurePackedSfixed64IsMutable();
-      packedSfixed64_.addLong(value);
-    }
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     * @param values The packedSfixed64 to add.
-     */
-    private void addAllPackedSfixed64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensurePackedSfixed64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedSfixed64_);
-    }
-    /**
-     * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-     */
-    private void clearPackedSfixed64() {
-      packedSfixed64_ = emptyLongList();
-    }
-
-    public static final int PACKED_FLOAT_FIELD_NUMBER = 100;
-    private com.google.protobuf.Internal.FloatList packedFloat_;
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @return A list containing the packedFloat.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Float>
-        getPackedFloatList() {
-      return packedFloat_;
-    }
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @return The count of packedFloat.
-     */
-    @java.lang.Override
-    public int getPackedFloatCount() {
-      return packedFloat_.size();
-    }
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedFloat at the given index.
-     */
-    @java.lang.Override
-    public float getPackedFloat(int index) {
-      return packedFloat_.getFloat(index);
-    }
-    private int packedFloatMemoizedSerializedSize = -1;
-    private void ensurePackedFloatIsMutable() {
-      com.google.protobuf.Internal.FloatList tmp = packedFloat_;
-      if (!tmp.isModifiable()) {
-        packedFloat_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedFloat to set.
-     */
-    private void setPackedFloat(
-        int index, float value) {
-      ensurePackedFloatIsMutable();
-      packedFloat_.setFloat(index, value);
-    }
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param value The packedFloat to add.
-     */
-    private void addPackedFloat(float value) {
-      ensurePackedFloatIsMutable();
-      packedFloat_.addFloat(value);
-    }
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     * @param values The packedFloat to add.
-     */
-    private void addAllPackedFloat(
-        java.lang.Iterable<? extends java.lang.Float> values) {
-      ensurePackedFloatIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedFloat_);
-    }
-    /**
-     * <code>repeated float packed_float = 100 [packed = true];</code>
-     */
-    private void clearPackedFloat() {
-      packedFloat_ = emptyFloatList();
-    }
-
-    public static final int PACKED_DOUBLE_FIELD_NUMBER = 101;
-    private com.google.protobuf.Internal.DoubleList packedDouble_;
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @return A list containing the packedDouble.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Double>
-        getPackedDoubleList() {
-      return packedDouble_;
-    }
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @return The count of packedDouble.
-     */
-    @java.lang.Override
-    public int getPackedDoubleCount() {
-      return packedDouble_.size();
-    }
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedDouble at the given index.
-     */
-    @java.lang.Override
-    public double getPackedDouble(int index) {
-      return packedDouble_.getDouble(index);
-    }
-    private int packedDoubleMemoizedSerializedSize = -1;
-    private void ensurePackedDoubleIsMutable() {
-      com.google.protobuf.Internal.DoubleList tmp = packedDouble_;
-      if (!tmp.isModifiable()) {
-        packedDouble_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedDouble to set.
-     */
-    private void setPackedDouble(
-        int index, double value) {
-      ensurePackedDoubleIsMutable();
-      packedDouble_.setDouble(index, value);
-    }
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param value The packedDouble to add.
-     */
-    private void addPackedDouble(double value) {
-      ensurePackedDoubleIsMutable();
-      packedDouble_.addDouble(value);
-    }
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     * @param values The packedDouble to add.
-     */
-    private void addAllPackedDouble(
-        java.lang.Iterable<? extends java.lang.Double> values) {
-      ensurePackedDoubleIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedDouble_);
-    }
-    /**
-     * <code>repeated double packed_double = 101 [packed = true];</code>
-     */
-    private void clearPackedDouble() {
-      packedDouble_ = emptyDoubleList();
-    }
-
-    public static final int PACKED_BOOL_FIELD_NUMBER = 102;
-    private com.google.protobuf.Internal.BooleanList packedBool_;
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @return A list containing the packedBool.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Boolean>
-        getPackedBoolList() {
-      return packedBool_;
-    }
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @return The count of packedBool.
-     */
-    @java.lang.Override
-    public int getPackedBoolCount() {
-      return packedBool_.size();
-    }
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedBool at the given index.
-     */
-    @java.lang.Override
-    public boolean getPackedBool(int index) {
-      return packedBool_.getBoolean(index);
-    }
-    private int packedBoolMemoizedSerializedSize = -1;
-    private void ensurePackedBoolIsMutable() {
-      com.google.protobuf.Internal.BooleanList tmp = packedBool_;
-      if (!tmp.isModifiable()) {
-        packedBool_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedBool to set.
-     */
-    private void setPackedBool(
-        int index, boolean value) {
-      ensurePackedBoolIsMutable();
-      packedBool_.setBoolean(index, value);
-    }
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param value The packedBool to add.
-     */
-    private void addPackedBool(boolean value) {
-      ensurePackedBoolIsMutable();
-      packedBool_.addBoolean(value);
-    }
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     * @param values The packedBool to add.
-     */
-    private void addAllPackedBool(
-        java.lang.Iterable<? extends java.lang.Boolean> values) {
-      ensurePackedBoolIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedBool_);
-    }
-    /**
-     * <code>repeated bool packed_bool = 102 [packed = true];</code>
-     */
-    private void clearPackedBool() {
-      packedBool_ = emptyBooleanList();
-    }
-
-    public static final int PACKED_ENUM_FIELD_NUMBER = 103;
-    private com.google.protobuf.Internal.IntList packedEnum_;
-    private static final com.google.protobuf.Internal.ListAdapter.Converter<
-        java.lang.Integer, protobuf_unittest.UnittestProto.ForeignEnum> packedEnum_converter_ =
-            new com.google.protobuf.Internal.ListAdapter.Converter<
-                java.lang.Integer, protobuf_unittest.UnittestProto.ForeignEnum>() {
-              @java.lang.Override
-              public protobuf_unittest.UnittestProto.ForeignEnum convert(java.lang.Integer from) {
-                protobuf_unittest.UnittestProto.ForeignEnum result = protobuf_unittest.UnittestProto.ForeignEnum.forNumber(from);
-                return result == null ? protobuf_unittest.UnittestProto.ForeignEnum.FOREIGN_FOO : result;
-              }
-            };
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @return A list containing the packedEnum.
-     */
-    @java.lang.Override
-    public java.util.List<protobuf_unittest.UnittestProto.ForeignEnum> getPackedEnumList() {
-      return new com.google.protobuf.Internal.ListAdapter<
-          java.lang.Integer, protobuf_unittest.UnittestProto.ForeignEnum>(packedEnum_, packedEnum_converter_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @return The count of packedEnum.
-     */
-    @java.lang.Override
-    public int getPackedEnumCount() {
-      return packedEnum_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedEnum at the given index.
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.ForeignEnum getPackedEnum(int index) {
-      return packedEnum_converter_.convert(packedEnum_.getInt(index));
-    }
-    private int packedEnumMemoizedSerializedSize;
-    private void ensurePackedEnumIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedEnum_;
-      if (!tmp.isModifiable()) {
-        packedEnum_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedEnum to set.
-     */
-    private void setPackedEnum(
-        int index, protobuf_unittest.UnittestProto.ForeignEnum value) {
-      value.getClass();
-  ensurePackedEnumIsMutable();
-      packedEnum_.setInt(index, value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param value The packedEnum to add.
-     */
-    private void addPackedEnum(protobuf_unittest.UnittestProto.ForeignEnum value) {
-      value.getClass();
-  ensurePackedEnumIsMutable();
-      packedEnum_.addInt(value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     * @param values The packedEnum to add.
-     */
-    private void addAllPackedEnum(
-        java.lang.Iterable<? extends protobuf_unittest.UnittestProto.ForeignEnum> values) {
-      ensurePackedEnumIsMutable();
-      for (protobuf_unittest.UnittestProto.ForeignEnum value : values) {
-        packedEnum_.addInt(value.getNumber());
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-     */
-    private void clearPackedEnum() {
-      packedEnum_ = emptyIntList();
-    }
-
-    public static protobuf_unittest.UnittestProto.TestPackedTypes parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedTypes parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedTypes parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedTypes parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedTypes parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedTypes parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedTypes parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedTypes parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedTypes parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedTypes parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedTypes parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedTypes parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestPackedTypes prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestPackedTypes}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestPackedTypes, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestPackedTypes)
-        protobuf_unittest.UnittestProto.TestPackedTypesOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestPackedTypes.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @return A list containing the packedInt32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getPackedInt32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedInt32List());
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @return The count of packedInt32.
-       */
-      @java.lang.Override
-      public int getPackedInt32Count() {
-        return instance.getPackedInt32Count();
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedInt32 at the given index.
-       */
-      @java.lang.Override
-      public int getPackedInt32(int index) {
-        return instance.getPackedInt32(index);
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @param value The packedInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedInt32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setPackedInt32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @param value The packedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedInt32(int value) {
-        copyOnWrite();
-        instance.addPackedInt32(value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @param values The packedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedInt32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllPackedInt32(values);
-        return this;
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 90 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedInt32() {
-        copyOnWrite();
-        instance.clearPackedInt32();
-        return this;
-      }
-
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @return A list containing the packedInt64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getPackedInt64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedInt64List());
-      }
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @return The count of packedInt64.
-       */
-      @java.lang.Override
-      public int getPackedInt64Count() {
-        return instance.getPackedInt64Count();
-      }
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedInt64 at the given index.
-       */
-      @java.lang.Override
-      public long getPackedInt64(int index) {
-        return instance.getPackedInt64(index);
-      }
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @param value The packedInt64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedInt64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setPackedInt64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @param value The packedInt64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedInt64(long value) {
-        copyOnWrite();
-        instance.addPackedInt64(value);
-        return this;
-      }
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @param values The packedInt64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedInt64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllPackedInt64(values);
-        return this;
-      }
-      /**
-       * <code>repeated int64 packed_int64 = 91 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedInt64() {
-        copyOnWrite();
-        instance.clearPackedInt64();
-        return this;
-      }
-
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @return A list containing the packedUint32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getPackedUint32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedUint32List());
-      }
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @return The count of packedUint32.
-       */
-      @java.lang.Override
-      public int getPackedUint32Count() {
-        return instance.getPackedUint32Count();
-      }
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedUint32 at the given index.
-       */
-      @java.lang.Override
-      public int getPackedUint32(int index) {
-        return instance.getPackedUint32(index);
-      }
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @param value The packedUint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedUint32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setPackedUint32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @param value The packedUint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedUint32(int value) {
-        copyOnWrite();
-        instance.addPackedUint32(value);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @param values The packedUint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedUint32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllPackedUint32(values);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 packed_uint32 = 92 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedUint32() {
-        copyOnWrite();
-        instance.clearPackedUint32();
-        return this;
-      }
-
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @return A list containing the packedUint64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getPackedUint64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedUint64List());
-      }
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @return The count of packedUint64.
-       */
-      @java.lang.Override
-      public int getPackedUint64Count() {
-        return instance.getPackedUint64Count();
-      }
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedUint64 at the given index.
-       */
-      @java.lang.Override
-      public long getPackedUint64(int index) {
-        return instance.getPackedUint64(index);
-      }
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @param value The packedUint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedUint64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setPackedUint64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @param value The packedUint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedUint64(long value) {
-        copyOnWrite();
-        instance.addPackedUint64(value);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @param values The packedUint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedUint64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllPackedUint64(values);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 packed_uint64 = 93 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedUint64() {
-        copyOnWrite();
-        instance.clearPackedUint64();
-        return this;
-      }
-
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @return A list containing the packedSint32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getPackedSint32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedSint32List());
-      }
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @return The count of packedSint32.
-       */
-      @java.lang.Override
-      public int getPackedSint32Count() {
-        return instance.getPackedSint32Count();
-      }
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedSint32 at the given index.
-       */
-      @java.lang.Override
-      public int getPackedSint32(int index) {
-        return instance.getPackedSint32(index);
-      }
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @param value The packedSint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedSint32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setPackedSint32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @param value The packedSint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedSint32(int value) {
-        copyOnWrite();
-        instance.addPackedSint32(value);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @param values The packedSint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedSint32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllPackedSint32(values);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 packed_sint32 = 94 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedSint32() {
-        copyOnWrite();
-        instance.clearPackedSint32();
-        return this;
-      }
-
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @return A list containing the packedSint64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getPackedSint64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedSint64List());
-      }
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @return The count of packedSint64.
-       */
-      @java.lang.Override
-      public int getPackedSint64Count() {
-        return instance.getPackedSint64Count();
-      }
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedSint64 at the given index.
-       */
-      @java.lang.Override
-      public long getPackedSint64(int index) {
-        return instance.getPackedSint64(index);
-      }
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @param value The packedSint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedSint64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setPackedSint64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @param value The packedSint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedSint64(long value) {
-        copyOnWrite();
-        instance.addPackedSint64(value);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @param values The packedSint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedSint64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllPackedSint64(values);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 packed_sint64 = 95 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedSint64() {
-        copyOnWrite();
-        instance.clearPackedSint64();
-        return this;
-      }
-
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @return A list containing the packedFixed32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getPackedFixed32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedFixed32List());
-      }
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @return The count of packedFixed32.
-       */
-      @java.lang.Override
-      public int getPackedFixed32Count() {
-        return instance.getPackedFixed32Count();
-      }
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedFixed32 at the given index.
-       */
-      @java.lang.Override
-      public int getPackedFixed32(int index) {
-        return instance.getPackedFixed32(index);
-      }
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @param value The packedFixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedFixed32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setPackedFixed32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @param value The packedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedFixed32(int value) {
-        copyOnWrite();
-        instance.addPackedFixed32(value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @param values The packedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedFixed32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllPackedFixed32(values);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 packed_fixed32 = 96 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedFixed32() {
-        copyOnWrite();
-        instance.clearPackedFixed32();
-        return this;
-      }
-
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @return A list containing the packedFixed64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getPackedFixed64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedFixed64List());
-      }
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @return The count of packedFixed64.
-       */
-      @java.lang.Override
-      public int getPackedFixed64Count() {
-        return instance.getPackedFixed64Count();
-      }
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedFixed64 at the given index.
-       */
-      @java.lang.Override
-      public long getPackedFixed64(int index) {
-        return instance.getPackedFixed64(index);
-      }
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @param value The packedFixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedFixed64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setPackedFixed64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @param value The packedFixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedFixed64(long value) {
-        copyOnWrite();
-        instance.addPackedFixed64(value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @param values The packedFixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedFixed64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllPackedFixed64(values);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 packed_fixed64 = 97 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedFixed64() {
-        copyOnWrite();
-        instance.clearPackedFixed64();
-        return this;
-      }
-
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @return A list containing the packedSfixed32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getPackedSfixed32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedSfixed32List());
-      }
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @return The count of packedSfixed32.
-       */
-      @java.lang.Override
-      public int getPackedSfixed32Count() {
-        return instance.getPackedSfixed32Count();
-      }
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedSfixed32 at the given index.
-       */
-      @java.lang.Override
-      public int getPackedSfixed32(int index) {
-        return instance.getPackedSfixed32(index);
-      }
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @param value The packedSfixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedSfixed32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setPackedSfixed32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @param value The packedSfixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedSfixed32(int value) {
-        copyOnWrite();
-        instance.addPackedSfixed32(value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @param values The packedSfixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedSfixed32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllPackedSfixed32(values);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 packed_sfixed32 = 98 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedSfixed32() {
-        copyOnWrite();
-        instance.clearPackedSfixed32();
-        return this;
-      }
-
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @return A list containing the packedSfixed64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getPackedSfixed64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedSfixed64List());
-      }
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @return The count of packedSfixed64.
-       */
-      @java.lang.Override
-      public int getPackedSfixed64Count() {
-        return instance.getPackedSfixed64Count();
-      }
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedSfixed64 at the given index.
-       */
-      @java.lang.Override
-      public long getPackedSfixed64(int index) {
-        return instance.getPackedSfixed64(index);
-      }
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @param value The packedSfixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedSfixed64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setPackedSfixed64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @param value The packedSfixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedSfixed64(long value) {
-        copyOnWrite();
-        instance.addPackedSfixed64(value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @param values The packedSfixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedSfixed64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllPackedSfixed64(values);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 packed_sfixed64 = 99 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedSfixed64() {
-        copyOnWrite();
-        instance.clearPackedSfixed64();
-        return this;
-      }
-
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @return A list containing the packedFloat.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Float>
-          getPackedFloatList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedFloatList());
-      }
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @return The count of packedFloat.
-       */
-      @java.lang.Override
-      public int getPackedFloatCount() {
-        return instance.getPackedFloatCount();
-      }
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedFloat at the given index.
-       */
-      @java.lang.Override
-      public float getPackedFloat(int index) {
-        return instance.getPackedFloat(index);
-      }
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @param value The packedFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedFloat(
-          int index, float value) {
-        copyOnWrite();
-        instance.setPackedFloat(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @param value The packedFloat to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedFloat(float value) {
-        copyOnWrite();
-        instance.addPackedFloat(value);
-        return this;
-      }
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @param values The packedFloat to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedFloat(
-          java.lang.Iterable<? extends java.lang.Float> values) {
-        copyOnWrite();
-        instance.addAllPackedFloat(values);
-        return this;
-      }
-      /**
-       * <code>repeated float packed_float = 100 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedFloat() {
-        copyOnWrite();
-        instance.clearPackedFloat();
-        return this;
-      }
-
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @return A list containing the packedDouble.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Double>
-          getPackedDoubleList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedDoubleList());
-      }
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @return The count of packedDouble.
-       */
-      @java.lang.Override
-      public int getPackedDoubleCount() {
-        return instance.getPackedDoubleCount();
-      }
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedDouble at the given index.
-       */
-      @java.lang.Override
-      public double getPackedDouble(int index) {
-        return instance.getPackedDouble(index);
-      }
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @param value The packedDouble to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedDouble(
-          int index, double value) {
-        copyOnWrite();
-        instance.setPackedDouble(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @param value The packedDouble to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedDouble(double value) {
-        copyOnWrite();
-        instance.addPackedDouble(value);
-        return this;
-      }
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @param values The packedDouble to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedDouble(
-          java.lang.Iterable<? extends java.lang.Double> values) {
-        copyOnWrite();
-        instance.addAllPackedDouble(values);
-        return this;
-      }
-      /**
-       * <code>repeated double packed_double = 101 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedDouble() {
-        copyOnWrite();
-        instance.clearPackedDouble();
-        return this;
-      }
-
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @return A list containing the packedBool.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Boolean>
-          getPackedBoolList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedBoolList());
-      }
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @return The count of packedBool.
-       */
-      @java.lang.Override
-      public int getPackedBoolCount() {
-        return instance.getPackedBoolCount();
-      }
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedBool at the given index.
-       */
-      @java.lang.Override
-      public boolean getPackedBool(int index) {
-        return instance.getPackedBool(index);
-      }
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @param value The packedBool to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedBool(
-          int index, boolean value) {
-        copyOnWrite();
-        instance.setPackedBool(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @param value The packedBool to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedBool(boolean value) {
-        copyOnWrite();
-        instance.addPackedBool(value);
-        return this;
-      }
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @param values The packedBool to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedBool(
-          java.lang.Iterable<? extends java.lang.Boolean> values) {
-        copyOnWrite();
-        instance.addAllPackedBool(values);
-        return this;
-      }
-      /**
-       * <code>repeated bool packed_bool = 102 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedBool() {
-        copyOnWrite();
-        instance.clearPackedBool();
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-       * @return A list containing the packedEnum.
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.ForeignEnum> getPackedEnumList() {
-        return instance.getPackedEnumList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-       * @return The count of packedEnum.
-       */
-      @java.lang.Override
-      public int getPackedEnumCount() {
-        return instance.getPackedEnumCount();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedEnum at the given index.
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.ForeignEnum getPackedEnum(int index) {
-        return instance.getPackedEnum(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-       * @param index The index to set the value at.
-       * @param value The packedEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedEnum(
-          int index, protobuf_unittest.UnittestProto.ForeignEnum value) {
-        copyOnWrite();
-        instance.setPackedEnum(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-       * @param value The packedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedEnum(protobuf_unittest.UnittestProto.ForeignEnum value) {
-        copyOnWrite();
-        instance.addPackedEnum(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-       * @param values The packedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedEnum(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.ForeignEnum> values) {
-        copyOnWrite();
-        instance.addAllPackedEnum(values);  return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum packed_enum = 103 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedEnum() {
-        copyOnWrite();
-        instance.clearPackedEnum();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestPackedTypes)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestPackedTypes();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "packedInt32_",
-              "packedInt64_",
-              "packedUint32_",
-              "packedUint64_",
-              "packedSint32_",
-              "packedSint64_",
-              "packedFixed32_",
-              "packedFixed64_",
-              "packedSfixed32_",
-              "packedSfixed64_",
-              "packedFloat_",
-              "packedDouble_",
-              "packedBool_",
-              "packedEnum_",
-              protobuf_unittest.UnittestProto.ForeignEnum.internalGetVerifier(),
-            };
-            java.lang.String info =
-                "\u0001\u000e\u0000\u0000Zg\u000e\u0000\u000e\u0000Z\'[%\\+]&^/_0`)a(b-c.d$e#f*g," +
-                "";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestPackedTypes> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestPackedTypes.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestPackedTypes>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestPackedTypes)
-    private static final protobuf_unittest.UnittestProto.TestPackedTypes DEFAULT_INSTANCE;
-    static {
-      TestPackedTypes defaultInstance = new TestPackedTypes();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestPackedTypes.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestPackedTypes getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestPackedTypes> PARSER;
-
-    public static com.google.protobuf.Parser<TestPackedTypes> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestUnpackedTypesOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestUnpackedTypes)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>repeated int32 unpacked_int32 = 90 [packed = false];</code>
-     * @return A list containing the unpackedInt32.
-     */
-    java.util.List<java.lang.Integer> getUnpackedInt32List();
-    /**
-     * <code>repeated int32 unpacked_int32 = 90 [packed = false];</code>
-     * @return The count of unpackedInt32.
-     */
-    int getUnpackedInt32Count();
-    /**
-     * <code>repeated int32 unpacked_int32 = 90 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedInt32 at the given index.
-     */
-    int getUnpackedInt32(int index);
-
-    /**
-     * <code>repeated int64 unpacked_int64 = 91 [packed = false];</code>
-     * @return A list containing the unpackedInt64.
-     */
-    java.util.List<java.lang.Long> getUnpackedInt64List();
-    /**
-     * <code>repeated int64 unpacked_int64 = 91 [packed = false];</code>
-     * @return The count of unpackedInt64.
-     */
-    int getUnpackedInt64Count();
-    /**
-     * <code>repeated int64 unpacked_int64 = 91 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedInt64 at the given index.
-     */
-    long getUnpackedInt64(int index);
-
-    /**
-     * <code>repeated uint32 unpacked_uint32 = 92 [packed = false];</code>
-     * @return A list containing the unpackedUint32.
-     */
-    java.util.List<java.lang.Integer> getUnpackedUint32List();
-    /**
-     * <code>repeated uint32 unpacked_uint32 = 92 [packed = false];</code>
-     * @return The count of unpackedUint32.
-     */
-    int getUnpackedUint32Count();
-    /**
-     * <code>repeated uint32 unpacked_uint32 = 92 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedUint32 at the given index.
-     */
-    int getUnpackedUint32(int index);
-
-    /**
-     * <code>repeated uint64 unpacked_uint64 = 93 [packed = false];</code>
-     * @return A list containing the unpackedUint64.
-     */
-    java.util.List<java.lang.Long> getUnpackedUint64List();
-    /**
-     * <code>repeated uint64 unpacked_uint64 = 93 [packed = false];</code>
-     * @return The count of unpackedUint64.
-     */
-    int getUnpackedUint64Count();
-    /**
-     * <code>repeated uint64 unpacked_uint64 = 93 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedUint64 at the given index.
-     */
-    long getUnpackedUint64(int index);
-
-    /**
-     * <code>repeated sint32 unpacked_sint32 = 94 [packed = false];</code>
-     * @return A list containing the unpackedSint32.
-     */
-    java.util.List<java.lang.Integer> getUnpackedSint32List();
-    /**
-     * <code>repeated sint32 unpacked_sint32 = 94 [packed = false];</code>
-     * @return The count of unpackedSint32.
-     */
-    int getUnpackedSint32Count();
-    /**
-     * <code>repeated sint32 unpacked_sint32 = 94 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedSint32 at the given index.
-     */
-    int getUnpackedSint32(int index);
-
-    /**
-     * <code>repeated sint64 unpacked_sint64 = 95 [packed = false];</code>
-     * @return A list containing the unpackedSint64.
-     */
-    java.util.List<java.lang.Long> getUnpackedSint64List();
-    /**
-     * <code>repeated sint64 unpacked_sint64 = 95 [packed = false];</code>
-     * @return The count of unpackedSint64.
-     */
-    int getUnpackedSint64Count();
-    /**
-     * <code>repeated sint64 unpacked_sint64 = 95 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedSint64 at the given index.
-     */
-    long getUnpackedSint64(int index);
-
-    /**
-     * <code>repeated fixed32 unpacked_fixed32 = 96 [packed = false];</code>
-     * @return A list containing the unpackedFixed32.
-     */
-    java.util.List<java.lang.Integer> getUnpackedFixed32List();
-    /**
-     * <code>repeated fixed32 unpacked_fixed32 = 96 [packed = false];</code>
-     * @return The count of unpackedFixed32.
-     */
-    int getUnpackedFixed32Count();
-    /**
-     * <code>repeated fixed32 unpacked_fixed32 = 96 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedFixed32 at the given index.
-     */
-    int getUnpackedFixed32(int index);
-
-    /**
-     * <code>repeated fixed64 unpacked_fixed64 = 97 [packed = false];</code>
-     * @return A list containing the unpackedFixed64.
-     */
-    java.util.List<java.lang.Long> getUnpackedFixed64List();
-    /**
-     * <code>repeated fixed64 unpacked_fixed64 = 97 [packed = false];</code>
-     * @return The count of unpackedFixed64.
-     */
-    int getUnpackedFixed64Count();
-    /**
-     * <code>repeated fixed64 unpacked_fixed64 = 97 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedFixed64 at the given index.
-     */
-    long getUnpackedFixed64(int index);
-
-    /**
-     * <code>repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];</code>
-     * @return A list containing the unpackedSfixed32.
-     */
-    java.util.List<java.lang.Integer> getUnpackedSfixed32List();
-    /**
-     * <code>repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];</code>
-     * @return The count of unpackedSfixed32.
-     */
-    int getUnpackedSfixed32Count();
-    /**
-     * <code>repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedSfixed32 at the given index.
-     */
-    int getUnpackedSfixed32(int index);
-
-    /**
-     * <code>repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];</code>
-     * @return A list containing the unpackedSfixed64.
-     */
-    java.util.List<java.lang.Long> getUnpackedSfixed64List();
-    /**
-     * <code>repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];</code>
-     * @return The count of unpackedSfixed64.
-     */
-    int getUnpackedSfixed64Count();
-    /**
-     * <code>repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedSfixed64 at the given index.
-     */
-    long getUnpackedSfixed64(int index);
-
-    /**
-     * <code>repeated float unpacked_float = 100 [packed = false];</code>
-     * @return A list containing the unpackedFloat.
-     */
-    java.util.List<java.lang.Float> getUnpackedFloatList();
-    /**
-     * <code>repeated float unpacked_float = 100 [packed = false];</code>
-     * @return The count of unpackedFloat.
-     */
-    int getUnpackedFloatCount();
-    /**
-     * <code>repeated float unpacked_float = 100 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedFloat at the given index.
-     */
-    float getUnpackedFloat(int index);
-
-    /**
-     * <code>repeated double unpacked_double = 101 [packed = false];</code>
-     * @return A list containing the unpackedDouble.
-     */
-    java.util.List<java.lang.Double> getUnpackedDoubleList();
-    /**
-     * <code>repeated double unpacked_double = 101 [packed = false];</code>
-     * @return The count of unpackedDouble.
-     */
-    int getUnpackedDoubleCount();
-    /**
-     * <code>repeated double unpacked_double = 101 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedDouble at the given index.
-     */
-    double getUnpackedDouble(int index);
-
-    /**
-     * <code>repeated bool unpacked_bool = 102 [packed = false];</code>
-     * @return A list containing the unpackedBool.
-     */
-    java.util.List<java.lang.Boolean> getUnpackedBoolList();
-    /**
-     * <code>repeated bool unpacked_bool = 102 [packed = false];</code>
-     * @return The count of unpackedBool.
-     */
-    int getUnpackedBoolCount();
-    /**
-     * <code>repeated bool unpacked_bool = 102 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedBool at the given index.
-     */
-    boolean getUnpackedBool(int index);
-
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum unpacked_enum = 103 [packed = false];</code>
-     * @return A list containing the unpackedEnum.
-     */
-    java.util.List<protobuf_unittest.UnittestProto.ForeignEnum> getUnpackedEnumList();
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum unpacked_enum = 103 [packed = false];</code>
-     * @return The count of unpackedEnum.
-     */
-    int getUnpackedEnumCount();
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum unpacked_enum = 103 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedEnum at the given index.
-     */
-    protobuf_unittest.UnittestProto.ForeignEnum getUnpackedEnum(int index);
-  }
-  /**
-   * <pre>
-   * A message with the same fields as TestPackedTypes, but without packing. Used
-   * to test packed &lt;-&gt; unpacked wire compatibility.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestUnpackedTypes}
-   */
-  public  static final class TestUnpackedTypes extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestUnpackedTypes, TestUnpackedTypes.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestUnpackedTypes)
-      TestUnpackedTypesOrBuilder {
-    private TestUnpackedTypes() {
-      unpackedInt32_ = emptyIntList();
-      unpackedInt64_ = emptyLongList();
-      unpackedUint32_ = emptyIntList();
-      unpackedUint64_ = emptyLongList();
-      unpackedSint32_ = emptyIntList();
-      unpackedSint64_ = emptyLongList();
-      unpackedFixed32_ = emptyIntList();
-      unpackedFixed64_ = emptyLongList();
-      unpackedSfixed32_ = emptyIntList();
-      unpackedSfixed64_ = emptyLongList();
-      unpackedFloat_ = emptyFloatList();
-      unpackedDouble_ = emptyDoubleList();
-      unpackedBool_ = emptyBooleanList();
-      unpackedEnum_ = emptyIntList();
-    }
-    public static final int UNPACKED_INT32_FIELD_NUMBER = 90;
-    private com.google.protobuf.Internal.IntList unpackedInt32_;
-    /**
-     * <code>repeated int32 unpacked_int32 = 90 [packed = false];</code>
-     * @return A list containing the unpackedInt32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getUnpackedInt32List() {
-      return unpackedInt32_;
-    }
-    /**
-     * <code>repeated int32 unpacked_int32 = 90 [packed = false];</code>
-     * @return The count of unpackedInt32.
-     */
-    @java.lang.Override
-    public int getUnpackedInt32Count() {
-      return unpackedInt32_.size();
-    }
-    /**
-     * <code>repeated int32 unpacked_int32 = 90 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedInt32 at the given index.
-     */
-    @java.lang.Override
-    public int getUnpackedInt32(int index) {
-      return unpackedInt32_.getInt(index);
-    }
-    private void ensureUnpackedInt32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = unpackedInt32_;
-      if (!tmp.isModifiable()) {
-        unpackedInt32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int32 unpacked_int32 = 90 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The unpackedInt32 to set.
-     */
-    private void setUnpackedInt32(
-        int index, int value) {
-      ensureUnpackedInt32IsMutable();
-      unpackedInt32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated int32 unpacked_int32 = 90 [packed = false];</code>
-     * @param value The unpackedInt32 to add.
-     */
-    private void addUnpackedInt32(int value) {
-      ensureUnpackedInt32IsMutable();
-      unpackedInt32_.addInt(value);
-    }
-    /**
-     * <code>repeated int32 unpacked_int32 = 90 [packed = false];</code>
-     * @param values The unpackedInt32 to add.
-     */
-    private void addAllUnpackedInt32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureUnpackedInt32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, unpackedInt32_);
-    }
-    /**
-     * <code>repeated int32 unpacked_int32 = 90 [packed = false];</code>
-     */
-    private void clearUnpackedInt32() {
-      unpackedInt32_ = emptyIntList();
-    }
-
-    public static final int UNPACKED_INT64_FIELD_NUMBER = 91;
-    private com.google.protobuf.Internal.LongList unpackedInt64_;
-    /**
-     * <code>repeated int64 unpacked_int64 = 91 [packed = false];</code>
-     * @return A list containing the unpackedInt64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getUnpackedInt64List() {
-      return unpackedInt64_;
-    }
-    /**
-     * <code>repeated int64 unpacked_int64 = 91 [packed = false];</code>
-     * @return The count of unpackedInt64.
-     */
-    @java.lang.Override
-    public int getUnpackedInt64Count() {
-      return unpackedInt64_.size();
-    }
-    /**
-     * <code>repeated int64 unpacked_int64 = 91 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedInt64 at the given index.
-     */
-    @java.lang.Override
-    public long getUnpackedInt64(int index) {
-      return unpackedInt64_.getLong(index);
-    }
-    private void ensureUnpackedInt64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = unpackedInt64_;
-      if (!tmp.isModifiable()) {
-        unpackedInt64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int64 unpacked_int64 = 91 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The unpackedInt64 to set.
-     */
-    private void setUnpackedInt64(
-        int index, long value) {
-      ensureUnpackedInt64IsMutable();
-      unpackedInt64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated int64 unpacked_int64 = 91 [packed = false];</code>
-     * @param value The unpackedInt64 to add.
-     */
-    private void addUnpackedInt64(long value) {
-      ensureUnpackedInt64IsMutable();
-      unpackedInt64_.addLong(value);
-    }
-    /**
-     * <code>repeated int64 unpacked_int64 = 91 [packed = false];</code>
-     * @param values The unpackedInt64 to add.
-     */
-    private void addAllUnpackedInt64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureUnpackedInt64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, unpackedInt64_);
-    }
-    /**
-     * <code>repeated int64 unpacked_int64 = 91 [packed = false];</code>
-     */
-    private void clearUnpackedInt64() {
-      unpackedInt64_ = emptyLongList();
-    }
-
-    public static final int UNPACKED_UINT32_FIELD_NUMBER = 92;
-    private com.google.protobuf.Internal.IntList unpackedUint32_;
-    /**
-     * <code>repeated uint32 unpacked_uint32 = 92 [packed = false];</code>
-     * @return A list containing the unpackedUint32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getUnpackedUint32List() {
-      return unpackedUint32_;
-    }
-    /**
-     * <code>repeated uint32 unpacked_uint32 = 92 [packed = false];</code>
-     * @return The count of unpackedUint32.
-     */
-    @java.lang.Override
-    public int getUnpackedUint32Count() {
-      return unpackedUint32_.size();
-    }
-    /**
-     * <code>repeated uint32 unpacked_uint32 = 92 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedUint32 at the given index.
-     */
-    @java.lang.Override
-    public int getUnpackedUint32(int index) {
-      return unpackedUint32_.getInt(index);
-    }
-    private void ensureUnpackedUint32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = unpackedUint32_;
-      if (!tmp.isModifiable()) {
-        unpackedUint32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated uint32 unpacked_uint32 = 92 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The unpackedUint32 to set.
-     */
-    private void setUnpackedUint32(
-        int index, int value) {
-      ensureUnpackedUint32IsMutable();
-      unpackedUint32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated uint32 unpacked_uint32 = 92 [packed = false];</code>
-     * @param value The unpackedUint32 to add.
-     */
-    private void addUnpackedUint32(int value) {
-      ensureUnpackedUint32IsMutable();
-      unpackedUint32_.addInt(value);
-    }
-    /**
-     * <code>repeated uint32 unpacked_uint32 = 92 [packed = false];</code>
-     * @param values The unpackedUint32 to add.
-     */
-    private void addAllUnpackedUint32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureUnpackedUint32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, unpackedUint32_);
-    }
-    /**
-     * <code>repeated uint32 unpacked_uint32 = 92 [packed = false];</code>
-     */
-    private void clearUnpackedUint32() {
-      unpackedUint32_ = emptyIntList();
-    }
-
-    public static final int UNPACKED_UINT64_FIELD_NUMBER = 93;
-    private com.google.protobuf.Internal.LongList unpackedUint64_;
-    /**
-     * <code>repeated uint64 unpacked_uint64 = 93 [packed = false];</code>
-     * @return A list containing the unpackedUint64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getUnpackedUint64List() {
-      return unpackedUint64_;
-    }
-    /**
-     * <code>repeated uint64 unpacked_uint64 = 93 [packed = false];</code>
-     * @return The count of unpackedUint64.
-     */
-    @java.lang.Override
-    public int getUnpackedUint64Count() {
-      return unpackedUint64_.size();
-    }
-    /**
-     * <code>repeated uint64 unpacked_uint64 = 93 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedUint64 at the given index.
-     */
-    @java.lang.Override
-    public long getUnpackedUint64(int index) {
-      return unpackedUint64_.getLong(index);
-    }
-    private void ensureUnpackedUint64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = unpackedUint64_;
-      if (!tmp.isModifiable()) {
-        unpackedUint64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated uint64 unpacked_uint64 = 93 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The unpackedUint64 to set.
-     */
-    private void setUnpackedUint64(
-        int index, long value) {
-      ensureUnpackedUint64IsMutable();
-      unpackedUint64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated uint64 unpacked_uint64 = 93 [packed = false];</code>
-     * @param value The unpackedUint64 to add.
-     */
-    private void addUnpackedUint64(long value) {
-      ensureUnpackedUint64IsMutable();
-      unpackedUint64_.addLong(value);
-    }
-    /**
-     * <code>repeated uint64 unpacked_uint64 = 93 [packed = false];</code>
-     * @param values The unpackedUint64 to add.
-     */
-    private void addAllUnpackedUint64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureUnpackedUint64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, unpackedUint64_);
-    }
-    /**
-     * <code>repeated uint64 unpacked_uint64 = 93 [packed = false];</code>
-     */
-    private void clearUnpackedUint64() {
-      unpackedUint64_ = emptyLongList();
-    }
-
-    public static final int UNPACKED_SINT32_FIELD_NUMBER = 94;
-    private com.google.protobuf.Internal.IntList unpackedSint32_;
-    /**
-     * <code>repeated sint32 unpacked_sint32 = 94 [packed = false];</code>
-     * @return A list containing the unpackedSint32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getUnpackedSint32List() {
-      return unpackedSint32_;
-    }
-    /**
-     * <code>repeated sint32 unpacked_sint32 = 94 [packed = false];</code>
-     * @return The count of unpackedSint32.
-     */
-    @java.lang.Override
-    public int getUnpackedSint32Count() {
-      return unpackedSint32_.size();
-    }
-    /**
-     * <code>repeated sint32 unpacked_sint32 = 94 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedSint32 at the given index.
-     */
-    @java.lang.Override
-    public int getUnpackedSint32(int index) {
-      return unpackedSint32_.getInt(index);
-    }
-    private void ensureUnpackedSint32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = unpackedSint32_;
-      if (!tmp.isModifiable()) {
-        unpackedSint32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sint32 unpacked_sint32 = 94 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The unpackedSint32 to set.
-     */
-    private void setUnpackedSint32(
-        int index, int value) {
-      ensureUnpackedSint32IsMutable();
-      unpackedSint32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated sint32 unpacked_sint32 = 94 [packed = false];</code>
-     * @param value The unpackedSint32 to add.
-     */
-    private void addUnpackedSint32(int value) {
-      ensureUnpackedSint32IsMutable();
-      unpackedSint32_.addInt(value);
-    }
-    /**
-     * <code>repeated sint32 unpacked_sint32 = 94 [packed = false];</code>
-     * @param values The unpackedSint32 to add.
-     */
-    private void addAllUnpackedSint32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureUnpackedSint32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, unpackedSint32_);
-    }
-    /**
-     * <code>repeated sint32 unpacked_sint32 = 94 [packed = false];</code>
-     */
-    private void clearUnpackedSint32() {
-      unpackedSint32_ = emptyIntList();
-    }
-
-    public static final int UNPACKED_SINT64_FIELD_NUMBER = 95;
-    private com.google.protobuf.Internal.LongList unpackedSint64_;
-    /**
-     * <code>repeated sint64 unpacked_sint64 = 95 [packed = false];</code>
-     * @return A list containing the unpackedSint64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getUnpackedSint64List() {
-      return unpackedSint64_;
-    }
-    /**
-     * <code>repeated sint64 unpacked_sint64 = 95 [packed = false];</code>
-     * @return The count of unpackedSint64.
-     */
-    @java.lang.Override
-    public int getUnpackedSint64Count() {
-      return unpackedSint64_.size();
-    }
-    /**
-     * <code>repeated sint64 unpacked_sint64 = 95 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedSint64 at the given index.
-     */
-    @java.lang.Override
-    public long getUnpackedSint64(int index) {
-      return unpackedSint64_.getLong(index);
-    }
-    private void ensureUnpackedSint64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = unpackedSint64_;
-      if (!tmp.isModifiable()) {
-        unpackedSint64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sint64 unpacked_sint64 = 95 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The unpackedSint64 to set.
-     */
-    private void setUnpackedSint64(
-        int index, long value) {
-      ensureUnpackedSint64IsMutable();
-      unpackedSint64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated sint64 unpacked_sint64 = 95 [packed = false];</code>
-     * @param value The unpackedSint64 to add.
-     */
-    private void addUnpackedSint64(long value) {
-      ensureUnpackedSint64IsMutable();
-      unpackedSint64_.addLong(value);
-    }
-    /**
-     * <code>repeated sint64 unpacked_sint64 = 95 [packed = false];</code>
-     * @param values The unpackedSint64 to add.
-     */
-    private void addAllUnpackedSint64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureUnpackedSint64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, unpackedSint64_);
-    }
-    /**
-     * <code>repeated sint64 unpacked_sint64 = 95 [packed = false];</code>
-     */
-    private void clearUnpackedSint64() {
-      unpackedSint64_ = emptyLongList();
-    }
-
-    public static final int UNPACKED_FIXED32_FIELD_NUMBER = 96;
-    private com.google.protobuf.Internal.IntList unpackedFixed32_;
-    /**
-     * <code>repeated fixed32 unpacked_fixed32 = 96 [packed = false];</code>
-     * @return A list containing the unpackedFixed32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getUnpackedFixed32List() {
-      return unpackedFixed32_;
-    }
-    /**
-     * <code>repeated fixed32 unpacked_fixed32 = 96 [packed = false];</code>
-     * @return The count of unpackedFixed32.
-     */
-    @java.lang.Override
-    public int getUnpackedFixed32Count() {
-      return unpackedFixed32_.size();
-    }
-    /**
-     * <code>repeated fixed32 unpacked_fixed32 = 96 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedFixed32 at the given index.
-     */
-    @java.lang.Override
-    public int getUnpackedFixed32(int index) {
-      return unpackedFixed32_.getInt(index);
-    }
-    private void ensureUnpackedFixed32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = unpackedFixed32_;
-      if (!tmp.isModifiable()) {
-        unpackedFixed32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated fixed32 unpacked_fixed32 = 96 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The unpackedFixed32 to set.
-     */
-    private void setUnpackedFixed32(
-        int index, int value) {
-      ensureUnpackedFixed32IsMutable();
-      unpackedFixed32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated fixed32 unpacked_fixed32 = 96 [packed = false];</code>
-     * @param value The unpackedFixed32 to add.
-     */
-    private void addUnpackedFixed32(int value) {
-      ensureUnpackedFixed32IsMutable();
-      unpackedFixed32_.addInt(value);
-    }
-    /**
-     * <code>repeated fixed32 unpacked_fixed32 = 96 [packed = false];</code>
-     * @param values The unpackedFixed32 to add.
-     */
-    private void addAllUnpackedFixed32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureUnpackedFixed32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, unpackedFixed32_);
-    }
-    /**
-     * <code>repeated fixed32 unpacked_fixed32 = 96 [packed = false];</code>
-     */
-    private void clearUnpackedFixed32() {
-      unpackedFixed32_ = emptyIntList();
-    }
-
-    public static final int UNPACKED_FIXED64_FIELD_NUMBER = 97;
-    private com.google.protobuf.Internal.LongList unpackedFixed64_;
-    /**
-     * <code>repeated fixed64 unpacked_fixed64 = 97 [packed = false];</code>
-     * @return A list containing the unpackedFixed64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getUnpackedFixed64List() {
-      return unpackedFixed64_;
-    }
-    /**
-     * <code>repeated fixed64 unpacked_fixed64 = 97 [packed = false];</code>
-     * @return The count of unpackedFixed64.
-     */
-    @java.lang.Override
-    public int getUnpackedFixed64Count() {
-      return unpackedFixed64_.size();
-    }
-    /**
-     * <code>repeated fixed64 unpacked_fixed64 = 97 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedFixed64 at the given index.
-     */
-    @java.lang.Override
-    public long getUnpackedFixed64(int index) {
-      return unpackedFixed64_.getLong(index);
-    }
-    private void ensureUnpackedFixed64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = unpackedFixed64_;
-      if (!tmp.isModifiable()) {
-        unpackedFixed64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated fixed64 unpacked_fixed64 = 97 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The unpackedFixed64 to set.
-     */
-    private void setUnpackedFixed64(
-        int index, long value) {
-      ensureUnpackedFixed64IsMutable();
-      unpackedFixed64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated fixed64 unpacked_fixed64 = 97 [packed = false];</code>
-     * @param value The unpackedFixed64 to add.
-     */
-    private void addUnpackedFixed64(long value) {
-      ensureUnpackedFixed64IsMutable();
-      unpackedFixed64_.addLong(value);
-    }
-    /**
-     * <code>repeated fixed64 unpacked_fixed64 = 97 [packed = false];</code>
-     * @param values The unpackedFixed64 to add.
-     */
-    private void addAllUnpackedFixed64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureUnpackedFixed64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, unpackedFixed64_);
-    }
-    /**
-     * <code>repeated fixed64 unpacked_fixed64 = 97 [packed = false];</code>
-     */
-    private void clearUnpackedFixed64() {
-      unpackedFixed64_ = emptyLongList();
-    }
-
-    public static final int UNPACKED_SFIXED32_FIELD_NUMBER = 98;
-    private com.google.protobuf.Internal.IntList unpackedSfixed32_;
-    /**
-     * <code>repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];</code>
-     * @return A list containing the unpackedSfixed32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getUnpackedSfixed32List() {
-      return unpackedSfixed32_;
-    }
-    /**
-     * <code>repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];</code>
-     * @return The count of unpackedSfixed32.
-     */
-    @java.lang.Override
-    public int getUnpackedSfixed32Count() {
-      return unpackedSfixed32_.size();
-    }
-    /**
-     * <code>repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedSfixed32 at the given index.
-     */
-    @java.lang.Override
-    public int getUnpackedSfixed32(int index) {
-      return unpackedSfixed32_.getInt(index);
-    }
-    private void ensureUnpackedSfixed32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = unpackedSfixed32_;
-      if (!tmp.isModifiable()) {
-        unpackedSfixed32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The unpackedSfixed32 to set.
-     */
-    private void setUnpackedSfixed32(
-        int index, int value) {
-      ensureUnpackedSfixed32IsMutable();
-      unpackedSfixed32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];</code>
-     * @param value The unpackedSfixed32 to add.
-     */
-    private void addUnpackedSfixed32(int value) {
-      ensureUnpackedSfixed32IsMutable();
-      unpackedSfixed32_.addInt(value);
-    }
-    /**
-     * <code>repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];</code>
-     * @param values The unpackedSfixed32 to add.
-     */
-    private void addAllUnpackedSfixed32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureUnpackedSfixed32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, unpackedSfixed32_);
-    }
-    /**
-     * <code>repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];</code>
-     */
-    private void clearUnpackedSfixed32() {
-      unpackedSfixed32_ = emptyIntList();
-    }
-
-    public static final int UNPACKED_SFIXED64_FIELD_NUMBER = 99;
-    private com.google.protobuf.Internal.LongList unpackedSfixed64_;
-    /**
-     * <code>repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];</code>
-     * @return A list containing the unpackedSfixed64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getUnpackedSfixed64List() {
-      return unpackedSfixed64_;
-    }
-    /**
-     * <code>repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];</code>
-     * @return The count of unpackedSfixed64.
-     */
-    @java.lang.Override
-    public int getUnpackedSfixed64Count() {
-      return unpackedSfixed64_.size();
-    }
-    /**
-     * <code>repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedSfixed64 at the given index.
-     */
-    @java.lang.Override
-    public long getUnpackedSfixed64(int index) {
-      return unpackedSfixed64_.getLong(index);
-    }
-    private void ensureUnpackedSfixed64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = unpackedSfixed64_;
-      if (!tmp.isModifiable()) {
-        unpackedSfixed64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The unpackedSfixed64 to set.
-     */
-    private void setUnpackedSfixed64(
-        int index, long value) {
-      ensureUnpackedSfixed64IsMutable();
-      unpackedSfixed64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];</code>
-     * @param value The unpackedSfixed64 to add.
-     */
-    private void addUnpackedSfixed64(long value) {
-      ensureUnpackedSfixed64IsMutable();
-      unpackedSfixed64_.addLong(value);
-    }
-    /**
-     * <code>repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];</code>
-     * @param values The unpackedSfixed64 to add.
-     */
-    private void addAllUnpackedSfixed64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureUnpackedSfixed64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, unpackedSfixed64_);
-    }
-    /**
-     * <code>repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];</code>
-     */
-    private void clearUnpackedSfixed64() {
-      unpackedSfixed64_ = emptyLongList();
-    }
-
-    public static final int UNPACKED_FLOAT_FIELD_NUMBER = 100;
-    private com.google.protobuf.Internal.FloatList unpackedFloat_;
-    /**
-     * <code>repeated float unpacked_float = 100 [packed = false];</code>
-     * @return A list containing the unpackedFloat.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Float>
-        getUnpackedFloatList() {
-      return unpackedFloat_;
-    }
-    /**
-     * <code>repeated float unpacked_float = 100 [packed = false];</code>
-     * @return The count of unpackedFloat.
-     */
-    @java.lang.Override
-    public int getUnpackedFloatCount() {
-      return unpackedFloat_.size();
-    }
-    /**
-     * <code>repeated float unpacked_float = 100 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedFloat at the given index.
-     */
-    @java.lang.Override
-    public float getUnpackedFloat(int index) {
-      return unpackedFloat_.getFloat(index);
-    }
-    private void ensureUnpackedFloatIsMutable() {
-      com.google.protobuf.Internal.FloatList tmp = unpackedFloat_;
-      if (!tmp.isModifiable()) {
-        unpackedFloat_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated float unpacked_float = 100 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The unpackedFloat to set.
-     */
-    private void setUnpackedFloat(
-        int index, float value) {
-      ensureUnpackedFloatIsMutable();
-      unpackedFloat_.setFloat(index, value);
-    }
-    /**
-     * <code>repeated float unpacked_float = 100 [packed = false];</code>
-     * @param value The unpackedFloat to add.
-     */
-    private void addUnpackedFloat(float value) {
-      ensureUnpackedFloatIsMutable();
-      unpackedFloat_.addFloat(value);
-    }
-    /**
-     * <code>repeated float unpacked_float = 100 [packed = false];</code>
-     * @param values The unpackedFloat to add.
-     */
-    private void addAllUnpackedFloat(
-        java.lang.Iterable<? extends java.lang.Float> values) {
-      ensureUnpackedFloatIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, unpackedFloat_);
-    }
-    /**
-     * <code>repeated float unpacked_float = 100 [packed = false];</code>
-     */
-    private void clearUnpackedFloat() {
-      unpackedFloat_ = emptyFloatList();
-    }
-
-    public static final int UNPACKED_DOUBLE_FIELD_NUMBER = 101;
-    private com.google.protobuf.Internal.DoubleList unpackedDouble_;
-    /**
-     * <code>repeated double unpacked_double = 101 [packed = false];</code>
-     * @return A list containing the unpackedDouble.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Double>
-        getUnpackedDoubleList() {
-      return unpackedDouble_;
-    }
-    /**
-     * <code>repeated double unpacked_double = 101 [packed = false];</code>
-     * @return The count of unpackedDouble.
-     */
-    @java.lang.Override
-    public int getUnpackedDoubleCount() {
-      return unpackedDouble_.size();
-    }
-    /**
-     * <code>repeated double unpacked_double = 101 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedDouble at the given index.
-     */
-    @java.lang.Override
-    public double getUnpackedDouble(int index) {
-      return unpackedDouble_.getDouble(index);
-    }
-    private void ensureUnpackedDoubleIsMutable() {
-      com.google.protobuf.Internal.DoubleList tmp = unpackedDouble_;
-      if (!tmp.isModifiable()) {
-        unpackedDouble_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated double unpacked_double = 101 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The unpackedDouble to set.
-     */
-    private void setUnpackedDouble(
-        int index, double value) {
-      ensureUnpackedDoubleIsMutable();
-      unpackedDouble_.setDouble(index, value);
-    }
-    /**
-     * <code>repeated double unpacked_double = 101 [packed = false];</code>
-     * @param value The unpackedDouble to add.
-     */
-    private void addUnpackedDouble(double value) {
-      ensureUnpackedDoubleIsMutable();
-      unpackedDouble_.addDouble(value);
-    }
-    /**
-     * <code>repeated double unpacked_double = 101 [packed = false];</code>
-     * @param values The unpackedDouble to add.
-     */
-    private void addAllUnpackedDouble(
-        java.lang.Iterable<? extends java.lang.Double> values) {
-      ensureUnpackedDoubleIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, unpackedDouble_);
-    }
-    /**
-     * <code>repeated double unpacked_double = 101 [packed = false];</code>
-     */
-    private void clearUnpackedDouble() {
-      unpackedDouble_ = emptyDoubleList();
-    }
-
-    public static final int UNPACKED_BOOL_FIELD_NUMBER = 102;
-    private com.google.protobuf.Internal.BooleanList unpackedBool_;
-    /**
-     * <code>repeated bool unpacked_bool = 102 [packed = false];</code>
-     * @return A list containing the unpackedBool.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Boolean>
-        getUnpackedBoolList() {
-      return unpackedBool_;
-    }
-    /**
-     * <code>repeated bool unpacked_bool = 102 [packed = false];</code>
-     * @return The count of unpackedBool.
-     */
-    @java.lang.Override
-    public int getUnpackedBoolCount() {
-      return unpackedBool_.size();
-    }
-    /**
-     * <code>repeated bool unpacked_bool = 102 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedBool at the given index.
-     */
-    @java.lang.Override
-    public boolean getUnpackedBool(int index) {
-      return unpackedBool_.getBoolean(index);
-    }
-    private void ensureUnpackedBoolIsMutable() {
-      com.google.protobuf.Internal.BooleanList tmp = unpackedBool_;
-      if (!tmp.isModifiable()) {
-        unpackedBool_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated bool unpacked_bool = 102 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The unpackedBool to set.
-     */
-    private void setUnpackedBool(
-        int index, boolean value) {
-      ensureUnpackedBoolIsMutable();
-      unpackedBool_.setBoolean(index, value);
-    }
-    /**
-     * <code>repeated bool unpacked_bool = 102 [packed = false];</code>
-     * @param value The unpackedBool to add.
-     */
-    private void addUnpackedBool(boolean value) {
-      ensureUnpackedBoolIsMutable();
-      unpackedBool_.addBoolean(value);
-    }
-    /**
-     * <code>repeated bool unpacked_bool = 102 [packed = false];</code>
-     * @param values The unpackedBool to add.
-     */
-    private void addAllUnpackedBool(
-        java.lang.Iterable<? extends java.lang.Boolean> values) {
-      ensureUnpackedBoolIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, unpackedBool_);
-    }
-    /**
-     * <code>repeated bool unpacked_bool = 102 [packed = false];</code>
-     */
-    private void clearUnpackedBool() {
-      unpackedBool_ = emptyBooleanList();
-    }
-
-    public static final int UNPACKED_ENUM_FIELD_NUMBER = 103;
-    private com.google.protobuf.Internal.IntList unpackedEnum_;
-    private static final com.google.protobuf.Internal.ListAdapter.Converter<
-        java.lang.Integer, protobuf_unittest.UnittestProto.ForeignEnum> unpackedEnum_converter_ =
-            new com.google.protobuf.Internal.ListAdapter.Converter<
-                java.lang.Integer, protobuf_unittest.UnittestProto.ForeignEnum>() {
-              @java.lang.Override
-              public protobuf_unittest.UnittestProto.ForeignEnum convert(java.lang.Integer from) {
-                protobuf_unittest.UnittestProto.ForeignEnum result = protobuf_unittest.UnittestProto.ForeignEnum.forNumber(from);
-                return result == null ? protobuf_unittest.UnittestProto.ForeignEnum.FOREIGN_FOO : result;
-              }
-            };
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum unpacked_enum = 103 [packed = false];</code>
-     * @return A list containing the unpackedEnum.
-     */
-    @java.lang.Override
-    public java.util.List<protobuf_unittest.UnittestProto.ForeignEnum> getUnpackedEnumList() {
-      return new com.google.protobuf.Internal.ListAdapter<
-          java.lang.Integer, protobuf_unittest.UnittestProto.ForeignEnum>(unpackedEnum_, unpackedEnum_converter_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum unpacked_enum = 103 [packed = false];</code>
-     * @return The count of unpackedEnum.
-     */
-    @java.lang.Override
-    public int getUnpackedEnumCount() {
-      return unpackedEnum_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum unpacked_enum = 103 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The unpackedEnum at the given index.
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.ForeignEnum getUnpackedEnum(int index) {
-      return unpackedEnum_converter_.convert(unpackedEnum_.getInt(index));
-    }
-    private void ensureUnpackedEnumIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = unpackedEnum_;
-      if (!tmp.isModifiable()) {
-        unpackedEnum_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum unpacked_enum = 103 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The unpackedEnum to set.
-     */
-    private void setUnpackedEnum(
-        int index, protobuf_unittest.UnittestProto.ForeignEnum value) {
-      value.getClass();
-  ensureUnpackedEnumIsMutable();
-      unpackedEnum_.setInt(index, value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum unpacked_enum = 103 [packed = false];</code>
-     * @param value The unpackedEnum to add.
-     */
-    private void addUnpackedEnum(protobuf_unittest.UnittestProto.ForeignEnum value) {
-      value.getClass();
-  ensureUnpackedEnumIsMutable();
-      unpackedEnum_.addInt(value.getNumber());
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum unpacked_enum = 103 [packed = false];</code>
-     * @param values The unpackedEnum to add.
-     */
-    private void addAllUnpackedEnum(
-        java.lang.Iterable<? extends protobuf_unittest.UnittestProto.ForeignEnum> values) {
-      ensureUnpackedEnumIsMutable();
-      for (protobuf_unittest.UnittestProto.ForeignEnum value : values) {
-        unpackedEnum_.addInt(value.getNumber());
-      }
-    }
-    /**
-     * <code>repeated .protobuf_unittest.ForeignEnum unpacked_enum = 103 [packed = false];</code>
-     */
-    private void clearUnpackedEnum() {
-      unpackedEnum_ = emptyIntList();
-    }
-
-    public static protobuf_unittest.UnittestProto.TestUnpackedTypes parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedTypes parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedTypes parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedTypes parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedTypes parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedTypes parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedTypes parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedTypes parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedTypes parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedTypes parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedTypes parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedTypes parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestUnpackedTypes prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * A message with the same fields as TestPackedTypes, but without packing. Used
-     * to test packed &lt;-&gt; unpacked wire compatibility.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestUnpackedTypes}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestUnpackedTypes, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestUnpackedTypes)
-        protobuf_unittest.UnittestProto.TestUnpackedTypesOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestUnpackedTypes.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>repeated int32 unpacked_int32 = 90 [packed = false];</code>
-       * @return A list containing the unpackedInt32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getUnpackedInt32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getUnpackedInt32List());
-      }
-      /**
-       * <code>repeated int32 unpacked_int32 = 90 [packed = false];</code>
-       * @return The count of unpackedInt32.
-       */
-      @java.lang.Override
-      public int getUnpackedInt32Count() {
-        return instance.getUnpackedInt32Count();
-      }
-      /**
-       * <code>repeated int32 unpacked_int32 = 90 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The unpackedInt32 at the given index.
-       */
-      @java.lang.Override
-      public int getUnpackedInt32(int index) {
-        return instance.getUnpackedInt32(index);
-      }
-      /**
-       * <code>repeated int32 unpacked_int32 = 90 [packed = false];</code>
-       * @param value The unpackedInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setUnpackedInt32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setUnpackedInt32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 unpacked_int32 = 90 [packed = false];</code>
-       * @param value The unpackedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addUnpackedInt32(int value) {
-        copyOnWrite();
-        instance.addUnpackedInt32(value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 unpacked_int32 = 90 [packed = false];</code>
-       * @param values The unpackedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllUnpackedInt32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllUnpackedInt32(values);
-        return this;
-      }
-      /**
-       * <code>repeated int32 unpacked_int32 = 90 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearUnpackedInt32() {
-        copyOnWrite();
-        instance.clearUnpackedInt32();
-        return this;
-      }
-
-      /**
-       * <code>repeated int64 unpacked_int64 = 91 [packed = false];</code>
-       * @return A list containing the unpackedInt64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getUnpackedInt64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getUnpackedInt64List());
-      }
-      /**
-       * <code>repeated int64 unpacked_int64 = 91 [packed = false];</code>
-       * @return The count of unpackedInt64.
-       */
-      @java.lang.Override
-      public int getUnpackedInt64Count() {
-        return instance.getUnpackedInt64Count();
-      }
-      /**
-       * <code>repeated int64 unpacked_int64 = 91 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The unpackedInt64 at the given index.
-       */
-      @java.lang.Override
-      public long getUnpackedInt64(int index) {
-        return instance.getUnpackedInt64(index);
-      }
-      /**
-       * <code>repeated int64 unpacked_int64 = 91 [packed = false];</code>
-       * @param value The unpackedInt64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setUnpackedInt64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setUnpackedInt64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int64 unpacked_int64 = 91 [packed = false];</code>
-       * @param value The unpackedInt64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addUnpackedInt64(long value) {
-        copyOnWrite();
-        instance.addUnpackedInt64(value);
-        return this;
-      }
-      /**
-       * <code>repeated int64 unpacked_int64 = 91 [packed = false];</code>
-       * @param values The unpackedInt64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllUnpackedInt64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllUnpackedInt64(values);
-        return this;
-      }
-      /**
-       * <code>repeated int64 unpacked_int64 = 91 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearUnpackedInt64() {
-        copyOnWrite();
-        instance.clearUnpackedInt64();
-        return this;
-      }
-
-      /**
-       * <code>repeated uint32 unpacked_uint32 = 92 [packed = false];</code>
-       * @return A list containing the unpackedUint32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getUnpackedUint32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getUnpackedUint32List());
-      }
-      /**
-       * <code>repeated uint32 unpacked_uint32 = 92 [packed = false];</code>
-       * @return The count of unpackedUint32.
-       */
-      @java.lang.Override
-      public int getUnpackedUint32Count() {
-        return instance.getUnpackedUint32Count();
-      }
-      /**
-       * <code>repeated uint32 unpacked_uint32 = 92 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The unpackedUint32 at the given index.
-       */
-      @java.lang.Override
-      public int getUnpackedUint32(int index) {
-        return instance.getUnpackedUint32(index);
-      }
-      /**
-       * <code>repeated uint32 unpacked_uint32 = 92 [packed = false];</code>
-       * @param value The unpackedUint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setUnpackedUint32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setUnpackedUint32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 unpacked_uint32 = 92 [packed = false];</code>
-       * @param value The unpackedUint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addUnpackedUint32(int value) {
-        copyOnWrite();
-        instance.addUnpackedUint32(value);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 unpacked_uint32 = 92 [packed = false];</code>
-       * @param values The unpackedUint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllUnpackedUint32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllUnpackedUint32(values);
-        return this;
-      }
-      /**
-       * <code>repeated uint32 unpacked_uint32 = 92 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearUnpackedUint32() {
-        copyOnWrite();
-        instance.clearUnpackedUint32();
-        return this;
-      }
-
-      /**
-       * <code>repeated uint64 unpacked_uint64 = 93 [packed = false];</code>
-       * @return A list containing the unpackedUint64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getUnpackedUint64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getUnpackedUint64List());
-      }
-      /**
-       * <code>repeated uint64 unpacked_uint64 = 93 [packed = false];</code>
-       * @return The count of unpackedUint64.
-       */
-      @java.lang.Override
-      public int getUnpackedUint64Count() {
-        return instance.getUnpackedUint64Count();
-      }
-      /**
-       * <code>repeated uint64 unpacked_uint64 = 93 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The unpackedUint64 at the given index.
-       */
-      @java.lang.Override
-      public long getUnpackedUint64(int index) {
-        return instance.getUnpackedUint64(index);
-      }
-      /**
-       * <code>repeated uint64 unpacked_uint64 = 93 [packed = false];</code>
-       * @param value The unpackedUint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setUnpackedUint64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setUnpackedUint64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 unpacked_uint64 = 93 [packed = false];</code>
-       * @param value The unpackedUint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addUnpackedUint64(long value) {
-        copyOnWrite();
-        instance.addUnpackedUint64(value);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 unpacked_uint64 = 93 [packed = false];</code>
-       * @param values The unpackedUint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllUnpackedUint64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllUnpackedUint64(values);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 unpacked_uint64 = 93 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearUnpackedUint64() {
-        copyOnWrite();
-        instance.clearUnpackedUint64();
-        return this;
-      }
-
-      /**
-       * <code>repeated sint32 unpacked_sint32 = 94 [packed = false];</code>
-       * @return A list containing the unpackedSint32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getUnpackedSint32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getUnpackedSint32List());
-      }
-      /**
-       * <code>repeated sint32 unpacked_sint32 = 94 [packed = false];</code>
-       * @return The count of unpackedSint32.
-       */
-      @java.lang.Override
-      public int getUnpackedSint32Count() {
-        return instance.getUnpackedSint32Count();
-      }
-      /**
-       * <code>repeated sint32 unpacked_sint32 = 94 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The unpackedSint32 at the given index.
-       */
-      @java.lang.Override
-      public int getUnpackedSint32(int index) {
-        return instance.getUnpackedSint32(index);
-      }
-      /**
-       * <code>repeated sint32 unpacked_sint32 = 94 [packed = false];</code>
-       * @param value The unpackedSint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setUnpackedSint32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setUnpackedSint32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 unpacked_sint32 = 94 [packed = false];</code>
-       * @param value The unpackedSint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addUnpackedSint32(int value) {
-        copyOnWrite();
-        instance.addUnpackedSint32(value);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 unpacked_sint32 = 94 [packed = false];</code>
-       * @param values The unpackedSint32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllUnpackedSint32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllUnpackedSint32(values);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 unpacked_sint32 = 94 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearUnpackedSint32() {
-        copyOnWrite();
-        instance.clearUnpackedSint32();
-        return this;
-      }
-
-      /**
-       * <code>repeated sint64 unpacked_sint64 = 95 [packed = false];</code>
-       * @return A list containing the unpackedSint64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getUnpackedSint64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getUnpackedSint64List());
-      }
-      /**
-       * <code>repeated sint64 unpacked_sint64 = 95 [packed = false];</code>
-       * @return The count of unpackedSint64.
-       */
-      @java.lang.Override
-      public int getUnpackedSint64Count() {
-        return instance.getUnpackedSint64Count();
-      }
-      /**
-       * <code>repeated sint64 unpacked_sint64 = 95 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The unpackedSint64 at the given index.
-       */
-      @java.lang.Override
-      public long getUnpackedSint64(int index) {
-        return instance.getUnpackedSint64(index);
-      }
-      /**
-       * <code>repeated sint64 unpacked_sint64 = 95 [packed = false];</code>
-       * @param value The unpackedSint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setUnpackedSint64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setUnpackedSint64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 unpacked_sint64 = 95 [packed = false];</code>
-       * @param value The unpackedSint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addUnpackedSint64(long value) {
-        copyOnWrite();
-        instance.addUnpackedSint64(value);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 unpacked_sint64 = 95 [packed = false];</code>
-       * @param values The unpackedSint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllUnpackedSint64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllUnpackedSint64(values);
-        return this;
-      }
-      /**
-       * <code>repeated sint64 unpacked_sint64 = 95 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearUnpackedSint64() {
-        copyOnWrite();
-        instance.clearUnpackedSint64();
-        return this;
-      }
-
-      /**
-       * <code>repeated fixed32 unpacked_fixed32 = 96 [packed = false];</code>
-       * @return A list containing the unpackedFixed32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getUnpackedFixed32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getUnpackedFixed32List());
-      }
-      /**
-       * <code>repeated fixed32 unpacked_fixed32 = 96 [packed = false];</code>
-       * @return The count of unpackedFixed32.
-       */
-      @java.lang.Override
-      public int getUnpackedFixed32Count() {
-        return instance.getUnpackedFixed32Count();
-      }
-      /**
-       * <code>repeated fixed32 unpacked_fixed32 = 96 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The unpackedFixed32 at the given index.
-       */
-      @java.lang.Override
-      public int getUnpackedFixed32(int index) {
-        return instance.getUnpackedFixed32(index);
-      }
-      /**
-       * <code>repeated fixed32 unpacked_fixed32 = 96 [packed = false];</code>
-       * @param value The unpackedFixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setUnpackedFixed32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setUnpackedFixed32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 unpacked_fixed32 = 96 [packed = false];</code>
-       * @param value The unpackedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addUnpackedFixed32(int value) {
-        copyOnWrite();
-        instance.addUnpackedFixed32(value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 unpacked_fixed32 = 96 [packed = false];</code>
-       * @param values The unpackedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllUnpackedFixed32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllUnpackedFixed32(values);
-        return this;
-      }
-      /**
-       * <code>repeated fixed32 unpacked_fixed32 = 96 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearUnpackedFixed32() {
-        copyOnWrite();
-        instance.clearUnpackedFixed32();
-        return this;
-      }
-
-      /**
-       * <code>repeated fixed64 unpacked_fixed64 = 97 [packed = false];</code>
-       * @return A list containing the unpackedFixed64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getUnpackedFixed64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getUnpackedFixed64List());
-      }
-      /**
-       * <code>repeated fixed64 unpacked_fixed64 = 97 [packed = false];</code>
-       * @return The count of unpackedFixed64.
-       */
-      @java.lang.Override
-      public int getUnpackedFixed64Count() {
-        return instance.getUnpackedFixed64Count();
-      }
-      /**
-       * <code>repeated fixed64 unpacked_fixed64 = 97 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The unpackedFixed64 at the given index.
-       */
-      @java.lang.Override
-      public long getUnpackedFixed64(int index) {
-        return instance.getUnpackedFixed64(index);
-      }
-      /**
-       * <code>repeated fixed64 unpacked_fixed64 = 97 [packed = false];</code>
-       * @param value The unpackedFixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setUnpackedFixed64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setUnpackedFixed64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 unpacked_fixed64 = 97 [packed = false];</code>
-       * @param value The unpackedFixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addUnpackedFixed64(long value) {
-        copyOnWrite();
-        instance.addUnpackedFixed64(value);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 unpacked_fixed64 = 97 [packed = false];</code>
-       * @param values The unpackedFixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllUnpackedFixed64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllUnpackedFixed64(values);
-        return this;
-      }
-      /**
-       * <code>repeated fixed64 unpacked_fixed64 = 97 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearUnpackedFixed64() {
-        copyOnWrite();
-        instance.clearUnpackedFixed64();
-        return this;
-      }
-
-      /**
-       * <code>repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];</code>
-       * @return A list containing the unpackedSfixed32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getUnpackedSfixed32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getUnpackedSfixed32List());
-      }
-      /**
-       * <code>repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];</code>
-       * @return The count of unpackedSfixed32.
-       */
-      @java.lang.Override
-      public int getUnpackedSfixed32Count() {
-        return instance.getUnpackedSfixed32Count();
-      }
-      /**
-       * <code>repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The unpackedSfixed32 at the given index.
-       */
-      @java.lang.Override
-      public int getUnpackedSfixed32(int index) {
-        return instance.getUnpackedSfixed32(index);
-      }
-      /**
-       * <code>repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];</code>
-       * @param value The unpackedSfixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setUnpackedSfixed32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setUnpackedSfixed32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];</code>
-       * @param value The unpackedSfixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addUnpackedSfixed32(int value) {
-        copyOnWrite();
-        instance.addUnpackedSfixed32(value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];</code>
-       * @param values The unpackedSfixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllUnpackedSfixed32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllUnpackedSfixed32(values);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearUnpackedSfixed32() {
-        copyOnWrite();
-        instance.clearUnpackedSfixed32();
-        return this;
-      }
-
-      /**
-       * <code>repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];</code>
-       * @return A list containing the unpackedSfixed64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getUnpackedSfixed64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getUnpackedSfixed64List());
-      }
-      /**
-       * <code>repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];</code>
-       * @return The count of unpackedSfixed64.
-       */
-      @java.lang.Override
-      public int getUnpackedSfixed64Count() {
-        return instance.getUnpackedSfixed64Count();
-      }
-      /**
-       * <code>repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The unpackedSfixed64 at the given index.
-       */
-      @java.lang.Override
-      public long getUnpackedSfixed64(int index) {
-        return instance.getUnpackedSfixed64(index);
-      }
-      /**
-       * <code>repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];</code>
-       * @param value The unpackedSfixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setUnpackedSfixed64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setUnpackedSfixed64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];</code>
-       * @param value The unpackedSfixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addUnpackedSfixed64(long value) {
-        copyOnWrite();
-        instance.addUnpackedSfixed64(value);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];</code>
-       * @param values The unpackedSfixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllUnpackedSfixed64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllUnpackedSfixed64(values);
-        return this;
-      }
-      /**
-       * <code>repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearUnpackedSfixed64() {
-        copyOnWrite();
-        instance.clearUnpackedSfixed64();
-        return this;
-      }
-
-      /**
-       * <code>repeated float unpacked_float = 100 [packed = false];</code>
-       * @return A list containing the unpackedFloat.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Float>
-          getUnpackedFloatList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getUnpackedFloatList());
-      }
-      /**
-       * <code>repeated float unpacked_float = 100 [packed = false];</code>
-       * @return The count of unpackedFloat.
-       */
-      @java.lang.Override
-      public int getUnpackedFloatCount() {
-        return instance.getUnpackedFloatCount();
-      }
-      /**
-       * <code>repeated float unpacked_float = 100 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The unpackedFloat at the given index.
-       */
-      @java.lang.Override
-      public float getUnpackedFloat(int index) {
-        return instance.getUnpackedFloat(index);
-      }
-      /**
-       * <code>repeated float unpacked_float = 100 [packed = false];</code>
-       * @param value The unpackedFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setUnpackedFloat(
-          int index, float value) {
-        copyOnWrite();
-        instance.setUnpackedFloat(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated float unpacked_float = 100 [packed = false];</code>
-       * @param value The unpackedFloat to add.
-       * @return This builder for chaining.
-       */
-      public Builder addUnpackedFloat(float value) {
-        copyOnWrite();
-        instance.addUnpackedFloat(value);
-        return this;
-      }
-      /**
-       * <code>repeated float unpacked_float = 100 [packed = false];</code>
-       * @param values The unpackedFloat to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllUnpackedFloat(
-          java.lang.Iterable<? extends java.lang.Float> values) {
-        copyOnWrite();
-        instance.addAllUnpackedFloat(values);
-        return this;
-      }
-      /**
-       * <code>repeated float unpacked_float = 100 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearUnpackedFloat() {
-        copyOnWrite();
-        instance.clearUnpackedFloat();
-        return this;
-      }
-
-      /**
-       * <code>repeated double unpacked_double = 101 [packed = false];</code>
-       * @return A list containing the unpackedDouble.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Double>
-          getUnpackedDoubleList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getUnpackedDoubleList());
-      }
-      /**
-       * <code>repeated double unpacked_double = 101 [packed = false];</code>
-       * @return The count of unpackedDouble.
-       */
-      @java.lang.Override
-      public int getUnpackedDoubleCount() {
-        return instance.getUnpackedDoubleCount();
-      }
-      /**
-       * <code>repeated double unpacked_double = 101 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The unpackedDouble at the given index.
-       */
-      @java.lang.Override
-      public double getUnpackedDouble(int index) {
-        return instance.getUnpackedDouble(index);
-      }
-      /**
-       * <code>repeated double unpacked_double = 101 [packed = false];</code>
-       * @param value The unpackedDouble to set.
-       * @return This builder for chaining.
-       */
-      public Builder setUnpackedDouble(
-          int index, double value) {
-        copyOnWrite();
-        instance.setUnpackedDouble(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated double unpacked_double = 101 [packed = false];</code>
-       * @param value The unpackedDouble to add.
-       * @return This builder for chaining.
-       */
-      public Builder addUnpackedDouble(double value) {
-        copyOnWrite();
-        instance.addUnpackedDouble(value);
-        return this;
-      }
-      /**
-       * <code>repeated double unpacked_double = 101 [packed = false];</code>
-       * @param values The unpackedDouble to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllUnpackedDouble(
-          java.lang.Iterable<? extends java.lang.Double> values) {
-        copyOnWrite();
-        instance.addAllUnpackedDouble(values);
-        return this;
-      }
-      /**
-       * <code>repeated double unpacked_double = 101 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearUnpackedDouble() {
-        copyOnWrite();
-        instance.clearUnpackedDouble();
-        return this;
-      }
-
-      /**
-       * <code>repeated bool unpacked_bool = 102 [packed = false];</code>
-       * @return A list containing the unpackedBool.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Boolean>
-          getUnpackedBoolList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getUnpackedBoolList());
-      }
-      /**
-       * <code>repeated bool unpacked_bool = 102 [packed = false];</code>
-       * @return The count of unpackedBool.
-       */
-      @java.lang.Override
-      public int getUnpackedBoolCount() {
-        return instance.getUnpackedBoolCount();
-      }
-      /**
-       * <code>repeated bool unpacked_bool = 102 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The unpackedBool at the given index.
-       */
-      @java.lang.Override
-      public boolean getUnpackedBool(int index) {
-        return instance.getUnpackedBool(index);
-      }
-      /**
-       * <code>repeated bool unpacked_bool = 102 [packed = false];</code>
-       * @param value The unpackedBool to set.
-       * @return This builder for chaining.
-       */
-      public Builder setUnpackedBool(
-          int index, boolean value) {
-        copyOnWrite();
-        instance.setUnpackedBool(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated bool unpacked_bool = 102 [packed = false];</code>
-       * @param value The unpackedBool to add.
-       * @return This builder for chaining.
-       */
-      public Builder addUnpackedBool(boolean value) {
-        copyOnWrite();
-        instance.addUnpackedBool(value);
-        return this;
-      }
-      /**
-       * <code>repeated bool unpacked_bool = 102 [packed = false];</code>
-       * @param values The unpackedBool to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllUnpackedBool(
-          java.lang.Iterable<? extends java.lang.Boolean> values) {
-        copyOnWrite();
-        instance.addAllUnpackedBool(values);
-        return this;
-      }
-      /**
-       * <code>repeated bool unpacked_bool = 102 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearUnpackedBool() {
-        copyOnWrite();
-        instance.clearUnpackedBool();
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum unpacked_enum = 103 [packed = false];</code>
-       * @return A list containing the unpackedEnum.
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.ForeignEnum> getUnpackedEnumList() {
-        return instance.getUnpackedEnumList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum unpacked_enum = 103 [packed = false];</code>
-       * @return The count of unpackedEnum.
-       */
-      @java.lang.Override
-      public int getUnpackedEnumCount() {
-        return instance.getUnpackedEnumCount();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum unpacked_enum = 103 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The unpackedEnum at the given index.
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.ForeignEnum getUnpackedEnum(int index) {
-        return instance.getUnpackedEnum(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum unpacked_enum = 103 [packed = false];</code>
-       * @param index The index to set the value at.
-       * @param value The unpackedEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setUnpackedEnum(
-          int index, protobuf_unittest.UnittestProto.ForeignEnum value) {
-        copyOnWrite();
-        instance.setUnpackedEnum(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum unpacked_enum = 103 [packed = false];</code>
-       * @param value The unpackedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addUnpackedEnum(protobuf_unittest.UnittestProto.ForeignEnum value) {
-        copyOnWrite();
-        instance.addUnpackedEnum(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum unpacked_enum = 103 [packed = false];</code>
-       * @param values The unpackedEnum to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllUnpackedEnum(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.ForeignEnum> values) {
-        copyOnWrite();
-        instance.addAllUnpackedEnum(values);  return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.ForeignEnum unpacked_enum = 103 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearUnpackedEnum() {
-        copyOnWrite();
-        instance.clearUnpackedEnum();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestUnpackedTypes)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestUnpackedTypes();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "unpackedInt32_",
-              "unpackedInt64_",
-              "unpackedUint32_",
-              "unpackedUint64_",
-              "unpackedSint32_",
-              "unpackedSint64_",
-              "unpackedFixed32_",
-              "unpackedFixed64_",
-              "unpackedSfixed32_",
-              "unpackedSfixed64_",
-              "unpackedFloat_",
-              "unpackedDouble_",
-              "unpackedBool_",
-              "unpackedEnum_",
-              protobuf_unittest.UnittestProto.ForeignEnum.internalGetVerifier(),
-            };
-            java.lang.String info =
-                "\u0001\u000e\u0000\u0000Zg\u000e\u0000\u000e\u0000Z\u0016[\u0014\\\u001d]\u0015^" +
-                "!_\"`\u0018a\u0017b\u001fc d\u0013e\u0012f\u0019g\u001e";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestUnpackedTypes> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestUnpackedTypes.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestUnpackedTypes>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestUnpackedTypes)
-    private static final protobuf_unittest.UnittestProto.TestUnpackedTypes DEFAULT_INSTANCE;
-    static {
-      TestUnpackedTypes defaultInstance = new TestUnpackedTypes();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestUnpackedTypes.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestUnpackedTypes getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestUnpackedTypes> PARSER;
-
-    public static com.google.protobuf.Parser<TestUnpackedTypes> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestPackedExtensionsOrBuilder extends 
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestPackedExtensions)
-       com.google.protobuf.GeneratedMessageLite.
-            ExtendableMessageOrBuilder<
-                TestPackedExtensions, TestPackedExtensions.Builder> {
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestPackedExtensions}
-   */
-  public  static final class TestPackedExtensions extends
-      com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
-        TestPackedExtensions, TestPackedExtensions.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestPackedExtensions)
-      TestPackedExtensionsOrBuilder {
-    private TestPackedExtensions() {
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedExtensions parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedExtensions parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedExtensions parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedExtensions parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedExtensions parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedExtensions parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedExtensions parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedExtensions parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedExtensions parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedExtensions parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedExtensions parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestPackedExtensions parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestPackedExtensions prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestPackedExtensions}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
-          protobuf_unittest.UnittestProto.TestPackedExtensions, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestPackedExtensions)
-        protobuf_unittest.UnittestProto.TestPackedExtensionsOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestPackedExtensions.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestPackedExtensions)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestPackedExtensions();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestPackedExtensions> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestPackedExtensions.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestPackedExtensions>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestPackedExtensions)
-    private static final protobuf_unittest.UnittestProto.TestPackedExtensions DEFAULT_INSTANCE;
-    static {
-      TestPackedExtensions defaultInstance = new TestPackedExtensions();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestPackedExtensions.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestPackedExtensions getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestPackedExtensions> PARSER;
-
-    public static com.google.protobuf.Parser<TestPackedExtensions> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestUnpackedExtensionsOrBuilder extends 
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestUnpackedExtensions)
-       com.google.protobuf.GeneratedMessageLite.
-            ExtendableMessageOrBuilder<
-                TestUnpackedExtensions, TestUnpackedExtensions.Builder> {
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestUnpackedExtensions}
-   */
-  public  static final class TestUnpackedExtensions extends
-      com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
-        TestUnpackedExtensions, TestUnpackedExtensions.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestUnpackedExtensions)
-      TestUnpackedExtensionsOrBuilder {
-    private TestUnpackedExtensions() {
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedExtensions parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedExtensions parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedExtensions parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedExtensions parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedExtensions parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedExtensions parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedExtensions parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedExtensions parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedExtensions parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedExtensions parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedExtensions parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestUnpackedExtensions parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestUnpackedExtensions prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestUnpackedExtensions}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
-          protobuf_unittest.UnittestProto.TestUnpackedExtensions, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestUnpackedExtensions)
-        protobuf_unittest.UnittestProto.TestUnpackedExtensionsOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestUnpackedExtensions.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestUnpackedExtensions)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestUnpackedExtensions();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestUnpackedExtensions> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestUnpackedExtensions.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestUnpackedExtensions>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestUnpackedExtensions)
-    private static final protobuf_unittest.UnittestProto.TestUnpackedExtensions DEFAULT_INSTANCE;
-    static {
-      TestUnpackedExtensions defaultInstance = new TestUnpackedExtensions();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestUnpackedExtensions.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestUnpackedExtensions getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestUnpackedExtensions> PARSER;
-
-    public static com.google.protobuf.Parser<TestUnpackedExtensions> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestDynamicExtensionsOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestDynamicExtensions)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional fixed32 scalar_extension = 2000;</code>
-     * @return Whether the scalarExtension field is set.
-     */
-    boolean hasScalarExtension();
-    /**
-     * <code>optional fixed32 scalar_extension = 2000;</code>
-     * @return The scalarExtension.
-     */
-    int getScalarExtension();
-
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum enum_extension = 2001;</code>
-     * @return Whether the enumExtension field is set.
-     */
-    boolean hasEnumExtension();
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum enum_extension = 2001;</code>
-     * @return The enumExtension.
-     */
-    protobuf_unittest.UnittestProto.ForeignEnum getEnumExtension();
-
-    /**
-     * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicEnumType dynamic_enum_extension = 2002;</code>
-     * @return Whether the dynamicEnumExtension field is set.
-     */
-    boolean hasDynamicEnumExtension();
-    /**
-     * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicEnumType dynamic_enum_extension = 2002;</code>
-     * @return The dynamicEnumExtension.
-     */
-    protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicEnumType getDynamicEnumExtension();
-
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage message_extension = 2003;</code>
-     * @return Whether the messageExtension field is set.
-     */
-    boolean hasMessageExtension();
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage message_extension = 2003;</code>
-     * @return The messageExtension.
-     */
-    protobuf_unittest.UnittestProto.ForeignMessage getMessageExtension();
-
-    /**
-     * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicMessageType dynamic_message_extension = 2004;</code>
-     * @return Whether the dynamicMessageExtension field is set.
-     */
-    boolean hasDynamicMessageExtension();
-    /**
-     * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicMessageType dynamic_message_extension = 2004;</code>
-     * @return The dynamicMessageExtension.
-     */
-    protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType getDynamicMessageExtension();
-
-    /**
-     * <code>repeated string repeated_extension = 2005;</code>
-     * @return A list containing the repeatedExtension.
-     */
-    java.util.List<java.lang.String>
-        getRepeatedExtensionList();
-    /**
-     * <code>repeated string repeated_extension = 2005;</code>
-     * @return The count of repeatedExtension.
-     */
-    int getRepeatedExtensionCount();
-    /**
-     * <code>repeated string repeated_extension = 2005;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedExtension at the given index.
-     */
-    java.lang.String getRepeatedExtension(int index);
-    /**
-     * <code>repeated string repeated_extension = 2005;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedExtension at the given index.
-     */
-    com.google.protobuf.ByteString
-        getRepeatedExtensionBytes(int index);
-
-    /**
-     * <code>repeated sint32 packed_extension = 2006 [packed = true];</code>
-     * @return A list containing the packedExtension.
-     */
-    java.util.List<java.lang.Integer> getPackedExtensionList();
-    /**
-     * <code>repeated sint32 packed_extension = 2006 [packed = true];</code>
-     * @return The count of packedExtension.
-     */
-    int getPackedExtensionCount();
-    /**
-     * <code>repeated sint32 packed_extension = 2006 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedExtension at the given index.
-     */
-    int getPackedExtension(int index);
-  }
-  /**
-   * <pre>
-   * Used by ExtensionSetTest/DynamicExtensions.  The test actually builds
-   * a set of extensions to TestAllExtensions dynamically, based on the fields
-   * of this message type.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestDynamicExtensions}
-   */
-  public  static final class TestDynamicExtensions extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestDynamicExtensions, TestDynamicExtensions.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestDynamicExtensions)
-      TestDynamicExtensionsOrBuilder {
-    private TestDynamicExtensions() {
-      enumExtension_ = 4;
-      dynamicEnumExtension_ = 2200;
-      repeatedExtension_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-      packedExtension_ = emptyIntList();
-    }
-    /**
-     * Protobuf enum {@code protobuf_unittest.TestDynamicExtensions.DynamicEnumType}
-     */
-    public enum DynamicEnumType
-        implements com.google.protobuf.Internal.EnumLite {
-      /**
-       * <code>DYNAMIC_FOO = 2200;</code>
-       */
-      DYNAMIC_FOO(2200),
-      /**
-       * <code>DYNAMIC_BAR = 2201;</code>
-       */
-      DYNAMIC_BAR(2201),
-      /**
-       * <code>DYNAMIC_BAZ = 2202;</code>
-       */
-      DYNAMIC_BAZ(2202),
-      ;
-
-      /**
-       * <code>DYNAMIC_FOO = 2200;</code>
-       */
-      public static final int DYNAMIC_FOO_VALUE = 2200;
-      /**
-       * <code>DYNAMIC_BAR = 2201;</code>
-       */
-      public static final int DYNAMIC_BAR_VALUE = 2201;
-      /**
-       * <code>DYNAMIC_BAZ = 2202;</code>
-       */
-      public static final int DYNAMIC_BAZ_VALUE = 2202;
-
-
-      @java.lang.Override
-      public final int getNumber() {
-        return value;
-      }
-
-      /**
-       * @param value The number of the enum to look for.
-       * @return The enum associated with the given number.
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static DynamicEnumType valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static DynamicEnumType forNumber(int value) {
-        switch (value) {
-          case 2200: return DYNAMIC_FOO;
-          case 2201: return DYNAMIC_BAR;
-          case 2202: return DYNAMIC_BAZ;
-          default: return null;
-        }
-      }
-
-      public static com.google.protobuf.Internal.EnumLiteMap<DynamicEnumType>
-          internalGetValueMap() {
-        return internalValueMap;
-      }
-      private static final com.google.protobuf.Internal.EnumLiteMap<
-          DynamicEnumType> internalValueMap =
-            new com.google.protobuf.Internal.EnumLiteMap<DynamicEnumType>() {
-              @java.lang.Override
-              public DynamicEnumType findValueByNumber(int number) {
-                return DynamicEnumType.forNumber(number);
-              }
-            };
-
-      public static com.google.protobuf.Internal.EnumVerifier 
-          internalGetVerifier() {
-        return DynamicEnumTypeVerifier.INSTANCE;
-      }
-
-      private static final class DynamicEnumTypeVerifier implements 
-           com.google.protobuf.Internal.EnumVerifier { 
-              static final com.google.protobuf.Internal.EnumVerifier           INSTANCE = new DynamicEnumTypeVerifier();
-              @java.lang.Override
-              public boolean isInRange(int number) {
-                return DynamicEnumType.forNumber(number) != null;
-              }
-            };
-
-      private final int value;
-
-      private DynamicEnumType(int value) {
-        this.value = value;
-      }
-
-      // @@protoc_insertion_point(enum_scope:protobuf_unittest.TestDynamicExtensions.DynamicEnumType)
-    }
-
-    public interface DynamicMessageTypeOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestDynamicExtensions.DynamicMessageType)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int32 dynamic_field = 2100;</code>
-       * @return Whether the dynamicField field is set.
-       */
-      boolean hasDynamicField();
-      /**
-       * <code>optional int32 dynamic_field = 2100;</code>
-       * @return The dynamicField.
-       */
-      int getDynamicField();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestDynamicExtensions.DynamicMessageType}
-     */
-    public  static final class DynamicMessageType extends
-        com.google.protobuf.GeneratedMessageLite<
-            DynamicMessageType, DynamicMessageType.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestDynamicExtensions.DynamicMessageType)
-        DynamicMessageTypeOrBuilder {
-      private DynamicMessageType() {
-      }
-      private int bitField0_;
-      public static final int DYNAMIC_FIELD_FIELD_NUMBER = 2100;
-      private int dynamicField_;
-      /**
-       * <code>optional int32 dynamic_field = 2100;</code>
-       * @return Whether the dynamicField field is set.
-       */
-      @java.lang.Override
-      public boolean hasDynamicField() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int32 dynamic_field = 2100;</code>
-       * @return The dynamicField.
-       */
-      @java.lang.Override
-      public int getDynamicField() {
-        return dynamicField_;
-      }
-      /**
-       * <code>optional int32 dynamic_field = 2100;</code>
-       * @param value The dynamicField to set.
-       */
-      private void setDynamicField(int value) {
-        bitField0_ |= 0x00000001;
-        dynamicField_ = value;
-      }
-      /**
-       * <code>optional int32 dynamic_field = 2100;</code>
-       */
-      private void clearDynamicField() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        dynamicField_ = 0;
-      }
-
-      public static protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestDynamicExtensions.DynamicMessageType}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestDynamicExtensions.DynamicMessageType)
-          protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageTypeOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int32 dynamic_field = 2100;</code>
-         * @return Whether the dynamicField field is set.
-         */
-        @java.lang.Override
-        public boolean hasDynamicField() {
-          return instance.hasDynamicField();
-        }
-        /**
-         * <code>optional int32 dynamic_field = 2100;</code>
-         * @return The dynamicField.
-         */
-        @java.lang.Override
-        public int getDynamicField() {
-          return instance.getDynamicField();
-        }
-        /**
-         * <code>optional int32 dynamic_field = 2100;</code>
-         * @param value The dynamicField to set.
-         * @return This builder for chaining.
-         */
-        public Builder setDynamicField(int value) {
-          copyOnWrite();
-          instance.setDynamicField(value);
-          return this;
-        }
-        /**
-         * <code>optional int32 dynamic_field = 2100;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearDynamicField() {
-          copyOnWrite();
-          instance.clearDynamicField();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestDynamicExtensions.DynamicMessageType)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "dynamicField_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\u0834\u0834\u0001\u0000\u0000\u0000\u0834\u1004\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestDynamicExtensions.DynamicMessageType)
-      private static final protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType DEFAULT_INSTANCE;
-      static {
-        DynamicMessageType defaultInstance = new DynamicMessageType();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          DynamicMessageType.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<DynamicMessageType> PARSER;
-
-      public static com.google.protobuf.Parser<DynamicMessageType> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int bitField0_;
-    public static final int SCALAR_EXTENSION_FIELD_NUMBER = 2000;
-    private int scalarExtension_;
-    /**
-     * <code>optional fixed32 scalar_extension = 2000;</code>
-     * @return Whether the scalarExtension field is set.
-     */
-    @java.lang.Override
-    public boolean hasScalarExtension() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional fixed32 scalar_extension = 2000;</code>
-     * @return The scalarExtension.
-     */
-    @java.lang.Override
-    public int getScalarExtension() {
-      return scalarExtension_;
-    }
-    /**
-     * <code>optional fixed32 scalar_extension = 2000;</code>
-     * @param value The scalarExtension to set.
-     */
-    private void setScalarExtension(int value) {
-      bitField0_ |= 0x00000001;
-      scalarExtension_ = value;
-    }
-    /**
-     * <code>optional fixed32 scalar_extension = 2000;</code>
-     */
-    private void clearScalarExtension() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      scalarExtension_ = 0;
-    }
-
-    public static final int ENUM_EXTENSION_FIELD_NUMBER = 2001;
-    private int enumExtension_;
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum enum_extension = 2001;</code>
-     * @return Whether the enumExtension field is set.
-     */
-    @java.lang.Override
-    public boolean hasEnumExtension() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum enum_extension = 2001;</code>
-     * @return The enumExtension.
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.ForeignEnum getEnumExtension() {
-      protobuf_unittest.UnittestProto.ForeignEnum result = protobuf_unittest.UnittestProto.ForeignEnum.forNumber(enumExtension_);
-      return result == null ? protobuf_unittest.UnittestProto.ForeignEnum.FOREIGN_FOO : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum enum_extension = 2001;</code>
-     * @param value The enumExtension to set.
-     */
-    private void setEnumExtension(protobuf_unittest.UnittestProto.ForeignEnum value) {
-      enumExtension_ = value.getNumber();
-      bitField0_ |= 0x00000002;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum enum_extension = 2001;</code>
-     */
-    private void clearEnumExtension() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      enumExtension_ = 4;
-    }
-
-    public static final int DYNAMIC_ENUM_EXTENSION_FIELD_NUMBER = 2002;
-    private int dynamicEnumExtension_;
-    /**
-     * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicEnumType dynamic_enum_extension = 2002;</code>
-     * @return Whether the dynamicEnumExtension field is set.
-     */
-    @java.lang.Override
-    public boolean hasDynamicEnumExtension() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicEnumType dynamic_enum_extension = 2002;</code>
-     * @return The dynamicEnumExtension.
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicEnumType getDynamicEnumExtension() {
-      protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicEnumType result = protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicEnumType.forNumber(dynamicEnumExtension_);
-      return result == null ? protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicEnumType.DYNAMIC_FOO : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicEnumType dynamic_enum_extension = 2002;</code>
-     * @param value The dynamicEnumExtension to set.
-     */
-    private void setDynamicEnumExtension(protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicEnumType value) {
-      dynamicEnumExtension_ = value.getNumber();
-      bitField0_ |= 0x00000004;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicEnumType dynamic_enum_extension = 2002;</code>
-     */
-    private void clearDynamicEnumExtension() {
-      bitField0_ = (bitField0_ & ~0x00000004);
-      dynamicEnumExtension_ = 2200;
-    }
-
-    public static final int MESSAGE_EXTENSION_FIELD_NUMBER = 2003;
-    private protobuf_unittest.UnittestProto.ForeignMessage messageExtension_;
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage message_extension = 2003;</code>
-     */
-    @java.lang.Override
-    public boolean hasMessageExtension() {
-      return ((bitField0_ & 0x00000008) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage message_extension = 2003;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.ForeignMessage getMessageExtension() {
-      return messageExtension_ == null ? protobuf_unittest.UnittestProto.ForeignMessage.getDefaultInstance() : messageExtension_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage message_extension = 2003;</code>
-     */
-    private void setMessageExtension(protobuf_unittest.UnittestProto.ForeignMessage value) {
-      value.getClass();
-  messageExtension_ = value;
-      bitField0_ |= 0x00000008;
-      }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage message_extension = 2003;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeMessageExtension(protobuf_unittest.UnittestProto.ForeignMessage value) {
-      value.getClass();
-  if (messageExtension_ != null &&
-          messageExtension_ != protobuf_unittest.UnittestProto.ForeignMessage.getDefaultInstance()) {
-        messageExtension_ =
-          protobuf_unittest.UnittestProto.ForeignMessage.newBuilder(messageExtension_).mergeFrom(value).buildPartial();
-      } else {
-        messageExtension_ = value;
-      }
-      bitField0_ |= 0x00000008;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage message_extension = 2003;</code>
-     */
-    private void clearMessageExtension() {  messageExtension_ = null;
-      bitField0_ = (bitField0_ & ~0x00000008);
-    }
-
-    public static final int DYNAMIC_MESSAGE_EXTENSION_FIELD_NUMBER = 2004;
-    private protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType dynamicMessageExtension_;
-    /**
-     * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicMessageType dynamic_message_extension = 2004;</code>
-     */
-    @java.lang.Override
-    public boolean hasDynamicMessageExtension() {
-      return ((bitField0_ & 0x00000010) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicMessageType dynamic_message_extension = 2004;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType getDynamicMessageExtension() {
-      return dynamicMessageExtension_ == null ? protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType.getDefaultInstance() : dynamicMessageExtension_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicMessageType dynamic_message_extension = 2004;</code>
-     */
-    private void setDynamicMessageExtension(protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType value) {
-      value.getClass();
-  dynamicMessageExtension_ = value;
-      bitField0_ |= 0x00000010;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicMessageType dynamic_message_extension = 2004;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeDynamicMessageExtension(protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType value) {
-      value.getClass();
-  if (dynamicMessageExtension_ != null &&
-          dynamicMessageExtension_ != protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType.getDefaultInstance()) {
-        dynamicMessageExtension_ =
-          protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType.newBuilder(dynamicMessageExtension_).mergeFrom(value).buildPartial();
-      } else {
-        dynamicMessageExtension_ = value;
-      }
-      bitField0_ |= 0x00000010;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicMessageType dynamic_message_extension = 2004;</code>
-     */
-    private void clearDynamicMessageExtension() {  dynamicMessageExtension_ = null;
-      bitField0_ = (bitField0_ & ~0x00000010);
-    }
-
-    public static final int REPEATED_EXTENSION_FIELD_NUMBER = 2005;
-    private com.google.protobuf.Internal.ProtobufList<java.lang.String> repeatedExtension_;
-    /**
-     * <code>repeated string repeated_extension = 2005;</code>
-     * @return A list containing the repeatedExtension.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.String> getRepeatedExtensionList() {
-      return repeatedExtension_;
-    }
-    /**
-     * <code>repeated string repeated_extension = 2005;</code>
-     * @return The count of repeatedExtension.
-     */
-    @java.lang.Override
-    public int getRepeatedExtensionCount() {
-      return repeatedExtension_.size();
-    }
-    /**
-     * <code>repeated string repeated_extension = 2005;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedExtension at the given index.
-     */
-    @java.lang.Override
-    public java.lang.String getRepeatedExtension(int index) {
-      return repeatedExtension_.get(index);
-    }
-    /**
-     * <code>repeated string repeated_extension = 2005;</code>
-     * @param index The index of the value to return.
-     * @return The bytes of the repeatedExtension at the given index.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getRepeatedExtensionBytes(int index) {
-      return com.google.protobuf.ByteString.copyFromUtf8(
-          repeatedExtension_.get(index));
-    }
-    private void ensureRepeatedExtensionIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =
-          repeatedExtension_;  if (!tmp.isModifiable()) {
-        repeatedExtension_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated string repeated_extension = 2005;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedExtension to set.
-     */
-    private void setRepeatedExtension(
-        int index, java.lang.String value) {
-      value.getClass();
-  ensureRepeatedExtensionIsMutable();
-      repeatedExtension_.set(index, value);
-    }
-    /**
-     * <code>repeated string repeated_extension = 2005;</code>
-     * @param value The repeatedExtension to add.
-     */
-    private void addRepeatedExtension(
-        java.lang.String value) {
-      value.getClass();
-  ensureRepeatedExtensionIsMutable();
-      repeatedExtension_.add(value);
-    }
-    /**
-     * <code>repeated string repeated_extension = 2005;</code>
-     * @param values The repeatedExtension to add.
-     */
-    private void addAllRepeatedExtension(
-        java.lang.Iterable<java.lang.String> values) {
-      ensureRepeatedExtensionIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedExtension_);
-    }
-    /**
-     * <code>repeated string repeated_extension = 2005;</code>
-     */
-    private void clearRepeatedExtension() {
-      repeatedExtension_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-    }
-    /**
-     * <code>repeated string repeated_extension = 2005;</code>
-     * @param value The bytes of the repeatedExtension to add.
-     */
-    private void addRepeatedExtensionBytes(
-        com.google.protobuf.ByteString value) {
-      ensureRepeatedExtensionIsMutable();
-      repeatedExtension_.add(value.toStringUtf8());
-    }
-
-    public static final int PACKED_EXTENSION_FIELD_NUMBER = 2006;
-    private com.google.protobuf.Internal.IntList packedExtension_;
-    /**
-     * <code>repeated sint32 packed_extension = 2006 [packed = true];</code>
-     * @return A list containing the packedExtension.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getPackedExtensionList() {
-      return packedExtension_;
-    }
-    /**
-     * <code>repeated sint32 packed_extension = 2006 [packed = true];</code>
-     * @return The count of packedExtension.
-     */
-    @java.lang.Override
-    public int getPackedExtensionCount() {
-      return packedExtension_.size();
-    }
-    /**
-     * <code>repeated sint32 packed_extension = 2006 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedExtension at the given index.
-     */
-    @java.lang.Override
-    public int getPackedExtension(int index) {
-      return packedExtension_.getInt(index);
-    }
-    private int packedExtensionMemoizedSerializedSize = -1;
-    private void ensurePackedExtensionIsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedExtension_;
-      if (!tmp.isModifiable()) {
-        packedExtension_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated sint32 packed_extension = 2006 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedExtension to set.
-     */
-    private void setPackedExtension(
-        int index, int value) {
-      ensurePackedExtensionIsMutable();
-      packedExtension_.setInt(index, value);
-    }
-    /**
-     * <code>repeated sint32 packed_extension = 2006 [packed = true];</code>
-     * @param value The packedExtension to add.
-     */
-    private void addPackedExtension(int value) {
-      ensurePackedExtensionIsMutable();
-      packedExtension_.addInt(value);
-    }
-    /**
-     * <code>repeated sint32 packed_extension = 2006 [packed = true];</code>
-     * @param values The packedExtension to add.
-     */
-    private void addAllPackedExtension(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensurePackedExtensionIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedExtension_);
-    }
-    /**
-     * <code>repeated sint32 packed_extension = 2006 [packed = true];</code>
-     */
-    private void clearPackedExtension() {
-      packedExtension_ = emptyIntList();
-    }
-
-    public static protobuf_unittest.UnittestProto.TestDynamicExtensions parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestDynamicExtensions parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDynamicExtensions parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestDynamicExtensions parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDynamicExtensions parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestDynamicExtensions parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDynamicExtensions parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestDynamicExtensions parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDynamicExtensions parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestDynamicExtensions parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestDynamicExtensions parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestDynamicExtensions parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestDynamicExtensions prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Used by ExtensionSetTest/DynamicExtensions.  The test actually builds
-     * a set of extensions to TestAllExtensions dynamically, based on the fields
-     * of this message type.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestDynamicExtensions}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestDynamicExtensions, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestDynamicExtensions)
-        protobuf_unittest.UnittestProto.TestDynamicExtensionsOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestDynamicExtensions.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional fixed32 scalar_extension = 2000;</code>
-       * @return Whether the scalarExtension field is set.
-       */
-      @java.lang.Override
-      public boolean hasScalarExtension() {
-        return instance.hasScalarExtension();
-      }
-      /**
-       * <code>optional fixed32 scalar_extension = 2000;</code>
-       * @return The scalarExtension.
-       */
-      @java.lang.Override
-      public int getScalarExtension() {
-        return instance.getScalarExtension();
-      }
-      /**
-       * <code>optional fixed32 scalar_extension = 2000;</code>
-       * @param value The scalarExtension to set.
-       * @return This builder for chaining.
-       */
-      public Builder setScalarExtension(int value) {
-        copyOnWrite();
-        instance.setScalarExtension(value);
-        return this;
-      }
-      /**
-       * <code>optional fixed32 scalar_extension = 2000;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearScalarExtension() {
-        copyOnWrite();
-        instance.clearScalarExtension();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum enum_extension = 2001;</code>
-       * @return Whether the enumExtension field is set.
-       */
-      @java.lang.Override
-      public boolean hasEnumExtension() {
-        return instance.hasEnumExtension();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum enum_extension = 2001;</code>
-       * @return The enumExtension.
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.ForeignEnum getEnumExtension() {
-        return instance.getEnumExtension();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum enum_extension = 2001;</code>
-       * @param value The enum numeric value on the wire for enumExtension to set.
-       * @return This builder for chaining.
-       */
-      public Builder setEnumExtension(protobuf_unittest.UnittestProto.ForeignEnum value) {
-        copyOnWrite();
-        instance.setEnumExtension(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum enum_extension = 2001;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearEnumExtension() {
-        copyOnWrite();
-        instance.clearEnumExtension();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicEnumType dynamic_enum_extension = 2002;</code>
-       * @return Whether the dynamicEnumExtension field is set.
-       */
-      @java.lang.Override
-      public boolean hasDynamicEnumExtension() {
-        return instance.hasDynamicEnumExtension();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicEnumType dynamic_enum_extension = 2002;</code>
-       * @return The dynamicEnumExtension.
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicEnumType getDynamicEnumExtension() {
-        return instance.getDynamicEnumExtension();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicEnumType dynamic_enum_extension = 2002;</code>
-       * @param value The enum numeric value on the wire for dynamicEnumExtension to set.
-       * @return This builder for chaining.
-       */
-      public Builder setDynamicEnumExtension(protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicEnumType value) {
-        copyOnWrite();
-        instance.setDynamicEnumExtension(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicEnumType dynamic_enum_extension = 2002;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearDynamicEnumExtension() {
-        copyOnWrite();
-        instance.clearDynamicEnumExtension();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage message_extension = 2003;</code>
-       */
-      @java.lang.Override
-      public boolean hasMessageExtension() {
-        return instance.hasMessageExtension();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage message_extension = 2003;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.ForeignMessage getMessageExtension() {
-        return instance.getMessageExtension();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage message_extension = 2003;</code>
-       */
-      public Builder setMessageExtension(protobuf_unittest.UnittestProto.ForeignMessage value) {
-        copyOnWrite();
-        instance.setMessageExtension(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage message_extension = 2003;</code>
-       */
-      public Builder setMessageExtension(
-          protobuf_unittest.UnittestProto.ForeignMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setMessageExtension(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage message_extension = 2003;</code>
-       */
-      public Builder mergeMessageExtension(protobuf_unittest.UnittestProto.ForeignMessage value) {
-        copyOnWrite();
-        instance.mergeMessageExtension(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage message_extension = 2003;</code>
-       */
-      public Builder clearMessageExtension() {  copyOnWrite();
-        instance.clearMessageExtension();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicMessageType dynamic_message_extension = 2004;</code>
-       */
-      @java.lang.Override
-      public boolean hasDynamicMessageExtension() {
-        return instance.hasDynamicMessageExtension();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicMessageType dynamic_message_extension = 2004;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType getDynamicMessageExtension() {
-        return instance.getDynamicMessageExtension();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicMessageType dynamic_message_extension = 2004;</code>
-       */
-      public Builder setDynamicMessageExtension(protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType value) {
-        copyOnWrite();
-        instance.setDynamicMessageExtension(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicMessageType dynamic_message_extension = 2004;</code>
-       */
-      public Builder setDynamicMessageExtension(
-          protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType.Builder builderForValue) {
-        copyOnWrite();
-        instance.setDynamicMessageExtension(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicMessageType dynamic_message_extension = 2004;</code>
-       */
-      public Builder mergeDynamicMessageExtension(protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicMessageType value) {
-        copyOnWrite();
-        instance.mergeDynamicMessageExtension(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestDynamicExtensions.DynamicMessageType dynamic_message_extension = 2004;</code>
-       */
-      public Builder clearDynamicMessageExtension() {  copyOnWrite();
-        instance.clearDynamicMessageExtension();
-        return this;
-      }
-
-      /**
-       * <code>repeated string repeated_extension = 2005;</code>
-       * @return A list containing the repeatedExtension.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.String>
-          getRepeatedExtensionList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedExtensionList());
-      }
-      /**
-       * <code>repeated string repeated_extension = 2005;</code>
-       * @return The count of repeatedExtension.
-       */
-      @java.lang.Override
-      public int getRepeatedExtensionCount() {
-        return instance.getRepeatedExtensionCount();
-      }
-      /**
-       * <code>repeated string repeated_extension = 2005;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedExtension at the given index.
-       */
-      @java.lang.Override
-      public java.lang.String getRepeatedExtension(int index) {
-        return instance.getRepeatedExtension(index);
-      }
-      /**
-       * <code>repeated string repeated_extension = 2005;</code>
-       * @param index The index of the value to return.
-       * @return The bytes of the repeatedExtension at the given index.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getRepeatedExtensionBytes(int index) {
-        return instance.getRepeatedExtensionBytes(index);
-      }
-      /**
-       * <code>repeated string repeated_extension = 2005;</code>
-       * @param index The index to set the value at.
-       * @param value The repeatedExtension to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedExtension(
-          int index, java.lang.String value) {
-        copyOnWrite();
-        instance.setRepeatedExtension(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_extension = 2005;</code>
-       * @param value The repeatedExtension to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedExtension(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.addRepeatedExtension(value);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_extension = 2005;</code>
-       * @param values The repeatedExtension to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedExtension(
-          java.lang.Iterable<java.lang.String> values) {
-        copyOnWrite();
-        instance.addAllRepeatedExtension(values);
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_extension = 2005;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedExtension() {
-        copyOnWrite();
-        instance.clearRepeatedExtension();
-        return this;
-      }
-      /**
-       * <code>repeated string repeated_extension = 2005;</code>
-       * @param value The bytes of the repeatedExtension to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedExtensionBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.addRepeatedExtensionBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>repeated sint32 packed_extension = 2006 [packed = true];</code>
-       * @return A list containing the packedExtension.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getPackedExtensionList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedExtensionList());
-      }
-      /**
-       * <code>repeated sint32 packed_extension = 2006 [packed = true];</code>
-       * @return The count of packedExtension.
-       */
-      @java.lang.Override
-      public int getPackedExtensionCount() {
-        return instance.getPackedExtensionCount();
-      }
-      /**
-       * <code>repeated sint32 packed_extension = 2006 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedExtension at the given index.
-       */
-      @java.lang.Override
-      public int getPackedExtension(int index) {
-        return instance.getPackedExtension(index);
-      }
-      /**
-       * <code>repeated sint32 packed_extension = 2006 [packed = true];</code>
-       * @param value The packedExtension to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedExtension(
-          int index, int value) {
-        copyOnWrite();
-        instance.setPackedExtension(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 packed_extension = 2006 [packed = true];</code>
-       * @param value The packedExtension to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedExtension(int value) {
-        copyOnWrite();
-        instance.addPackedExtension(value);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 packed_extension = 2006 [packed = true];</code>
-       * @param values The packedExtension to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedExtension(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllPackedExtension(values);
-        return this;
-      }
-      /**
-       * <code>repeated sint32 packed_extension = 2006 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedExtension() {
-        copyOnWrite();
-        instance.clearPackedExtension();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestDynamicExtensions)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestDynamicExtensions();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "scalarExtension_",
-              "enumExtension_",
-              protobuf_unittest.UnittestProto.ForeignEnum.internalGetVerifier(),
-              "dynamicEnumExtension_",
-              protobuf_unittest.UnittestProto.TestDynamicExtensions.DynamicEnumType.internalGetVerifier(),
-              "messageExtension_",
-              "dynamicMessageExtension_",
-              "repeatedExtension_",
-              "packedExtension_",
-            };
-            java.lang.String info =
-                "\u0001\u0007\u0000\u0001\u07d0\u07d6\u0007\u0000\u0002\u0000\u07d0\u1006\u0000\u07d1" +
-                "\u100c\u0001\u07d2\u100c\u0002\u07d3\u1009\u0003\u07d4\u1009\u0004\u07d5\u001a\u07d6" +
-                "/";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestDynamicExtensions> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestDynamicExtensions.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestDynamicExtensions>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestDynamicExtensions)
-    private static final protobuf_unittest.UnittestProto.TestDynamicExtensions DEFAULT_INSTANCE;
-    static {
-      TestDynamicExtensions defaultInstance = new TestDynamicExtensions();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestDynamicExtensions.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestDynamicExtensions getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestDynamicExtensions> PARSER;
-
-    public static com.google.protobuf.Parser<TestDynamicExtensions> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestRepeatedScalarDifferentTagSizesOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestRepeatedScalarDifferentTagSizes)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <pre>
-     * Parsing repeated fixed size values used to fail. This message needs to be
-     * used in order to get a tag of the right size; all of the repeated fields
-     * in TestAllTypes didn't trigger the check.
-     * </pre>
-     *
-     * <code>repeated fixed32 repeated_fixed32 = 12;</code>
-     * @return A list containing the repeatedFixed32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedFixed32List();
-    /**
-     * <pre>
-     * Parsing repeated fixed size values used to fail. This message needs to be
-     * used in order to get a tag of the right size; all of the repeated fields
-     * in TestAllTypes didn't trigger the check.
-     * </pre>
-     *
-     * <code>repeated fixed32 repeated_fixed32 = 12;</code>
-     * @return The count of repeatedFixed32.
-     */
-    int getRepeatedFixed32Count();
-    /**
-     * <pre>
-     * Parsing repeated fixed size values used to fail. This message needs to be
-     * used in order to get a tag of the right size; all of the repeated fields
-     * in TestAllTypes didn't trigger the check.
-     * </pre>
-     *
-     * <code>repeated fixed32 repeated_fixed32 = 12;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed32 at the given index.
-     */
-    int getRepeatedFixed32(int index);
-
-    /**
-     * <pre>
-     * Check for a varint type, just for good measure.
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 13;</code>
-     * @return A list containing the repeatedInt32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedInt32List();
-    /**
-     * <pre>
-     * Check for a varint type, just for good measure.
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 13;</code>
-     * @return The count of repeatedInt32.
-     */
-    int getRepeatedInt32Count();
-    /**
-     * <pre>
-     * Check for a varint type, just for good measure.
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 13;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt32 at the given index.
-     */
-    int getRepeatedInt32(int index);
-
-    /**
-     * <pre>
-     * These have two-byte tags.
-     * </pre>
-     *
-     * <code>repeated fixed64 repeated_fixed64 = 2046;</code>
-     * @return A list containing the repeatedFixed64.
-     */
-    java.util.List<java.lang.Long> getRepeatedFixed64List();
-    /**
-     * <pre>
-     * These have two-byte tags.
-     * </pre>
-     *
-     * <code>repeated fixed64 repeated_fixed64 = 2046;</code>
-     * @return The count of repeatedFixed64.
-     */
-    int getRepeatedFixed64Count();
-    /**
-     * <pre>
-     * These have two-byte tags.
-     * </pre>
-     *
-     * <code>repeated fixed64 repeated_fixed64 = 2046;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed64 at the given index.
-     */
-    long getRepeatedFixed64(int index);
-
-    /**
-     * <code>repeated int64 repeated_int64 = 2047;</code>
-     * @return A list containing the repeatedInt64.
-     */
-    java.util.List<java.lang.Long> getRepeatedInt64List();
-    /**
-     * <code>repeated int64 repeated_int64 = 2047;</code>
-     * @return The count of repeatedInt64.
-     */
-    int getRepeatedInt64Count();
-    /**
-     * <code>repeated int64 repeated_int64 = 2047;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt64 at the given index.
-     */
-    long getRepeatedInt64(int index);
-
-    /**
-     * <pre>
-     * Three byte tags.
-     * </pre>
-     *
-     * <code>repeated float repeated_float = 262142;</code>
-     * @return A list containing the repeatedFloat.
-     */
-    java.util.List<java.lang.Float> getRepeatedFloatList();
-    /**
-     * <pre>
-     * Three byte tags.
-     * </pre>
-     *
-     * <code>repeated float repeated_float = 262142;</code>
-     * @return The count of repeatedFloat.
-     */
-    int getRepeatedFloatCount();
-    /**
-     * <pre>
-     * Three byte tags.
-     * </pre>
-     *
-     * <code>repeated float repeated_float = 262142;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFloat at the given index.
-     */
-    float getRepeatedFloat(int index);
-
-    /**
-     * <code>repeated uint64 repeated_uint64 = 262143;</code>
-     * @return A list containing the repeatedUint64.
-     */
-    java.util.List<java.lang.Long> getRepeatedUint64List();
-    /**
-     * <code>repeated uint64 repeated_uint64 = 262143;</code>
-     * @return The count of repeatedUint64.
-     */
-    int getRepeatedUint64Count();
-    /**
-     * <code>repeated uint64 repeated_uint64 = 262143;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedUint64 at the given index.
-     */
-    long getRepeatedUint64(int index);
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestRepeatedScalarDifferentTagSizes}
-   */
-  public  static final class TestRepeatedScalarDifferentTagSizes extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestRepeatedScalarDifferentTagSizes, TestRepeatedScalarDifferentTagSizes.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestRepeatedScalarDifferentTagSizes)
-      TestRepeatedScalarDifferentTagSizesOrBuilder {
-    private TestRepeatedScalarDifferentTagSizes() {
-      repeatedFixed32_ = emptyIntList();
-      repeatedInt32_ = emptyIntList();
-      repeatedFixed64_ = emptyLongList();
-      repeatedInt64_ = emptyLongList();
-      repeatedFloat_ = emptyFloatList();
-      repeatedUint64_ = emptyLongList();
-    }
-    public static final int REPEATED_FIXED32_FIELD_NUMBER = 12;
-    private com.google.protobuf.Internal.IntList repeatedFixed32_;
-    /**
-     * <pre>
-     * Parsing repeated fixed size values used to fail. This message needs to be
-     * used in order to get a tag of the right size; all of the repeated fields
-     * in TestAllTypes didn't trigger the check.
-     * </pre>
-     *
-     * <code>repeated fixed32 repeated_fixed32 = 12;</code>
-     * @return A list containing the repeatedFixed32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedFixed32List() {
-      return repeatedFixed32_;
-    }
-    /**
-     * <pre>
-     * Parsing repeated fixed size values used to fail. This message needs to be
-     * used in order to get a tag of the right size; all of the repeated fields
-     * in TestAllTypes didn't trigger the check.
-     * </pre>
-     *
-     * <code>repeated fixed32 repeated_fixed32 = 12;</code>
-     * @return The count of repeatedFixed32.
-     */
-    @java.lang.Override
-    public int getRepeatedFixed32Count() {
-      return repeatedFixed32_.size();
-    }
-    /**
-     * <pre>
-     * Parsing repeated fixed size values used to fail. This message needs to be
-     * used in order to get a tag of the right size; all of the repeated fields
-     * in TestAllTypes didn't trigger the check.
-     * </pre>
-     *
-     * <code>repeated fixed32 repeated_fixed32 = 12;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedFixed32(int index) {
-      return repeatedFixed32_.getInt(index);
-    }
-    private void ensureRepeatedFixed32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedFixed32_;
-      if (!tmp.isModifiable()) {
-        repeatedFixed32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <pre>
-     * Parsing repeated fixed size values used to fail. This message needs to be
-     * used in order to get a tag of the right size; all of the repeated fields
-     * in TestAllTypes didn't trigger the check.
-     * </pre>
-     *
-     * <code>repeated fixed32 repeated_fixed32 = 12;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed32 to set.
-     */
-    private void setRepeatedFixed32(
-        int index, int value) {
-      ensureRepeatedFixed32IsMutable();
-      repeatedFixed32_.setInt(index, value);
-    }
-    /**
-     * <pre>
-     * Parsing repeated fixed size values used to fail. This message needs to be
-     * used in order to get a tag of the right size; all of the repeated fields
-     * in TestAllTypes didn't trigger the check.
-     * </pre>
-     *
-     * <code>repeated fixed32 repeated_fixed32 = 12;</code>
-     * @param value The repeatedFixed32 to add.
-     */
-    private void addRepeatedFixed32(int value) {
-      ensureRepeatedFixed32IsMutable();
-      repeatedFixed32_.addInt(value);
-    }
-    /**
-     * <pre>
-     * Parsing repeated fixed size values used to fail. This message needs to be
-     * used in order to get a tag of the right size; all of the repeated fields
-     * in TestAllTypes didn't trigger the check.
-     * </pre>
-     *
-     * <code>repeated fixed32 repeated_fixed32 = 12;</code>
-     * @param values The repeatedFixed32 to add.
-     */
-    private void addAllRepeatedFixed32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedFixed32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedFixed32_);
-    }
-    /**
-     * <pre>
-     * Parsing repeated fixed size values used to fail. This message needs to be
-     * used in order to get a tag of the right size; all of the repeated fields
-     * in TestAllTypes didn't trigger the check.
-     * </pre>
-     *
-     * <code>repeated fixed32 repeated_fixed32 = 12;</code>
-     */
-    private void clearRepeatedFixed32() {
-      repeatedFixed32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_INT32_FIELD_NUMBER = 13;
-    private com.google.protobuf.Internal.IntList repeatedInt32_;
-    /**
-     * <pre>
-     * Check for a varint type, just for good measure.
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 13;</code>
-     * @return A list containing the repeatedInt32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedInt32List() {
-      return repeatedInt32_;
-    }
-    /**
-     * <pre>
-     * Check for a varint type, just for good measure.
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 13;</code>
-     * @return The count of repeatedInt32.
-     */
-    @java.lang.Override
-    public int getRepeatedInt32Count() {
-      return repeatedInt32_.size();
-    }
-    /**
-     * <pre>
-     * Check for a varint type, just for good measure.
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 13;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedInt32(int index) {
-      return repeatedInt32_.getInt(index);
-    }
-    private void ensureRepeatedInt32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedInt32_;
-      if (!tmp.isModifiable()) {
-        repeatedInt32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <pre>
-     * Check for a varint type, just for good measure.
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 13;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt32 to set.
-     */
-    private void setRepeatedInt32(
-        int index, int value) {
-      ensureRepeatedInt32IsMutable();
-      repeatedInt32_.setInt(index, value);
-    }
-    /**
-     * <pre>
-     * Check for a varint type, just for good measure.
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 13;</code>
-     * @param value The repeatedInt32 to add.
-     */
-    private void addRepeatedInt32(int value) {
-      ensureRepeatedInt32IsMutable();
-      repeatedInt32_.addInt(value);
-    }
-    /**
-     * <pre>
-     * Check for a varint type, just for good measure.
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 13;</code>
-     * @param values The repeatedInt32 to add.
-     */
-    private void addAllRepeatedInt32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedInt32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedInt32_);
-    }
-    /**
-     * <pre>
-     * Check for a varint type, just for good measure.
-     * </pre>
-     *
-     * <code>repeated int32 repeated_int32 = 13;</code>
-     */
-    private void clearRepeatedInt32() {
-      repeatedInt32_ = emptyIntList();
-    }
-
-    public static final int REPEATED_FIXED64_FIELD_NUMBER = 2046;
-    private com.google.protobuf.Internal.LongList repeatedFixed64_;
-    /**
-     * <pre>
-     * These have two-byte tags.
-     * </pre>
-     *
-     * <code>repeated fixed64 repeated_fixed64 = 2046;</code>
-     * @return A list containing the repeatedFixed64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedFixed64List() {
-      return repeatedFixed64_;
-    }
-    /**
-     * <pre>
-     * These have two-byte tags.
-     * </pre>
-     *
-     * <code>repeated fixed64 repeated_fixed64 = 2046;</code>
-     * @return The count of repeatedFixed64.
-     */
-    @java.lang.Override
-    public int getRepeatedFixed64Count() {
-      return repeatedFixed64_.size();
-    }
-    /**
-     * <pre>
-     * These have two-byte tags.
-     * </pre>
-     *
-     * <code>repeated fixed64 repeated_fixed64 = 2046;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFixed64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedFixed64(int index) {
-      return repeatedFixed64_.getLong(index);
-    }
-    private void ensureRepeatedFixed64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedFixed64_;
-      if (!tmp.isModifiable()) {
-        repeatedFixed64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <pre>
-     * These have two-byte tags.
-     * </pre>
-     *
-     * <code>repeated fixed64 repeated_fixed64 = 2046;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFixed64 to set.
-     */
-    private void setRepeatedFixed64(
-        int index, long value) {
-      ensureRepeatedFixed64IsMutable();
-      repeatedFixed64_.setLong(index, value);
-    }
-    /**
-     * <pre>
-     * These have two-byte tags.
-     * </pre>
-     *
-     * <code>repeated fixed64 repeated_fixed64 = 2046;</code>
-     * @param value The repeatedFixed64 to add.
-     */
-    private void addRepeatedFixed64(long value) {
-      ensureRepeatedFixed64IsMutable();
-      repeatedFixed64_.addLong(value);
-    }
-    /**
-     * <pre>
-     * These have two-byte tags.
-     * </pre>
-     *
-     * <code>repeated fixed64 repeated_fixed64 = 2046;</code>
-     * @param values The repeatedFixed64 to add.
-     */
-    private void addAllRepeatedFixed64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedFixed64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedFixed64_);
-    }
-    /**
-     * <pre>
-     * These have two-byte tags.
-     * </pre>
-     *
-     * <code>repeated fixed64 repeated_fixed64 = 2046;</code>
-     */
-    private void clearRepeatedFixed64() {
-      repeatedFixed64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_INT64_FIELD_NUMBER = 2047;
-    private com.google.protobuf.Internal.LongList repeatedInt64_;
-    /**
-     * <code>repeated int64 repeated_int64 = 2047;</code>
-     * @return A list containing the repeatedInt64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedInt64List() {
-      return repeatedInt64_;
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 2047;</code>
-     * @return The count of repeatedInt64.
-     */
-    @java.lang.Override
-    public int getRepeatedInt64Count() {
-      return repeatedInt64_.size();
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 2047;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedInt64(int index) {
-      return repeatedInt64_.getLong(index);
-    }
-    private void ensureRepeatedInt64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedInt64_;
-      if (!tmp.isModifiable()) {
-        repeatedInt64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 2047;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt64 to set.
-     */
-    private void setRepeatedInt64(
-        int index, long value) {
-      ensureRepeatedInt64IsMutable();
-      repeatedInt64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 2047;</code>
-     * @param value The repeatedInt64 to add.
-     */
-    private void addRepeatedInt64(long value) {
-      ensureRepeatedInt64IsMutable();
-      repeatedInt64_.addLong(value);
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 2047;</code>
-     * @param values The repeatedInt64 to add.
-     */
-    private void addAllRepeatedInt64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedInt64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedInt64_);
-    }
-    /**
-     * <code>repeated int64 repeated_int64 = 2047;</code>
-     */
-    private void clearRepeatedInt64() {
-      repeatedInt64_ = emptyLongList();
-    }
-
-    public static final int REPEATED_FLOAT_FIELD_NUMBER = 262142;
-    private com.google.protobuf.Internal.FloatList repeatedFloat_;
-    /**
-     * <pre>
-     * Three byte tags.
-     * </pre>
-     *
-     * <code>repeated float repeated_float = 262142;</code>
-     * @return A list containing the repeatedFloat.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Float>
-        getRepeatedFloatList() {
-      return repeatedFloat_;
-    }
-    /**
-     * <pre>
-     * Three byte tags.
-     * </pre>
-     *
-     * <code>repeated float repeated_float = 262142;</code>
-     * @return The count of repeatedFloat.
-     */
-    @java.lang.Override
-    public int getRepeatedFloatCount() {
-      return repeatedFloat_.size();
-    }
-    /**
-     * <pre>
-     * Three byte tags.
-     * </pre>
-     *
-     * <code>repeated float repeated_float = 262142;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedFloat at the given index.
-     */
-    @java.lang.Override
-    public float getRepeatedFloat(int index) {
-      return repeatedFloat_.getFloat(index);
-    }
-    private void ensureRepeatedFloatIsMutable() {
-      com.google.protobuf.Internal.FloatList tmp = repeatedFloat_;
-      if (!tmp.isModifiable()) {
-        repeatedFloat_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <pre>
-     * Three byte tags.
-     * </pre>
-     *
-     * <code>repeated float repeated_float = 262142;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedFloat to set.
-     */
-    private void setRepeatedFloat(
-        int index, float value) {
-      ensureRepeatedFloatIsMutable();
-      repeatedFloat_.setFloat(index, value);
-    }
-    /**
-     * <pre>
-     * Three byte tags.
-     * </pre>
-     *
-     * <code>repeated float repeated_float = 262142;</code>
-     * @param value The repeatedFloat to add.
-     */
-    private void addRepeatedFloat(float value) {
-      ensureRepeatedFloatIsMutable();
-      repeatedFloat_.addFloat(value);
-    }
-    /**
-     * <pre>
-     * Three byte tags.
-     * </pre>
-     *
-     * <code>repeated float repeated_float = 262142;</code>
-     * @param values The repeatedFloat to add.
-     */
-    private void addAllRepeatedFloat(
-        java.lang.Iterable<? extends java.lang.Float> values) {
-      ensureRepeatedFloatIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedFloat_);
-    }
-    /**
-     * <pre>
-     * Three byte tags.
-     * </pre>
-     *
-     * <code>repeated float repeated_float = 262142;</code>
-     */
-    private void clearRepeatedFloat() {
-      repeatedFloat_ = emptyFloatList();
-    }
-
-    public static final int REPEATED_UINT64_FIELD_NUMBER = 262143;
-    private com.google.protobuf.Internal.LongList repeatedUint64_;
-    /**
-     * <code>repeated uint64 repeated_uint64 = 262143;</code>
-     * @return A list containing the repeatedUint64.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Long>
-        getRepeatedUint64List() {
-      return repeatedUint64_;
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 262143;</code>
-     * @return The count of repeatedUint64.
-     */
-    @java.lang.Override
-    public int getRepeatedUint64Count() {
-      return repeatedUint64_.size();
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 262143;</code>
-     * @param index The index of the element to return.
-     * @return The repeatedUint64 at the given index.
-     */
-    @java.lang.Override
-    public long getRepeatedUint64(int index) {
-      return repeatedUint64_.getLong(index);
-    }
-    private void ensureRepeatedUint64IsMutable() {
-      com.google.protobuf.Internal.LongList tmp = repeatedUint64_;
-      if (!tmp.isModifiable()) {
-        repeatedUint64_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 262143;</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedUint64 to set.
-     */
-    private void setRepeatedUint64(
-        int index, long value) {
-      ensureRepeatedUint64IsMutable();
-      repeatedUint64_.setLong(index, value);
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 262143;</code>
-     * @param value The repeatedUint64 to add.
-     */
-    private void addRepeatedUint64(long value) {
-      ensureRepeatedUint64IsMutable();
-      repeatedUint64_.addLong(value);
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 262143;</code>
-     * @param values The repeatedUint64 to add.
-     */
-    private void addAllRepeatedUint64(
-        java.lang.Iterable<? extends java.lang.Long> values) {
-      ensureRepeatedUint64IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedUint64_);
-    }
-    /**
-     * <code>repeated uint64 repeated_uint64 = 262143;</code>
-     */
-    private void clearRepeatedUint64() {
-      repeatedUint64_ = emptyLongList();
-    }
-
-    public static protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestRepeatedScalarDifferentTagSizes}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestRepeatedScalarDifferentTagSizes)
-        protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizesOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <pre>
-       * Parsing repeated fixed size values used to fail. This message needs to be
-       * used in order to get a tag of the right size; all of the repeated fields
-       * in TestAllTypes didn't trigger the check.
-       * </pre>
-       *
-       * <code>repeated fixed32 repeated_fixed32 = 12;</code>
-       * @return A list containing the repeatedFixed32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedFixed32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedFixed32List());
-      }
-      /**
-       * <pre>
-       * Parsing repeated fixed size values used to fail. This message needs to be
-       * used in order to get a tag of the right size; all of the repeated fields
-       * in TestAllTypes didn't trigger the check.
-       * </pre>
-       *
-       * <code>repeated fixed32 repeated_fixed32 = 12;</code>
-       * @return The count of repeatedFixed32.
-       */
-      @java.lang.Override
-      public int getRepeatedFixed32Count() {
-        return instance.getRepeatedFixed32Count();
-      }
-      /**
-       * <pre>
-       * Parsing repeated fixed size values used to fail. This message needs to be
-       * used in order to get a tag of the right size; all of the repeated fields
-       * in TestAllTypes didn't trigger the check.
-       * </pre>
-       *
-       * <code>repeated fixed32 repeated_fixed32 = 12;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedFixed32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedFixed32(int index) {
-        return instance.getRepeatedFixed32(index);
-      }
-      /**
-       * <pre>
-       * Parsing repeated fixed size values used to fail. This message needs to be
-       * used in order to get a tag of the right size; all of the repeated fields
-       * in TestAllTypes didn't trigger the check.
-       * </pre>
-       *
-       * <code>repeated fixed32 repeated_fixed32 = 12;</code>
-       * @param value The repeatedFixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedFixed32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedFixed32(index, value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Parsing repeated fixed size values used to fail. This message needs to be
-       * used in order to get a tag of the right size; all of the repeated fields
-       * in TestAllTypes didn't trigger the check.
-       * </pre>
-       *
-       * <code>repeated fixed32 repeated_fixed32 = 12;</code>
-       * @param value The repeatedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedFixed32(int value) {
-        copyOnWrite();
-        instance.addRepeatedFixed32(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Parsing repeated fixed size values used to fail. This message needs to be
-       * used in order to get a tag of the right size; all of the repeated fields
-       * in TestAllTypes didn't trigger the check.
-       * </pre>
-       *
-       * <code>repeated fixed32 repeated_fixed32 = 12;</code>
-       * @param values The repeatedFixed32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedFixed32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedFixed32(values);
-        return this;
-      }
-      /**
-       * <pre>
-       * Parsing repeated fixed size values used to fail. This message needs to be
-       * used in order to get a tag of the right size; all of the repeated fields
-       * in TestAllTypes didn't trigger the check.
-       * </pre>
-       *
-       * <code>repeated fixed32 repeated_fixed32 = 12;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedFixed32() {
-        copyOnWrite();
-        instance.clearRepeatedFixed32();
-        return this;
-      }
-
-      /**
-       * <pre>
-       * Check for a varint type, just for good measure.
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 13;</code>
-       * @return A list containing the repeatedInt32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedInt32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedInt32List());
-      }
-      /**
-       * <pre>
-       * Check for a varint type, just for good measure.
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 13;</code>
-       * @return The count of repeatedInt32.
-       */
-      @java.lang.Override
-      public int getRepeatedInt32Count() {
-        return instance.getRepeatedInt32Count();
-      }
-      /**
-       * <pre>
-       * Check for a varint type, just for good measure.
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 13;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedInt32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedInt32(int index) {
-        return instance.getRepeatedInt32(index);
-      }
-      /**
-       * <pre>
-       * Check for a varint type, just for good measure.
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 13;</code>
-       * @param value The repeatedInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedInt32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedInt32(index, value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Check for a varint type, just for good measure.
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 13;</code>
-       * @param value The repeatedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedInt32(int value) {
-        copyOnWrite();
-        instance.addRepeatedInt32(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Check for a varint type, just for good measure.
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 13;</code>
-       * @param values The repeatedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedInt32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedInt32(values);
-        return this;
-      }
-      /**
-       * <pre>
-       * Check for a varint type, just for good measure.
-       * </pre>
-       *
-       * <code>repeated int32 repeated_int32 = 13;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedInt32() {
-        copyOnWrite();
-        instance.clearRepeatedInt32();
-        return this;
-      }
-
-      /**
-       * <pre>
-       * These have two-byte tags.
-       * </pre>
-       *
-       * <code>repeated fixed64 repeated_fixed64 = 2046;</code>
-       * @return A list containing the repeatedFixed64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedFixed64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedFixed64List());
-      }
-      /**
-       * <pre>
-       * These have two-byte tags.
-       * </pre>
-       *
-       * <code>repeated fixed64 repeated_fixed64 = 2046;</code>
-       * @return The count of repeatedFixed64.
-       */
-      @java.lang.Override
-      public int getRepeatedFixed64Count() {
-        return instance.getRepeatedFixed64Count();
-      }
-      /**
-       * <pre>
-       * These have two-byte tags.
-       * </pre>
-       *
-       * <code>repeated fixed64 repeated_fixed64 = 2046;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedFixed64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedFixed64(int index) {
-        return instance.getRepeatedFixed64(index);
-      }
-      /**
-       * <pre>
-       * These have two-byte tags.
-       * </pre>
-       *
-       * <code>repeated fixed64 repeated_fixed64 = 2046;</code>
-       * @param value The repeatedFixed64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedFixed64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedFixed64(index, value);
-        return this;
-      }
-      /**
-       * <pre>
-       * These have two-byte tags.
-       * </pre>
-       *
-       * <code>repeated fixed64 repeated_fixed64 = 2046;</code>
-       * @param value The repeatedFixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedFixed64(long value) {
-        copyOnWrite();
-        instance.addRepeatedFixed64(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * These have two-byte tags.
-       * </pre>
-       *
-       * <code>repeated fixed64 repeated_fixed64 = 2046;</code>
-       * @param values The repeatedFixed64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedFixed64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedFixed64(values);
-        return this;
-      }
-      /**
-       * <pre>
-       * These have two-byte tags.
-       * </pre>
-       *
-       * <code>repeated fixed64 repeated_fixed64 = 2046;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedFixed64() {
-        copyOnWrite();
-        instance.clearRepeatedFixed64();
-        return this;
-      }
-
-      /**
-       * <code>repeated int64 repeated_int64 = 2047;</code>
-       * @return A list containing the repeatedInt64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedInt64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedInt64List());
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 2047;</code>
-       * @return The count of repeatedInt64.
-       */
-      @java.lang.Override
-      public int getRepeatedInt64Count() {
-        return instance.getRepeatedInt64Count();
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 2047;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedInt64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedInt64(int index) {
-        return instance.getRepeatedInt64(index);
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 2047;</code>
-       * @param value The repeatedInt64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedInt64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedInt64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 2047;</code>
-       * @param value The repeatedInt64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedInt64(long value) {
-        copyOnWrite();
-        instance.addRepeatedInt64(value);
-        return this;
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 2047;</code>
-       * @param values The repeatedInt64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedInt64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedInt64(values);
-        return this;
-      }
-      /**
-       * <code>repeated int64 repeated_int64 = 2047;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedInt64() {
-        copyOnWrite();
-        instance.clearRepeatedInt64();
-        return this;
-      }
-
-      /**
-       * <pre>
-       * Three byte tags.
-       * </pre>
-       *
-       * <code>repeated float repeated_float = 262142;</code>
-       * @return A list containing the repeatedFloat.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Float>
-          getRepeatedFloatList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedFloatList());
-      }
-      /**
-       * <pre>
-       * Three byte tags.
-       * </pre>
-       *
-       * <code>repeated float repeated_float = 262142;</code>
-       * @return The count of repeatedFloat.
-       */
-      @java.lang.Override
-      public int getRepeatedFloatCount() {
-        return instance.getRepeatedFloatCount();
-      }
-      /**
-       * <pre>
-       * Three byte tags.
-       * </pre>
-       *
-       * <code>repeated float repeated_float = 262142;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedFloat at the given index.
-       */
-      @java.lang.Override
-      public float getRepeatedFloat(int index) {
-        return instance.getRepeatedFloat(index);
-      }
-      /**
-       * <pre>
-       * Three byte tags.
-       * </pre>
-       *
-       * <code>repeated float repeated_float = 262142;</code>
-       * @param value The repeatedFloat to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedFloat(
-          int index, float value) {
-        copyOnWrite();
-        instance.setRepeatedFloat(index, value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Three byte tags.
-       * </pre>
-       *
-       * <code>repeated float repeated_float = 262142;</code>
-       * @param value The repeatedFloat to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedFloat(float value) {
-        copyOnWrite();
-        instance.addRepeatedFloat(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * Three byte tags.
-       * </pre>
-       *
-       * <code>repeated float repeated_float = 262142;</code>
-       * @param values The repeatedFloat to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedFloat(
-          java.lang.Iterable<? extends java.lang.Float> values) {
-        copyOnWrite();
-        instance.addAllRepeatedFloat(values);
-        return this;
-      }
-      /**
-       * <pre>
-       * Three byte tags.
-       * </pre>
-       *
-       * <code>repeated float repeated_float = 262142;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedFloat() {
-        copyOnWrite();
-        instance.clearRepeatedFloat();
-        return this;
-      }
-
-      /**
-       * <code>repeated uint64 repeated_uint64 = 262143;</code>
-       * @return A list containing the repeatedUint64.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Long>
-          getRepeatedUint64List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedUint64List());
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 262143;</code>
-       * @return The count of repeatedUint64.
-       */
-      @java.lang.Override
-      public int getRepeatedUint64Count() {
-        return instance.getRepeatedUint64Count();
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 262143;</code>
-       * @param index The index of the element to return.
-       * @return The repeatedUint64 at the given index.
-       */
-      @java.lang.Override
-      public long getRepeatedUint64(int index) {
-        return instance.getRepeatedUint64(index);
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 262143;</code>
-       * @param value The repeatedUint64 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedUint64(
-          int index, long value) {
-        copyOnWrite();
-        instance.setRepeatedUint64(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 262143;</code>
-       * @param value The repeatedUint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedUint64(long value) {
-        copyOnWrite();
-        instance.addRepeatedUint64(value);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 262143;</code>
-       * @param values The repeatedUint64 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedUint64(
-          java.lang.Iterable<? extends java.lang.Long> values) {
-        copyOnWrite();
-        instance.addAllRepeatedUint64(values);
-        return this;
-      }
-      /**
-       * <code>repeated uint64 repeated_uint64 = 262143;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedUint64() {
-        copyOnWrite();
-        instance.clearRepeatedUint64();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestRepeatedScalarDifferentTagSizes)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "repeatedFixed32_",
-              "repeatedInt32_",
-              "repeatedFixed64_",
-              "repeatedInt64_",
-              "repeatedFloat_",
-              "repeatedUint64_",
-            };
-            java.lang.String info =
-                "\u0001\u0006\u0000\u0000\f\uffff\u001f\u0006\u0000\u0006\u0000\f\u0018\r\u0016\u07fe" +
-                "\u0017\u07ff\u0014\ufffe\u001f\u0013\uffff\u001f\u0015";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestRepeatedScalarDifferentTagSizes)
-    private static final protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes DEFAULT_INSTANCE;
-    static {
-      TestRepeatedScalarDifferentTagSizes defaultInstance = new TestRepeatedScalarDifferentTagSizes();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestRepeatedScalarDifferentTagSizes.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestRepeatedScalarDifferentTagSizes getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestRepeatedScalarDifferentTagSizes> PARSER;
-
-    public static com.google.protobuf.Parser<TestRepeatedScalarDifferentTagSizes> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestParsingMergeOrBuilder extends 
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestParsingMerge)
-       com.google.protobuf.GeneratedMessageLite.
-            ExtendableMessageOrBuilder<
-                TestParsingMerge, TestParsingMerge.Builder> {
-
-    /**
-     * <code>required .protobuf_unittest.TestAllTypes required_all_types = 1;</code>
-     * @return Whether the requiredAllTypes field is set.
-     */
-    boolean hasRequiredAllTypes();
-    /**
-     * <code>required .protobuf_unittest.TestAllTypes required_all_types = 1;</code>
-     * @return The requiredAllTypes.
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes getRequiredAllTypes();
-
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes optional_all_types = 2;</code>
-     * @return Whether the optionalAllTypes field is set.
-     */
-    boolean hasOptionalAllTypes();
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes optional_all_types = 2;</code>
-     * @return The optionalAllTypes.
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes getOptionalAllTypes();
-
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-     */
-    java.util.List<protobuf_unittest.UnittestProto.TestAllTypes> 
-        getRepeatedAllTypesList();
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes getRepeatedAllTypes(int index);
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-     */
-    int getRepeatedAllTypesCount();
-
-    /**
-     * <code>optional group OptionalGroup = 10 { ... }</code>
-     * @return Whether the optionalgroup field is set.
-     */
-    boolean hasOptionalGroup();
-    /**
-     * <code>optional group OptionalGroup = 10 { ... }</code>
-     * @return The optionalgroup.
-     */
-    protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup getOptionalGroup();
-
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    java.util.List<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup> 
-        getRepeatedGroupList();
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup getRepeatedGroup(int index);
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    int getRepeatedGroupCount();
-  }
-  /**
-   * <pre>
-   * Test that if an optional or required message/group field appears multiple
-   * times in the input, they need to be merged.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.TestParsingMerge}
-   */
-  public  static final class TestParsingMerge extends
-      com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
-        TestParsingMerge, TestParsingMerge.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestParsingMerge)
-      TestParsingMergeOrBuilder {
-    private TestParsingMerge() {
-      repeatedAllTypes_ = emptyProtobufList();
-      repeatedGroup_ = emptyProtobufList();
-    }
-    public interface RepeatedFieldsGeneratorOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-       */
-      java.util.List<protobuf_unittest.UnittestProto.TestAllTypes> 
-          getField1List();
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-       */
-      protobuf_unittest.UnittestProto.TestAllTypes getField1(int index);
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-       */
-      int getField1Count();
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-       */
-      java.util.List<protobuf_unittest.UnittestProto.TestAllTypes> 
-          getField2List();
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-       */
-      protobuf_unittest.UnittestProto.TestAllTypes getField2(int index);
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-       */
-      int getField2Count();
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-       */
-      java.util.List<protobuf_unittest.UnittestProto.TestAllTypes> 
-          getField3List();
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-       */
-      protobuf_unittest.UnittestProto.TestAllTypes getField3(int index);
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-       */
-      int getField3Count();
-
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      java.util.List<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1> 
-          getGroup1List();
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 getGroup1(int index);
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      int getGroup1Count();
-
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      java.util.List<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2> 
-          getGroup2List();
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 getGroup2(int index);
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      int getGroup2Count();
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-       */
-      java.util.List<protobuf_unittest.UnittestProto.TestAllTypes> 
-          getExt1List();
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-       */
-      protobuf_unittest.UnittestProto.TestAllTypes getExt1(int index);
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-       */
-      int getExt1Count();
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-       */
-      java.util.List<protobuf_unittest.UnittestProto.TestAllTypes> 
-          getExt2List();
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-       */
-      protobuf_unittest.UnittestProto.TestAllTypes getExt2(int index);
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-       */
-      int getExt2Count();
-    }
-    /**
-     * <pre>
-     * RepeatedFieldsGenerator defines matching field types as TestParsingMerge,
-     * except that all fields are repeated. In the tests, we will serialize the
-     * RepeatedFieldsGenerator to bytes, and parse the bytes to TestParsingMerge.
-     * Repeated fields in RepeatedFieldsGenerator are expected to be merged into
-     * the corresponding required/optional fields in TestParsingMerge.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator}
-     */
-    public  static final class RepeatedFieldsGenerator extends
-        com.google.protobuf.GeneratedMessageLite<
-            RepeatedFieldsGenerator, RepeatedFieldsGenerator.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator)
-        RepeatedFieldsGeneratorOrBuilder {
-      private RepeatedFieldsGenerator() {
-        field1_ = emptyProtobufList();
-        field2_ = emptyProtobufList();
-        field3_ = emptyProtobufList();
-        group1_ = emptyProtobufList();
-        group2_ = emptyProtobufList();
-        ext1_ = emptyProtobufList();
-        ext2_ = emptyProtobufList();
-      }
-      public interface Group1OrBuilder extends
-          // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group1)
-          com.google.protobuf.MessageLiteOrBuilder {
-
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes field1 = 11;</code>
-         * @return Whether the field1 field is set.
-         */
-        boolean hasField1();
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes field1 = 11;</code>
-         * @return The field1.
-         */
-        protobuf_unittest.UnittestProto.TestAllTypes getField1();
-      }
-      /**
-       * Protobuf type {@code protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group1}
-       */
-      public  static final class Group1 extends
-          com.google.protobuf.GeneratedMessageLite<
-              Group1, Group1.Builder> implements
-          // @@protoc_insertion_point(message_implements:protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group1)
-          Group1OrBuilder {
-        private Group1() {
-        }
-        private int bitField0_;
-        public static final int FIELD1_FIELD_NUMBER = 11;
-        private protobuf_unittest.UnittestProto.TestAllTypes field1_;
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes field1 = 11;</code>
-         */
-        @java.lang.Override
-        public boolean hasField1() {
-          return ((bitField0_ & 0x00000001) != 0);
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes field1 = 11;</code>
-         */
-        @java.lang.Override
-        public protobuf_unittest.UnittestProto.TestAllTypes getField1() {
-          return field1_ == null ? protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance() : field1_;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes field1 = 11;</code>
-         */
-        private void setField1(protobuf_unittest.UnittestProto.TestAllTypes value) {
-          value.getClass();
-  field1_ = value;
-          bitField0_ |= 0x00000001;
-          }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes field1 = 11;</code>
-         */
-        @java.lang.SuppressWarnings({"ReferenceEquality"})
-        private void mergeField1(protobuf_unittest.UnittestProto.TestAllTypes value) {
-          value.getClass();
-  if (field1_ != null &&
-              field1_ != protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance()) {
-            field1_ =
-              protobuf_unittest.UnittestProto.TestAllTypes.newBuilder(field1_).mergeFrom(value).buildPartial();
-          } else {
-            field1_ = value;
-          }
-          bitField0_ |= 0x00000001;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes field1 = 11;</code>
-         */
-        private void clearField1() {  field1_ = null;
-          bitField0_ = (bitField0_ & ~0x00000001);
-        }
-
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 parseFrom(
-            java.nio.ByteBuffer data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 parseFrom(
-            java.nio.ByteBuffer data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 parseFrom(
-            com.google.protobuf.ByteString data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 parseFrom(
-            com.google.protobuf.ByteString data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 parseFrom(byte[] data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 parseFrom(
-            byte[] data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 parseFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 parseFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 parseDelimitedFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 parseDelimitedFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 parseFrom(
-            com.google.protobuf.CodedInputStream input)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 parseFrom(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input, extensionRegistry);
-        }
-
-        public static Builder newBuilder() {
-          return (Builder) DEFAULT_INSTANCE.createBuilder();
-        }
-        public static Builder newBuilder(protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 prototype) {
-          return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-        }
-
-        /**
-         * Protobuf type {@code protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group1}
-         */
-        public static final class Builder extends
-            com.google.protobuf.GeneratedMessageLite.Builder<
-              protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1, Builder> implements
-            // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group1)
-            protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1OrBuilder {
-          // Construct using protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1.newBuilder()
-          private Builder() {
-            super(DEFAULT_INSTANCE);
-          }
-
-
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypes field1 = 11;</code>
-           */
-          @java.lang.Override
-          public boolean hasField1() {
-            return instance.hasField1();
-          }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypes field1 = 11;</code>
-           */
-          @java.lang.Override
-          public protobuf_unittest.UnittestProto.TestAllTypes getField1() {
-            return instance.getField1();
-          }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypes field1 = 11;</code>
-           */
-          public Builder setField1(protobuf_unittest.UnittestProto.TestAllTypes value) {
-            copyOnWrite();
-            instance.setField1(value);
-            return this;
-            }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypes field1 = 11;</code>
-           */
-          public Builder setField1(
-              protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-            copyOnWrite();
-            instance.setField1(builderForValue.build());
-            return this;
-          }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypes field1 = 11;</code>
-           */
-          public Builder mergeField1(protobuf_unittest.UnittestProto.TestAllTypes value) {
-            copyOnWrite();
-            instance.mergeField1(value);
-            return this;
-          }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypes field1 = 11;</code>
-           */
-          public Builder clearField1() {  copyOnWrite();
-            instance.clearField1();
-            return this;
-          }
-
-          // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group1)
-        }
-        @java.lang.Override
-        @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-        protected final java.lang.Object dynamicMethod(
-            com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-            java.lang.Object arg0, java.lang.Object arg1) {
-          switch (method) {
-            case NEW_MUTABLE_INSTANCE: {
-              return new protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1();
-            }
-            case NEW_BUILDER: {
-              return new Builder();
-            }
-            case BUILD_MESSAGE_INFO: {
-                java.lang.Object[] objects = new java.lang.Object[] {
-                  "bitField0_",
-                  "field1_",
-                };
-                java.lang.String info =
-                    "\u0001\u0001\u0000\u0001\u000b\u000b\u0001\u0000\u0000\u0000\u000b\u1009\u0000";
-                return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-            }
-            // fall through
-            case GET_DEFAULT_INSTANCE: {
-              return DEFAULT_INSTANCE;
-            }
-            case GET_PARSER: {
-              com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1> parser = PARSER;
-              if (parser == null) {
-                synchronized (protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1.class) {
-                  parser = PARSER;
-                  if (parser == null) {
-                    parser =
-                        new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1>(
-                            DEFAULT_INSTANCE);
-                    PARSER = parser;
-                  }
-                }
-              }
-              return parser;
-          }
-          case GET_MEMOIZED_IS_INITIALIZED: {
-            return (byte) 1;
-          }
-          case SET_MEMOIZED_IS_INITIALIZED: {
-            return null;
-          }
-          }
-          throw new UnsupportedOperationException();
-        }
-
-
-        // @@protoc_insertion_point(class_scope:protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group1)
-        private static final protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 DEFAULT_INSTANCE;
-        static {
-          Group1 defaultInstance = new Group1();
-          // New instances are implicitly immutable so no need to make
-          // immutable.
-          DEFAULT_INSTANCE = defaultInstance;
-          com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-            Group1.class, defaultInstance);
-        }
-
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 getDefaultInstance() {
-          return DEFAULT_INSTANCE;
-        }
-
-        private static volatile com.google.protobuf.Parser<Group1> PARSER;
-
-        public static com.google.protobuf.Parser<Group1> parser() {
-          return DEFAULT_INSTANCE.getParserForType();
-        }
-      }
-
-      public interface Group2OrBuilder extends
-          // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group2)
-          com.google.protobuf.MessageLiteOrBuilder {
-
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes field1 = 21;</code>
-         * @return Whether the field1 field is set.
-         */
-        boolean hasField1();
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes field1 = 21;</code>
-         * @return The field1.
-         */
-        protobuf_unittest.UnittestProto.TestAllTypes getField1();
-      }
-      /**
-       * Protobuf type {@code protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group2}
-       */
-      public  static final class Group2 extends
-          com.google.protobuf.GeneratedMessageLite<
-              Group2, Group2.Builder> implements
-          // @@protoc_insertion_point(message_implements:protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group2)
-          Group2OrBuilder {
-        private Group2() {
-        }
-        private int bitField0_;
-        public static final int FIELD1_FIELD_NUMBER = 21;
-        private protobuf_unittest.UnittestProto.TestAllTypes field1_;
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes field1 = 21;</code>
-         */
-        @java.lang.Override
-        public boolean hasField1() {
-          return ((bitField0_ & 0x00000001) != 0);
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes field1 = 21;</code>
-         */
-        @java.lang.Override
-        public protobuf_unittest.UnittestProto.TestAllTypes getField1() {
-          return field1_ == null ? protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance() : field1_;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes field1 = 21;</code>
-         */
-        private void setField1(protobuf_unittest.UnittestProto.TestAllTypes value) {
-          value.getClass();
-  field1_ = value;
-          bitField0_ |= 0x00000001;
-          }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes field1 = 21;</code>
-         */
-        @java.lang.SuppressWarnings({"ReferenceEquality"})
-        private void mergeField1(protobuf_unittest.UnittestProto.TestAllTypes value) {
-          value.getClass();
-  if (field1_ != null &&
-              field1_ != protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance()) {
-            field1_ =
-              protobuf_unittest.UnittestProto.TestAllTypes.newBuilder(field1_).mergeFrom(value).buildPartial();
-          } else {
-            field1_ = value;
-          }
-          bitField0_ |= 0x00000001;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes field1 = 21;</code>
-         */
-        private void clearField1() {  field1_ = null;
-          bitField0_ = (bitField0_ & ~0x00000001);
-        }
-
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 parseFrom(
-            java.nio.ByteBuffer data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 parseFrom(
-            java.nio.ByteBuffer data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 parseFrom(
-            com.google.protobuf.ByteString data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 parseFrom(
-            com.google.protobuf.ByteString data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 parseFrom(byte[] data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 parseFrom(
-            byte[] data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, data, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 parseFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 parseFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 parseDelimitedFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 parseDelimitedFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 parseFrom(
-            com.google.protobuf.CodedInputStream input)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input);
-        }
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 parseFrom(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return com.google.protobuf.GeneratedMessageLite.parseFrom(
-              DEFAULT_INSTANCE, input, extensionRegistry);
-        }
-
-        public static Builder newBuilder() {
-          return (Builder) DEFAULT_INSTANCE.createBuilder();
-        }
-        public static Builder newBuilder(protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 prototype) {
-          return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-        }
-
-        /**
-         * Protobuf type {@code protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group2}
-         */
-        public static final class Builder extends
-            com.google.protobuf.GeneratedMessageLite.Builder<
-              protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2, Builder> implements
-            // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group2)
-            protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2OrBuilder {
-          // Construct using protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2.newBuilder()
-          private Builder() {
-            super(DEFAULT_INSTANCE);
-          }
-
-
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypes field1 = 21;</code>
-           */
-          @java.lang.Override
-          public boolean hasField1() {
-            return instance.hasField1();
-          }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypes field1 = 21;</code>
-           */
-          @java.lang.Override
-          public protobuf_unittest.UnittestProto.TestAllTypes getField1() {
-            return instance.getField1();
-          }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypes field1 = 21;</code>
-           */
-          public Builder setField1(protobuf_unittest.UnittestProto.TestAllTypes value) {
-            copyOnWrite();
-            instance.setField1(value);
-            return this;
-            }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypes field1 = 21;</code>
-           */
-          public Builder setField1(
-              protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-            copyOnWrite();
-            instance.setField1(builderForValue.build());
-            return this;
-          }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypes field1 = 21;</code>
-           */
-          public Builder mergeField1(protobuf_unittest.UnittestProto.TestAllTypes value) {
-            copyOnWrite();
-            instance.mergeField1(value);
-            return this;
-          }
-          /**
-           * <code>optional .protobuf_unittest.TestAllTypes field1 = 21;</code>
-           */
-          public Builder clearField1() {  copyOnWrite();
-            instance.clearField1();
-            return this;
-          }
-
-          // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group2)
-        }
-        @java.lang.Override
-        @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-        protected final java.lang.Object dynamicMethod(
-            com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-            java.lang.Object arg0, java.lang.Object arg1) {
-          switch (method) {
-            case NEW_MUTABLE_INSTANCE: {
-              return new protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2();
-            }
-            case NEW_BUILDER: {
-              return new Builder();
-            }
-            case BUILD_MESSAGE_INFO: {
-                java.lang.Object[] objects = new java.lang.Object[] {
-                  "bitField0_",
-                  "field1_",
-                };
-                java.lang.String info =
-                    "\u0001\u0001\u0000\u0001\u0015\u0015\u0001\u0000\u0000\u0000\u0015\u1009\u0000";
-                return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-            }
-            // fall through
-            case GET_DEFAULT_INSTANCE: {
-              return DEFAULT_INSTANCE;
-            }
-            case GET_PARSER: {
-              com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2> parser = PARSER;
-              if (parser == null) {
-                synchronized (protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2.class) {
-                  parser = PARSER;
-                  if (parser == null) {
-                    parser =
-                        new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2>(
-                            DEFAULT_INSTANCE);
-                    PARSER = parser;
-                  }
-                }
-              }
-              return parser;
-          }
-          case GET_MEMOIZED_IS_INITIALIZED: {
-            return (byte) 1;
-          }
-          case SET_MEMOIZED_IS_INITIALIZED: {
-            return null;
-          }
-          }
-          throw new UnsupportedOperationException();
-        }
-
-
-        // @@protoc_insertion_point(class_scope:protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group2)
-        private static final protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 DEFAULT_INSTANCE;
-        static {
-          Group2 defaultInstance = new Group2();
-          // New instances are implicitly immutable so no need to make
-          // immutable.
-          DEFAULT_INSTANCE = defaultInstance;
-          com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-            Group2.class, defaultInstance);
-        }
-
-        public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 getDefaultInstance() {
-          return DEFAULT_INSTANCE;
-        }
-
-        private static volatile com.google.protobuf.Parser<Group2> PARSER;
-
-        public static com.google.protobuf.Parser<Group2> parser() {
-          return DEFAULT_INSTANCE.getParserForType();
-        }
-      }
-
-      public static final int FIELD1_FIELD_NUMBER = 1;
-      private com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestAllTypes> field1_;
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes> getField1List() {
-        return field1_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-       */
-      public java.util.List<? extends protobuf_unittest.UnittestProto.TestAllTypesOrBuilder> 
-          getField1OrBuilderList() {
-        return field1_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-       */
-      @java.lang.Override
-      public int getField1Count() {
-        return field1_.size();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes getField1(int index) {
-        return field1_.get(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-       */
-      public protobuf_unittest.UnittestProto.TestAllTypesOrBuilder getField1OrBuilder(
-          int index) {
-        return field1_.get(index);
-      }
-      private void ensureField1IsMutable() {
-        com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestAllTypes> tmp = field1_;
-        if (!tmp.isModifiable()) {
-          field1_ =
-              com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-         }
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-       */
-      private void setField1(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  ensureField1IsMutable();
-        field1_.set(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-       */
-      private void addField1(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  ensureField1IsMutable();
-        field1_.add(value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-       */
-      private void addField1(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  ensureField1IsMutable();
-        field1_.add(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-       */
-      private void addAllField1(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes> values) {
-        ensureField1IsMutable();
-        com.google.protobuf.AbstractMessageLite.addAll(
-            values, field1_);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-       */
-      private void clearField1() {
-        field1_ = emptyProtobufList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-       */
-      private void removeField1(int index) {
-        ensureField1IsMutable();
-        field1_.remove(index);
-      }
-
-      public static final int FIELD2_FIELD_NUMBER = 2;
-      private com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestAllTypes> field2_;
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes> getField2List() {
-        return field2_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-       */
-      public java.util.List<? extends protobuf_unittest.UnittestProto.TestAllTypesOrBuilder> 
-          getField2OrBuilderList() {
-        return field2_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-       */
-      @java.lang.Override
-      public int getField2Count() {
-        return field2_.size();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes getField2(int index) {
-        return field2_.get(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-       */
-      public protobuf_unittest.UnittestProto.TestAllTypesOrBuilder getField2OrBuilder(
-          int index) {
-        return field2_.get(index);
-      }
-      private void ensureField2IsMutable() {
-        com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestAllTypes> tmp = field2_;
-        if (!tmp.isModifiable()) {
-          field2_ =
-              com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-         }
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-       */
-      private void setField2(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  ensureField2IsMutable();
-        field2_.set(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-       */
-      private void addField2(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  ensureField2IsMutable();
-        field2_.add(value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-       */
-      private void addField2(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  ensureField2IsMutable();
-        field2_.add(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-       */
-      private void addAllField2(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes> values) {
-        ensureField2IsMutable();
-        com.google.protobuf.AbstractMessageLite.addAll(
-            values, field2_);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-       */
-      private void clearField2() {
-        field2_ = emptyProtobufList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-       */
-      private void removeField2(int index) {
-        ensureField2IsMutable();
-        field2_.remove(index);
-      }
-
-      public static final int FIELD3_FIELD_NUMBER = 3;
-      private com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestAllTypes> field3_;
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes> getField3List() {
-        return field3_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-       */
-      public java.util.List<? extends protobuf_unittest.UnittestProto.TestAllTypesOrBuilder> 
-          getField3OrBuilderList() {
-        return field3_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-       */
-      @java.lang.Override
-      public int getField3Count() {
-        return field3_.size();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes getField3(int index) {
-        return field3_.get(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-       */
-      public protobuf_unittest.UnittestProto.TestAllTypesOrBuilder getField3OrBuilder(
-          int index) {
-        return field3_.get(index);
-      }
-      private void ensureField3IsMutable() {
-        com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestAllTypes> tmp = field3_;
-        if (!tmp.isModifiable()) {
-          field3_ =
-              com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-         }
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-       */
-      private void setField3(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  ensureField3IsMutable();
-        field3_.set(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-       */
-      private void addField3(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  ensureField3IsMutable();
-        field3_.add(value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-       */
-      private void addField3(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  ensureField3IsMutable();
-        field3_.add(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-       */
-      private void addAllField3(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes> values) {
-        ensureField3IsMutable();
-        com.google.protobuf.AbstractMessageLite.addAll(
-            values, field3_);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-       */
-      private void clearField3() {
-        field3_ = emptyProtobufList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-       */
-      private void removeField3(int index) {
-        ensureField3IsMutable();
-        field3_.remove(index);
-      }
-
-      public static final int GROUP1_FIELD_NUMBER = 10;
-      private com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1> group1_;
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1> getGroup1List() {
-        return group1_;
-      }
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      public java.util.List<? extends protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1OrBuilder> 
-          getGroup1OrBuilderList() {
-        return group1_;
-      }
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      @java.lang.Override
-      public int getGroup1Count() {
-        return group1_.size();
-      }
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 getGroup1(int index) {
-        return group1_.get(index);
-      }
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      public protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1OrBuilder getGroup1OrBuilder(
-          int index) {
-        return group1_.get(index);
-      }
-      private void ensureGroup1IsMutable() {
-        com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1> tmp = group1_;
-        if (!tmp.isModifiable()) {
-          group1_ =
-              com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-         }
-      }
-
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      private void setGroup1(
-          int index, protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 value) {
-        value.getClass();
-  ensureGroup1IsMutable();
-        group1_.set(index, value);
-      }
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      private void addGroup1(protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 value) {
-        value.getClass();
-  ensureGroup1IsMutable();
-        group1_.add(value);
-      }
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      private void addGroup1(
-          int index, protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 value) {
-        value.getClass();
-  ensureGroup1IsMutable();
-        group1_.add(index, value);
-      }
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      private void addAllGroup1(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1> values) {
-        ensureGroup1IsMutable();
-        com.google.protobuf.AbstractMessageLite.addAll(
-            values, group1_);
-      }
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      private void clearGroup1() {
-        group1_ = emptyProtobufList();
-      }
-      /**
-       * <code>repeated group Group1 = 10 { ... }</code>
-       */
-      private void removeGroup1(int index) {
-        ensureGroup1IsMutable();
-        group1_.remove(index);
-      }
-
-      public static final int GROUP2_FIELD_NUMBER = 20;
-      private com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2> group2_;
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2> getGroup2List() {
-        return group2_;
-      }
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      public java.util.List<? extends protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2OrBuilder> 
-          getGroup2OrBuilderList() {
-        return group2_;
-      }
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      @java.lang.Override
-      public int getGroup2Count() {
-        return group2_.size();
-      }
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 getGroup2(int index) {
-        return group2_.get(index);
-      }
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      public protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2OrBuilder getGroup2OrBuilder(
-          int index) {
-        return group2_.get(index);
-      }
-      private void ensureGroup2IsMutable() {
-        com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2> tmp = group2_;
-        if (!tmp.isModifiable()) {
-          group2_ =
-              com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-         }
-      }
-
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      private void setGroup2(
-          int index, protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 value) {
-        value.getClass();
-  ensureGroup2IsMutable();
-        group2_.set(index, value);
-      }
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      private void addGroup2(protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 value) {
-        value.getClass();
-  ensureGroup2IsMutable();
-        group2_.add(value);
-      }
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      private void addGroup2(
-          int index, protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 value) {
-        value.getClass();
-  ensureGroup2IsMutable();
-        group2_.add(index, value);
-      }
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      private void addAllGroup2(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2> values) {
-        ensureGroup2IsMutable();
-        com.google.protobuf.AbstractMessageLite.addAll(
-            values, group2_);
-      }
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      private void clearGroup2() {
-        group2_ = emptyProtobufList();
-      }
-      /**
-       * <code>repeated group Group2 = 20 { ... }</code>
-       */
-      private void removeGroup2(int index) {
-        ensureGroup2IsMutable();
-        group2_.remove(index);
-      }
-
-      public static final int EXT1_FIELD_NUMBER = 1000;
-      private com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestAllTypes> ext1_;
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes> getExt1List() {
-        return ext1_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-       */
-      public java.util.List<? extends protobuf_unittest.UnittestProto.TestAllTypesOrBuilder> 
-          getExt1OrBuilderList() {
-        return ext1_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-       */
-      @java.lang.Override
-      public int getExt1Count() {
-        return ext1_.size();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes getExt1(int index) {
-        return ext1_.get(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-       */
-      public protobuf_unittest.UnittestProto.TestAllTypesOrBuilder getExt1OrBuilder(
-          int index) {
-        return ext1_.get(index);
-      }
-      private void ensureExt1IsMutable() {
-        com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestAllTypes> tmp = ext1_;
-        if (!tmp.isModifiable()) {
-          ext1_ =
-              com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-         }
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-       */
-      private void setExt1(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  ensureExt1IsMutable();
-        ext1_.set(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-       */
-      private void addExt1(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  ensureExt1IsMutable();
-        ext1_.add(value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-       */
-      private void addExt1(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  ensureExt1IsMutable();
-        ext1_.add(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-       */
-      private void addAllExt1(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes> values) {
-        ensureExt1IsMutable();
-        com.google.protobuf.AbstractMessageLite.addAll(
-            values, ext1_);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-       */
-      private void clearExt1() {
-        ext1_ = emptyProtobufList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-       */
-      private void removeExt1(int index) {
-        ensureExt1IsMutable();
-        ext1_.remove(index);
-      }
-
-      public static final int EXT2_FIELD_NUMBER = 1001;
-      private com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestAllTypes> ext2_;
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes> getExt2List() {
-        return ext2_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-       */
-      public java.util.List<? extends protobuf_unittest.UnittestProto.TestAllTypesOrBuilder> 
-          getExt2OrBuilderList() {
-        return ext2_;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-       */
-      @java.lang.Override
-      public int getExt2Count() {
-        return ext2_.size();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes getExt2(int index) {
-        return ext2_.get(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-       */
-      public protobuf_unittest.UnittestProto.TestAllTypesOrBuilder getExt2OrBuilder(
-          int index) {
-        return ext2_.get(index);
-      }
-      private void ensureExt2IsMutable() {
-        com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestAllTypes> tmp = ext2_;
-        if (!tmp.isModifiable()) {
-          ext2_ =
-              com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-         }
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-       */
-      private void setExt2(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  ensureExt2IsMutable();
-        ext2_.set(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-       */
-      private void addExt2(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  ensureExt2IsMutable();
-        ext2_.add(value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-       */
-      private void addExt2(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  ensureExt2IsMutable();
-        ext2_.add(index, value);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-       */
-      private void addAllExt2(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes> values) {
-        ensureExt2IsMutable();
-        com.google.protobuf.AbstractMessageLite.addAll(
-            values, ext2_);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-       */
-      private void clearExt2() {
-        ext2_ = emptyProtobufList();
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-       */
-      private void removeExt2(int index) {
-        ensureExt2IsMutable();
-        ext2_.remove(index);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * <pre>
-       * RepeatedFieldsGenerator defines matching field types as TestParsingMerge,
-       * except that all fields are repeated. In the tests, we will serialize the
-       * RepeatedFieldsGenerator to bytes, and parse the bytes to TestParsingMerge.
-       * Repeated fields in RepeatedFieldsGenerator are expected to be merged into
-       * the corresponding required/optional fields in TestParsingMerge.
-       * </pre>
-       *
-       * Protobuf type {@code protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator)
-          protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGeneratorOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-         */
-        @java.lang.Override
-        public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes> getField1List() {
-          return java.util.Collections.unmodifiableList(
-              instance.getField1List());
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-         */
-        @java.lang.Override
-        public int getField1Count() {
-          return instance.getField1Count();
-        }/**
-         * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-         */
-        @java.lang.Override
-        public protobuf_unittest.UnittestProto.TestAllTypes getField1(int index) {
-          return instance.getField1(index);
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-         */
-        public Builder setField1(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.setField1(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-         */
-        public Builder setField1(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-          copyOnWrite();
-          instance.setField1(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-         */
-        public Builder addField1(protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.addField1(value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-         */
-        public Builder addField1(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.addField1(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-         */
-        public Builder addField1(
-            protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-          copyOnWrite();
-          instance.addField1(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-         */
-        public Builder addField1(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-          copyOnWrite();
-          instance.addField1(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-         */
-        public Builder addAllField1(
-            java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes> values) {
-          copyOnWrite();
-          instance.addAllField1(values);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-         */
-        public Builder clearField1() {
-          copyOnWrite();
-          instance.clearField1();
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field1 = 1;</code>
-         */
-        public Builder removeField1(int index) {
-          copyOnWrite();
-          instance.removeField1(index);
-          return this;
-        }
-
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-         */
-        @java.lang.Override
-        public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes> getField2List() {
-          return java.util.Collections.unmodifiableList(
-              instance.getField2List());
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-         */
-        @java.lang.Override
-        public int getField2Count() {
-          return instance.getField2Count();
-        }/**
-         * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-         */
-        @java.lang.Override
-        public protobuf_unittest.UnittestProto.TestAllTypes getField2(int index) {
-          return instance.getField2(index);
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-         */
-        public Builder setField2(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.setField2(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-         */
-        public Builder setField2(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-          copyOnWrite();
-          instance.setField2(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-         */
-        public Builder addField2(protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.addField2(value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-         */
-        public Builder addField2(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.addField2(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-         */
-        public Builder addField2(
-            protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-          copyOnWrite();
-          instance.addField2(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-         */
-        public Builder addField2(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-          copyOnWrite();
-          instance.addField2(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-         */
-        public Builder addAllField2(
-            java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes> values) {
-          copyOnWrite();
-          instance.addAllField2(values);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-         */
-        public Builder clearField2() {
-          copyOnWrite();
-          instance.clearField2();
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field2 = 2;</code>
-         */
-        public Builder removeField2(int index) {
-          copyOnWrite();
-          instance.removeField2(index);
-          return this;
-        }
-
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-         */
-        @java.lang.Override
-        public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes> getField3List() {
-          return java.util.Collections.unmodifiableList(
-              instance.getField3List());
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-         */
-        @java.lang.Override
-        public int getField3Count() {
-          return instance.getField3Count();
-        }/**
-         * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-         */
-        @java.lang.Override
-        public protobuf_unittest.UnittestProto.TestAllTypes getField3(int index) {
-          return instance.getField3(index);
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-         */
-        public Builder setField3(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.setField3(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-         */
-        public Builder setField3(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-          copyOnWrite();
-          instance.setField3(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-         */
-        public Builder addField3(protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.addField3(value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-         */
-        public Builder addField3(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.addField3(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-         */
-        public Builder addField3(
-            protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-          copyOnWrite();
-          instance.addField3(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-         */
-        public Builder addField3(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-          copyOnWrite();
-          instance.addField3(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-         */
-        public Builder addAllField3(
-            java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes> values) {
-          copyOnWrite();
-          instance.addAllField3(values);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-         */
-        public Builder clearField3() {
-          copyOnWrite();
-          instance.clearField3();
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes field3 = 3;</code>
-         */
-        public Builder removeField3(int index) {
-          copyOnWrite();
-          instance.removeField3(index);
-          return this;
-        }
-
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        @java.lang.Override
-        public java.util.List<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1> getGroup1List() {
-          return java.util.Collections.unmodifiableList(
-              instance.getGroup1List());
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        @java.lang.Override
-        public int getGroup1Count() {
-          return instance.getGroup1Count();
-        }/**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        @java.lang.Override
-        public protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 getGroup1(int index) {
-          return instance.getGroup1(index);
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        public Builder setGroup1(
-            int index, protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 value) {
-          copyOnWrite();
-          instance.setGroup1(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        public Builder setGroup1(
-            int index, protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1.Builder builderForValue) {
-          copyOnWrite();
-          instance.setGroup1(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        public Builder addGroup1(protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 value) {
-          copyOnWrite();
-          instance.addGroup1(value);
-          return this;
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        public Builder addGroup1(
-            int index, protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1 value) {
-          copyOnWrite();
-          instance.addGroup1(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        public Builder addGroup1(
-            protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1.Builder builderForValue) {
-          copyOnWrite();
-          instance.addGroup1(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        public Builder addGroup1(
-            int index, protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1.Builder builderForValue) {
-          copyOnWrite();
-          instance.addGroup1(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        public Builder addAllGroup1(
-            java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1> values) {
-          copyOnWrite();
-          instance.addAllGroup1(values);
-          return this;
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        public Builder clearGroup1() {
-          copyOnWrite();
-          instance.clearGroup1();
-          return this;
-        }
-        /**
-         * <code>repeated group Group1 = 10 { ... }</code>
-         */
-        public Builder removeGroup1(int index) {
-          copyOnWrite();
-          instance.removeGroup1(index);
-          return this;
-        }
-
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        @java.lang.Override
-        public java.util.List<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2> getGroup2List() {
-          return java.util.Collections.unmodifiableList(
-              instance.getGroup2List());
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        @java.lang.Override
-        public int getGroup2Count() {
-          return instance.getGroup2Count();
-        }/**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        @java.lang.Override
-        public protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 getGroup2(int index) {
-          return instance.getGroup2(index);
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        public Builder setGroup2(
-            int index, protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 value) {
-          copyOnWrite();
-          instance.setGroup2(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        public Builder setGroup2(
-            int index, protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2.Builder builderForValue) {
-          copyOnWrite();
-          instance.setGroup2(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        public Builder addGroup2(protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 value) {
-          copyOnWrite();
-          instance.addGroup2(value);
-          return this;
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        public Builder addGroup2(
-            int index, protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2 value) {
-          copyOnWrite();
-          instance.addGroup2(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        public Builder addGroup2(
-            protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2.Builder builderForValue) {
-          copyOnWrite();
-          instance.addGroup2(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        public Builder addGroup2(
-            int index, protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2.Builder builderForValue) {
-          copyOnWrite();
-          instance.addGroup2(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        public Builder addAllGroup2(
-            java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2> values) {
-          copyOnWrite();
-          instance.addAllGroup2(values);
-          return this;
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        public Builder clearGroup2() {
-          copyOnWrite();
-          instance.clearGroup2();
-          return this;
-        }
-        /**
-         * <code>repeated group Group2 = 20 { ... }</code>
-         */
-        public Builder removeGroup2(int index) {
-          copyOnWrite();
-          instance.removeGroup2(index);
-          return this;
-        }
-
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-         */
-        @java.lang.Override
-        public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes> getExt1List() {
-          return java.util.Collections.unmodifiableList(
-              instance.getExt1List());
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-         */
-        @java.lang.Override
-        public int getExt1Count() {
-          return instance.getExt1Count();
-        }/**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-         */
-        @java.lang.Override
-        public protobuf_unittest.UnittestProto.TestAllTypes getExt1(int index) {
-          return instance.getExt1(index);
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-         */
-        public Builder setExt1(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.setExt1(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-         */
-        public Builder setExt1(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-          copyOnWrite();
-          instance.setExt1(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-         */
-        public Builder addExt1(protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.addExt1(value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-         */
-        public Builder addExt1(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.addExt1(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-         */
-        public Builder addExt1(
-            protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-          copyOnWrite();
-          instance.addExt1(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-         */
-        public Builder addExt1(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-          copyOnWrite();
-          instance.addExt1(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-         */
-        public Builder addAllExt1(
-            java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes> values) {
-          copyOnWrite();
-          instance.addAllExt1(values);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-         */
-        public Builder clearExt1() {
-          copyOnWrite();
-          instance.clearExt1();
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext1 = 1000;</code>
-         */
-        public Builder removeExt1(int index) {
-          copyOnWrite();
-          instance.removeExt1(index);
-          return this;
-        }
-
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-         */
-        @java.lang.Override
-        public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes> getExt2List() {
-          return java.util.Collections.unmodifiableList(
-              instance.getExt2List());
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-         */
-        @java.lang.Override
-        public int getExt2Count() {
-          return instance.getExt2Count();
-        }/**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-         */
-        @java.lang.Override
-        public protobuf_unittest.UnittestProto.TestAllTypes getExt2(int index) {
-          return instance.getExt2(index);
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-         */
-        public Builder setExt2(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.setExt2(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-         */
-        public Builder setExt2(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-          copyOnWrite();
-          instance.setExt2(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-         */
-        public Builder addExt2(protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.addExt2(value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-         */
-        public Builder addExt2(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.addExt2(index, value);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-         */
-        public Builder addExt2(
-            protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-          copyOnWrite();
-          instance.addExt2(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-         */
-        public Builder addExt2(
-            int index, protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-          copyOnWrite();
-          instance.addExt2(index,
-              builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-         */
-        public Builder addAllExt2(
-            java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes> values) {
-          copyOnWrite();
-          instance.addAllExt2(values);
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-         */
-        public Builder clearExt2() {
-          copyOnWrite();
-          instance.clearExt2();
-          return this;
-        }
-        /**
-         * <code>repeated .protobuf_unittest.TestAllTypes ext2 = 1001;</code>
-         */
-        public Builder removeExt2(int index) {
-          copyOnWrite();
-          instance.removeExt2(index);
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "field1_",
-                protobuf_unittest.UnittestProto.TestAllTypes.class,
-                "field2_",
-                protobuf_unittest.UnittestProto.TestAllTypes.class,
-                "field3_",
-                protobuf_unittest.UnittestProto.TestAllTypes.class,
-                "group1_",
-                protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group1.class,
-                "group2_",
-                protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.Group2.class,
-                "ext1_",
-                protobuf_unittest.UnittestProto.TestAllTypes.class,
-                "ext2_",
-                protobuf_unittest.UnittestProto.TestAllTypes.class,
-              };
-              java.lang.String info =
-                  "\u0001\u0007\u0000\u0000\u0001\u03e9\u0007\u0000\u0007\u0000\u0001\u001b\u0002\u001b" +
-                  "\u0003\u001b\n1\u00141\u03e8\u001b\u03e9\u001b";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator)
-      private static final protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator DEFAULT_INSTANCE;
-      static {
-        RepeatedFieldsGenerator defaultInstance = new RepeatedFieldsGenerator();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          RepeatedFieldsGenerator.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedFieldsGenerator getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<RepeatedFieldsGenerator> PARSER;
-
-      public static com.google.protobuf.Parser<RepeatedFieldsGenerator> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    public interface OptionalGroupOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestParsingMerge.OptionalGroup)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes optional_group_all_types = 11;</code>
-       * @return Whether the optionalGroupAllTypes field is set.
-       */
-      boolean hasOptionalGroupAllTypes();
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes optional_group_all_types = 11;</code>
-       * @return The optionalGroupAllTypes.
-       */
-      protobuf_unittest.UnittestProto.TestAllTypes getOptionalGroupAllTypes();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestParsingMerge.OptionalGroup}
-     */
-    public  static final class OptionalGroup extends
-        com.google.protobuf.GeneratedMessageLite<
-            OptionalGroup, OptionalGroup.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestParsingMerge.OptionalGroup)
-        OptionalGroupOrBuilder {
-      private OptionalGroup() {
-      }
-      private int bitField0_;
-      public static final int OPTIONAL_GROUP_ALL_TYPES_FIELD_NUMBER = 11;
-      private protobuf_unittest.UnittestProto.TestAllTypes optionalGroupAllTypes_;
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes optional_group_all_types = 11;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalGroupAllTypes() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes optional_group_all_types = 11;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes getOptionalGroupAllTypes() {
-        return optionalGroupAllTypes_ == null ? protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance() : optionalGroupAllTypes_;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes optional_group_all_types = 11;</code>
-       */
-      private void setOptionalGroupAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  optionalGroupAllTypes_ = value;
-        bitField0_ |= 0x00000001;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes optional_group_all_types = 11;</code>
-       */
-      @java.lang.SuppressWarnings({"ReferenceEquality"})
-      private void mergeOptionalGroupAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  if (optionalGroupAllTypes_ != null &&
-            optionalGroupAllTypes_ != protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance()) {
-          optionalGroupAllTypes_ =
-            protobuf_unittest.UnittestProto.TestAllTypes.newBuilder(optionalGroupAllTypes_).mergeFrom(value).buildPartial();
-        } else {
-          optionalGroupAllTypes_ = value;
-        }
-        bitField0_ |= 0x00000001;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes optional_group_all_types = 11;</code>
-       */
-      private void clearOptionalGroupAllTypes() {  optionalGroupAllTypes_ = null;
-        bitField0_ = (bitField0_ & ~0x00000001);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestParsingMerge.OptionalGroup}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestParsingMerge.OptionalGroup)
-          protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroupOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes optional_group_all_types = 11;</code>
-         */
-        @java.lang.Override
-        public boolean hasOptionalGroupAllTypes() {
-          return instance.hasOptionalGroupAllTypes();
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes optional_group_all_types = 11;</code>
-         */
-        @java.lang.Override
-        public protobuf_unittest.UnittestProto.TestAllTypes getOptionalGroupAllTypes() {
-          return instance.getOptionalGroupAllTypes();
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes optional_group_all_types = 11;</code>
-         */
-        public Builder setOptionalGroupAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.setOptionalGroupAllTypes(value);
-          return this;
-          }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes optional_group_all_types = 11;</code>
-         */
-        public Builder setOptionalGroupAllTypes(
-            protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-          copyOnWrite();
-          instance.setOptionalGroupAllTypes(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes optional_group_all_types = 11;</code>
-         */
-        public Builder mergeOptionalGroupAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.mergeOptionalGroupAllTypes(value);
-          return this;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes optional_group_all_types = 11;</code>
-         */
-        public Builder clearOptionalGroupAllTypes() {  copyOnWrite();
-          instance.clearOptionalGroupAllTypes();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestParsingMerge.OptionalGroup)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "optionalGroupAllTypes_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\u000b\u000b\u0001\u0000\u0000\u0000\u000b\u1009\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestParsingMerge.OptionalGroup)
-      private static final protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup DEFAULT_INSTANCE;
-      static {
-        OptionalGroup defaultInstance = new OptionalGroup();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          OptionalGroup.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<OptionalGroup> PARSER;
-
-      public static com.google.protobuf.Parser<OptionalGroup> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    public interface RepeatedGroupOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestParsingMerge.RepeatedGroup)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes repeated_group_all_types = 21;</code>
-       * @return Whether the repeatedGroupAllTypes field is set.
-       */
-      boolean hasRepeatedGroupAllTypes();
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes repeated_group_all_types = 21;</code>
-       * @return The repeatedGroupAllTypes.
-       */
-      protobuf_unittest.UnittestProto.TestAllTypes getRepeatedGroupAllTypes();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestParsingMerge.RepeatedGroup}
-     */
-    public  static final class RepeatedGroup extends
-        com.google.protobuf.GeneratedMessageLite<
-            RepeatedGroup, RepeatedGroup.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestParsingMerge.RepeatedGroup)
-        RepeatedGroupOrBuilder {
-      private RepeatedGroup() {
-      }
-      private int bitField0_;
-      public static final int REPEATED_GROUP_ALL_TYPES_FIELD_NUMBER = 21;
-      private protobuf_unittest.UnittestProto.TestAllTypes repeatedGroupAllTypes_;
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes repeated_group_all_types = 21;</code>
-       */
-      @java.lang.Override
-      public boolean hasRepeatedGroupAllTypes() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes repeated_group_all_types = 21;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes getRepeatedGroupAllTypes() {
-        return repeatedGroupAllTypes_ == null ? protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance() : repeatedGroupAllTypes_;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes repeated_group_all_types = 21;</code>
-       */
-      private void setRepeatedGroupAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  repeatedGroupAllTypes_ = value;
-        bitField0_ |= 0x00000001;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes repeated_group_all_types = 21;</code>
-       */
-      @java.lang.SuppressWarnings({"ReferenceEquality"})
-      private void mergeRepeatedGroupAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        value.getClass();
-  if (repeatedGroupAllTypes_ != null &&
-            repeatedGroupAllTypes_ != protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance()) {
-          repeatedGroupAllTypes_ =
-            protobuf_unittest.UnittestProto.TestAllTypes.newBuilder(repeatedGroupAllTypes_).mergeFrom(value).buildPartial();
-        } else {
-          repeatedGroupAllTypes_ = value;
-        }
-        bitField0_ |= 0x00000001;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes repeated_group_all_types = 21;</code>
-       */
-      private void clearRepeatedGroupAllTypes() {  repeatedGroupAllTypes_ = null;
-        bitField0_ = (bitField0_ & ~0x00000001);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestParsingMerge.RepeatedGroup}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestParsingMerge.RepeatedGroup)
-          protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroupOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes repeated_group_all_types = 21;</code>
-         */
-        @java.lang.Override
-        public boolean hasRepeatedGroupAllTypes() {
-          return instance.hasRepeatedGroupAllTypes();
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes repeated_group_all_types = 21;</code>
-         */
-        @java.lang.Override
-        public protobuf_unittest.UnittestProto.TestAllTypes getRepeatedGroupAllTypes() {
-          return instance.getRepeatedGroupAllTypes();
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes repeated_group_all_types = 21;</code>
-         */
-        public Builder setRepeatedGroupAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.setRepeatedGroupAllTypes(value);
-          return this;
-          }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes repeated_group_all_types = 21;</code>
-         */
-        public Builder setRepeatedGroupAllTypes(
-            protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-          copyOnWrite();
-          instance.setRepeatedGroupAllTypes(builderForValue.build());
-          return this;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes repeated_group_all_types = 21;</code>
-         */
-        public Builder mergeRepeatedGroupAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-          copyOnWrite();
-          instance.mergeRepeatedGroupAllTypes(value);
-          return this;
-        }
-        /**
-         * <code>optional .protobuf_unittest.TestAllTypes repeated_group_all_types = 21;</code>
-         */
-        public Builder clearRepeatedGroupAllTypes() {  copyOnWrite();
-          instance.clearRepeatedGroupAllTypes();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestParsingMerge.RepeatedGroup)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "repeatedGroupAllTypes_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\u0015\u0015\u0001\u0000\u0000\u0000\u0015\u1009\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestParsingMerge.RepeatedGroup)
-      private static final protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup DEFAULT_INSTANCE;
-      static {
-        RepeatedGroup defaultInstance = new RepeatedGroup();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          RepeatedGroup.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<RepeatedGroup> PARSER;
-
-      public static com.google.protobuf.Parser<RepeatedGroup> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int bitField0_;
-    public static final int REQUIRED_ALL_TYPES_FIELD_NUMBER = 1;
-    private protobuf_unittest.UnittestProto.TestAllTypes requiredAllTypes_;
-    /**
-     * <code>required .protobuf_unittest.TestAllTypes required_all_types = 1;</code>
-     */
-    @java.lang.Override
-    public boolean hasRequiredAllTypes() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>required .protobuf_unittest.TestAllTypes required_all_types = 1;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes getRequiredAllTypes() {
-      return requiredAllTypes_ == null ? protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance() : requiredAllTypes_;
-    }
-    /**
-     * <code>required .protobuf_unittest.TestAllTypes required_all_types = 1;</code>
-     */
-    private void setRequiredAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-      value.getClass();
-  requiredAllTypes_ = value;
-      bitField0_ |= 0x00000001;
-      }
-    /**
-     * <code>required .protobuf_unittest.TestAllTypes required_all_types = 1;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeRequiredAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-      value.getClass();
-  if (requiredAllTypes_ != null &&
-          requiredAllTypes_ != protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance()) {
-        requiredAllTypes_ =
-          protobuf_unittest.UnittestProto.TestAllTypes.newBuilder(requiredAllTypes_).mergeFrom(value).buildPartial();
-      } else {
-        requiredAllTypes_ = value;
-      }
-      bitField0_ |= 0x00000001;
-    }
-    /**
-     * <code>required .protobuf_unittest.TestAllTypes required_all_types = 1;</code>
-     */
-    private void clearRequiredAllTypes() {  requiredAllTypes_ = null;
-      bitField0_ = (bitField0_ & ~0x00000001);
-    }
-
-    public static final int OPTIONAL_ALL_TYPES_FIELD_NUMBER = 2;
-    private protobuf_unittest.UnittestProto.TestAllTypes optionalAllTypes_;
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes optional_all_types = 2;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalAllTypes() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes optional_all_types = 2;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes getOptionalAllTypes() {
-      return optionalAllTypes_ == null ? protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance() : optionalAllTypes_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes optional_all_types = 2;</code>
-     */
-    private void setOptionalAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-      value.getClass();
-  optionalAllTypes_ = value;
-      bitField0_ |= 0x00000002;
-      }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes optional_all_types = 2;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-      value.getClass();
-  if (optionalAllTypes_ != null &&
-          optionalAllTypes_ != protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance()) {
-        optionalAllTypes_ =
-          protobuf_unittest.UnittestProto.TestAllTypes.newBuilder(optionalAllTypes_).mergeFrom(value).buildPartial();
-      } else {
-        optionalAllTypes_ = value;
-      }
-      bitField0_ |= 0x00000002;
-    }
-    /**
-     * <code>optional .protobuf_unittest.TestAllTypes optional_all_types = 2;</code>
-     */
-    private void clearOptionalAllTypes() {  optionalAllTypes_ = null;
-      bitField0_ = (bitField0_ & ~0x00000002);
-    }
-
-    public static final int REPEATED_ALL_TYPES_FIELD_NUMBER = 3;
-    private com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestAllTypes> repeatedAllTypes_;
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-     */
-    @java.lang.Override
-    public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes> getRepeatedAllTypesList() {
-      return repeatedAllTypes_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-     */
-    public java.util.List<? extends protobuf_unittest.UnittestProto.TestAllTypesOrBuilder> 
-        getRepeatedAllTypesOrBuilderList() {
-      return repeatedAllTypes_;
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-     */
-    @java.lang.Override
-    public int getRepeatedAllTypesCount() {
-      return repeatedAllTypes_.size();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes getRepeatedAllTypes(int index) {
-      return repeatedAllTypes_.get(index);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-     */
-    public protobuf_unittest.UnittestProto.TestAllTypesOrBuilder getRepeatedAllTypesOrBuilder(
-        int index) {
-      return repeatedAllTypes_.get(index);
-    }
-    private void ensureRepeatedAllTypesIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestAllTypes> tmp = repeatedAllTypes_;
-      if (!tmp.isModifiable()) {
-        repeatedAllTypes_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-     */
-    private void setRepeatedAllTypes(
-        int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-      value.getClass();
-  ensureRepeatedAllTypesIsMutable();
-      repeatedAllTypes_.set(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-     */
-    private void addRepeatedAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-      value.getClass();
-  ensureRepeatedAllTypesIsMutable();
-      repeatedAllTypes_.add(value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-     */
-    private void addRepeatedAllTypes(
-        int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-      value.getClass();
-  ensureRepeatedAllTypesIsMutable();
-      repeatedAllTypes_.add(index, value);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-     */
-    private void addAllRepeatedAllTypes(
-        java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes> values) {
-      ensureRepeatedAllTypesIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedAllTypes_);
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-     */
-    private void clearRepeatedAllTypes() {
-      repeatedAllTypes_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-     */
-    private void removeRepeatedAllTypes(int index) {
-      ensureRepeatedAllTypesIsMutable();
-      repeatedAllTypes_.remove(index);
-    }
-
-    public static final int OPTIONALGROUP_FIELD_NUMBER = 10;
-    private protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup optionalGroup_;
-    /**
-     * <code>optional group OptionalGroup = 10 { ... }</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalGroup() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional group OptionalGroup = 10 { ... }</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup getOptionalGroup() {
-      return optionalGroup_ == null ? protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup.getDefaultInstance() : optionalGroup_;
-    }
-    /**
-     * <code>optional group OptionalGroup = 10 { ... }</code>
-     */
-    private void setOptionalGroup(protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup value) {
-      value.getClass();
-  optionalGroup_ = value;
-      bitField0_ |= 0x00000004;
-      }
-    /**
-     * <code>optional group OptionalGroup = 10 { ... }</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalGroup(protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup value) {
-      value.getClass();
-  if (optionalGroup_ != null &&
-          optionalGroup_ != protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup.getDefaultInstance()) {
-        optionalGroup_ =
-          protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup.newBuilder(optionalGroup_).mergeFrom(value).buildPartial();
-      } else {
-        optionalGroup_ = value;
-      }
-      bitField0_ |= 0x00000004;
-    }
-    /**
-     * <code>optional group OptionalGroup = 10 { ... }</code>
-     */
-    private void clearOptionalGroup() {  optionalGroup_ = null;
-      bitField0_ = (bitField0_ & ~0x00000004);
-    }
-
-    public static final int REPEATEDGROUP_FIELD_NUMBER = 20;
-    private com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup> repeatedGroup_;
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    @java.lang.Override
-    public java.util.List<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup> getRepeatedGroupList() {
-      return repeatedGroup_;
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    public java.util.List<? extends protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroupOrBuilder> 
-        getRepeatedGroupOrBuilderList() {
-      return repeatedGroup_;
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    @java.lang.Override
-    public int getRepeatedGroupCount() {
-      return repeatedGroup_.size();
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup getRepeatedGroup(int index) {
-      return repeatedGroup_.get(index);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    public protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroupOrBuilder getRepeatedGroupOrBuilder(
-        int index) {
-      return repeatedGroup_.get(index);
-    }
-    private void ensureRepeatedGroupIsMutable() {
-      com.google.protobuf.Internal.ProtobufList<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup> tmp = repeatedGroup_;
-      if (!tmp.isModifiable()) {
-        repeatedGroup_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    private void setRepeatedGroup(
-        int index, protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup value) {
-      value.getClass();
-  ensureRepeatedGroupIsMutable();
-      repeatedGroup_.set(index, value);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    private void addRepeatedGroup(protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup value) {
-      value.getClass();
-  ensureRepeatedGroupIsMutable();
-      repeatedGroup_.add(value);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    private void addRepeatedGroup(
-        int index, protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup value) {
-      value.getClass();
-  ensureRepeatedGroupIsMutable();
-      repeatedGroup_.add(index, value);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    private void addAllRepeatedGroup(
-        java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup> values) {
-      ensureRepeatedGroupIsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedGroup_);
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    private void clearRepeatedGroup() {
-      repeatedGroup_ = emptyProtobufList();
-    }
-    /**
-     * <code>repeated group RepeatedGroup = 20 { ... }</code>
-     */
-    private void removeRepeatedGroup(int index) {
-      ensureRepeatedGroupIsMutable();
-      repeatedGroup_.remove(index);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestParsingMerge parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestParsingMerge parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestParsingMerge parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestParsingMerge parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestParsingMerge parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestParsingMerge parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestParsingMerge parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestParsingMerge parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestParsingMerge parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestParsingMerge parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestParsingMerge parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestParsingMerge parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestParsingMerge prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Test that if an optional or required message/group field appears multiple
-     * times in the input, they need to be merged.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.TestParsingMerge}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
-          protobuf_unittest.UnittestProto.TestParsingMerge, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestParsingMerge)
-        protobuf_unittest.UnittestProto.TestParsingMergeOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestParsingMerge.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>required .protobuf_unittest.TestAllTypes required_all_types = 1;</code>
-       */
-      @java.lang.Override
-      public boolean hasRequiredAllTypes() {
-        return instance.hasRequiredAllTypes();
-      }
-      /**
-       * <code>required .protobuf_unittest.TestAllTypes required_all_types = 1;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes getRequiredAllTypes() {
-        return instance.getRequiredAllTypes();
-      }
-      /**
-       * <code>required .protobuf_unittest.TestAllTypes required_all_types = 1;</code>
-       */
-      public Builder setRequiredAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        copyOnWrite();
-        instance.setRequiredAllTypes(value);
-        return this;
-        }
-      /**
-       * <code>required .protobuf_unittest.TestAllTypes required_all_types = 1;</code>
-       */
-      public Builder setRequiredAllTypes(
-          protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRequiredAllTypes(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>required .protobuf_unittest.TestAllTypes required_all_types = 1;</code>
-       */
-      public Builder mergeRequiredAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        copyOnWrite();
-        instance.mergeRequiredAllTypes(value);
-        return this;
-      }
-      /**
-       * <code>required .protobuf_unittest.TestAllTypes required_all_types = 1;</code>
-       */
-      public Builder clearRequiredAllTypes() {  copyOnWrite();
-        instance.clearRequiredAllTypes();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes optional_all_types = 2;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalAllTypes() {
-        return instance.hasOptionalAllTypes();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes optional_all_types = 2;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes getOptionalAllTypes() {
-        return instance.getOptionalAllTypes();
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes optional_all_types = 2;</code>
-       */
-      public Builder setOptionalAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        copyOnWrite();
-        instance.setOptionalAllTypes(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes optional_all_types = 2;</code>
-       */
-      public Builder setOptionalAllTypes(
-          protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalAllTypes(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes optional_all_types = 2;</code>
-       */
-      public Builder mergeOptionalAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        copyOnWrite();
-        instance.mergeOptionalAllTypes(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.TestAllTypes optional_all_types = 2;</code>
-       */
-      public Builder clearOptionalAllTypes() {  copyOnWrite();
-        instance.clearOptionalAllTypes();
-        return this;
-      }
-
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.TestAllTypes> getRepeatedAllTypesList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedAllTypesList());
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-       */
-      @java.lang.Override
-      public int getRepeatedAllTypesCount() {
-        return instance.getRepeatedAllTypesCount();
-      }/**
-       * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes getRepeatedAllTypes(int index) {
-        return instance.getRepeatedAllTypes(index);
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-       */
-      public Builder setRepeatedAllTypes(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-        copyOnWrite();
-        instance.setRepeatedAllTypes(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-       */
-      public Builder setRepeatedAllTypes(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedAllTypes(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-       */
-      public Builder addRepeatedAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        copyOnWrite();
-        instance.addRepeatedAllTypes(value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-       */
-      public Builder addRepeatedAllTypes(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes value) {
-        copyOnWrite();
-        instance.addRepeatedAllTypes(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-       */
-      public Builder addRepeatedAllTypes(
-          protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedAllTypes(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-       */
-      public Builder addRepeatedAllTypes(
-          int index, protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedAllTypes(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-       */
-      public Builder addAllRepeatedAllTypes(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestAllTypes> values) {
-        copyOnWrite();
-        instance.addAllRepeatedAllTypes(values);
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-       */
-      public Builder clearRepeatedAllTypes() {
-        copyOnWrite();
-        instance.clearRepeatedAllTypes();
-        return this;
-      }
-      /**
-       * <code>repeated .protobuf_unittest.TestAllTypes repeated_all_types = 3;</code>
-       */
-      public Builder removeRepeatedAllTypes(int index) {
-        copyOnWrite();
-        instance.removeRepeatedAllTypes(index);
-        return this;
-      }
-
-      /**
-       * <code>optional group OptionalGroup = 10 { ... }</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalGroup() {
-        return instance.hasOptionalGroup();
-      }
-      /**
-       * <code>optional group OptionalGroup = 10 { ... }</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup getOptionalGroup() {
-        return instance.getOptionalGroup();
-      }
-      /**
-       * <code>optional group OptionalGroup = 10 { ... }</code>
-       */
-      public Builder setOptionalGroup(protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup value) {
-        copyOnWrite();
-        instance.setOptionalGroup(value);
-        return this;
-        }
-      /**
-       * <code>optional group OptionalGroup = 10 { ... }</code>
-       */
-      public Builder setOptionalGroup(
-          protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalGroup(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional group OptionalGroup = 10 { ... }</code>
-       */
-      public Builder mergeOptionalGroup(protobuf_unittest.UnittestProto.TestParsingMerge.OptionalGroup value) {
-        copyOnWrite();
-        instance.mergeOptionalGroup(value);
-        return this;
-      }
-      /**
-       * <code>optional group OptionalGroup = 10 { ... }</code>
-       */
-      public Builder clearOptionalGroup() {  copyOnWrite();
-        instance.clearOptionalGroup();
-        return this;
-      }
-
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      @java.lang.Override
-      public java.util.List<protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup> getRepeatedGroupList() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedGroupList());
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      @java.lang.Override
-      public int getRepeatedGroupCount() {
-        return instance.getRepeatedGroupCount();
-      }/**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup getRepeatedGroup(int index) {
-        return instance.getRepeatedGroup(index);
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      public Builder setRepeatedGroup(
-          int index, protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup value) {
-        copyOnWrite();
-        instance.setRepeatedGroup(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      public Builder setRepeatedGroup(
-          int index, protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.setRepeatedGroup(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      public Builder addRepeatedGroup(protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup value) {
-        copyOnWrite();
-        instance.addRepeatedGroup(value);
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      public Builder addRepeatedGroup(
-          int index, protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup value) {
-        copyOnWrite();
-        instance.addRepeatedGroup(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      public Builder addRepeatedGroup(
-          protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedGroup(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      public Builder addRepeatedGroup(
-          int index, protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.addRepeatedGroup(index,
-            builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      public Builder addAllRepeatedGroup(
-          java.lang.Iterable<? extends protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup> values) {
-        copyOnWrite();
-        instance.addAllRepeatedGroup(values);
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      public Builder clearRepeatedGroup() {
-        copyOnWrite();
-        instance.clearRepeatedGroup();
-        return this;
-      }
-      /**
-       * <code>repeated group RepeatedGroup = 20 { ... }</code>
-       */
-      public Builder removeRepeatedGroup(int index) {
-        copyOnWrite();
-        instance.removeRepeatedGroup(index);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestParsingMerge)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestParsingMerge();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "requiredAllTypes_",
-              "optionalAllTypes_",
-              "repeatedAllTypes_",
-              protobuf_unittest.UnittestProto.TestAllTypes.class,
-              "optionalGroup_",
-              "repeatedGroup_",
-              protobuf_unittest.UnittestProto.TestParsingMerge.RepeatedGroup.class,
-            };
-            java.lang.String info =
-                "\u0001\u0005\u0000\u0001\u0001\u0014\u0005\u0000\u0002\u0001\u0001\u1509\u0000\u0002" +
-                "\u1009\u0001\u0003\u001b\n\u1011\u0002\u00141";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestParsingMerge> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestParsingMerge.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestParsingMerge>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestParsingMerge)
-    private static final protobuf_unittest.UnittestProto.TestParsingMerge DEFAULT_INSTANCE;
-    static {
-      TestParsingMerge defaultInstance = new TestParsingMerge();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestParsingMerge.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestParsingMerge getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestParsingMerge> PARSER;
-
-    public static com.google.protobuf.Parser<TestParsingMerge> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-    public static final int OPTIONAL_EXT_FIELD_NUMBER = 1000;
-    /**
-     * <code>extend .protobuf_unittest.TestParsingMerge { ... }</code>
-     */
-    public static final
-      com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-        protobuf_unittest.UnittestProto.TestParsingMerge,
-        protobuf_unittest.UnittestProto.TestAllTypes> optionalExt = com.google.protobuf.GeneratedMessageLite
-            .newSingularGeneratedExtension(
-          protobuf_unittest.UnittestProto.TestParsingMerge.getDefaultInstance(),
-          protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance(),
-          protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance(),
-          null,
-          1000,
-          com.google.protobuf.WireFormat.FieldType.MESSAGE,
-          protobuf_unittest.UnittestProto.TestAllTypes.class);
-    public static final int REPEATED_EXT_FIELD_NUMBER = 1001;
-    /**
-     * <code>extend .protobuf_unittest.TestParsingMerge { ... }</code>
-     */
-    public static final
-      com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-        protobuf_unittest.UnittestProto.TestParsingMerge,
-        java.util.List<protobuf_unittest.UnittestProto.TestAllTypes>> repeatedExt = com.google.protobuf.GeneratedMessageLite
-            .newRepeatedGeneratedExtension(
-          protobuf_unittest.UnittestProto.TestParsingMerge.getDefaultInstance(),
-          protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance(),
-          null,
-          1001,
-          com.google.protobuf.WireFormat.FieldType.MESSAGE,
-          false,
-          protobuf_unittest.UnittestProto.TestAllTypes.class);
-  }
-
-  public interface TestCommentInjectionMessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestCommentInjectionMessage)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <pre>
-     * *&#47; &lt;- This should not close the generated doc comment
-     * </pre>
-     *
-     * <code>optional string a = 1 [default = "*&#47; &lt;- Neither should this."];</code>
-     * @return Whether the a field is set.
-     */
-    boolean hasA();
-    /**
-     * <pre>
-     * *&#47; &lt;- This should not close the generated doc comment
-     * </pre>
-     *
-     * <code>optional string a = 1 [default = "*&#47; &lt;- Neither should this."];</code>
-     * @return The a.
-     */
-    java.lang.String getA();
-    /**
-     * <pre>
-     * *&#47; &lt;- This should not close the generated doc comment
-     * </pre>
-     *
-     * <code>optional string a = 1 [default = "*&#47; &lt;- Neither should this."];</code>
-     * @return The bytes for a.
-     */
-    com.google.protobuf.ByteString
-        getABytes();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestCommentInjectionMessage}
-   */
-  public  static final class TestCommentInjectionMessage extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestCommentInjectionMessage, TestCommentInjectionMessage.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestCommentInjectionMessage)
-      TestCommentInjectionMessageOrBuilder {
-    private TestCommentInjectionMessage() {
-      a_ = "*/ <- Neither should this.";
-    }
-    private int bitField0_;
-    public static final int A_FIELD_NUMBER = 1;
-    private java.lang.String a_;
-    /**
-     * <pre>
-     * *&#47; &lt;- This should not close the generated doc comment
-     * </pre>
-     *
-     * <code>optional string a = 1 [default = "*&#47; &lt;- Neither should this."];</code>
-     * @return Whether the a field is set.
-     */
-    @java.lang.Override
-    public boolean hasA() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <pre>
-     * *&#47; &lt;- This should not close the generated doc comment
-     * </pre>
-     *
-     * <code>optional string a = 1 [default = "*&#47; &lt;- Neither should this."];</code>
-     * @return The a.
-     */
-    @java.lang.Override
-    public java.lang.String getA() {
-      return a_;
-    }
-    /**
-     * <pre>
-     * *&#47; &lt;- This should not close the generated doc comment
-     * </pre>
-     *
-     * <code>optional string a = 1 [default = "*&#47; &lt;- Neither should this."];</code>
-     * @return The bytes for a.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getABytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(a_);
-    }
-    /**
-     * <pre>
-     * *&#47; &lt;- This should not close the generated doc comment
-     * </pre>
-     *
-     * <code>optional string a = 1 [default = "*&#47; &lt;- Neither should this."];</code>
-     * @param value The a to set.
-     */
-    private void setA(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00000001;
-      a_ = value;
-    }
-    /**
-     * <pre>
-     * *&#47; &lt;- This should not close the generated doc comment
-     * </pre>
-     *
-     * <code>optional string a = 1 [default = "*&#47; &lt;- Neither should this."];</code>
-     */
-    private void clearA() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      a_ = getDefaultInstance().getA();
-    }
-    /**
-     * <pre>
-     * *&#47; &lt;- This should not close the generated doc comment
-     * </pre>
-     *
-     * <code>optional string a = 1 [default = "*&#47; &lt;- Neither should this."];</code>
-     * @param value The bytes for a to set.
-     */
-    private void setABytes(
-        com.google.protobuf.ByteString value) {
-      a_ = value.toStringUtf8();
-      bitField0_ |= 0x00000001;
-    }
-
-    public static protobuf_unittest.UnittestProto.TestCommentInjectionMessage parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestCommentInjectionMessage parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestCommentInjectionMessage parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestCommentInjectionMessage parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestCommentInjectionMessage parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestCommentInjectionMessage parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestCommentInjectionMessage parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestCommentInjectionMessage parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestCommentInjectionMessage parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestCommentInjectionMessage parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestCommentInjectionMessage parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestCommentInjectionMessage parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestCommentInjectionMessage prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestCommentInjectionMessage}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestCommentInjectionMessage, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestCommentInjectionMessage)
-        protobuf_unittest.UnittestProto.TestCommentInjectionMessageOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestCommentInjectionMessage.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <pre>
-       * *&#47; &lt;- This should not close the generated doc comment
-       * </pre>
-       *
-       * <code>optional string a = 1 [default = "*&#47; &lt;- Neither should this."];</code>
-       * @return Whether the a field is set.
-       */
-      @java.lang.Override
-      public boolean hasA() {
-        return instance.hasA();
-      }
-      /**
-       * <pre>
-       * *&#47; &lt;- This should not close the generated doc comment
-       * </pre>
-       *
-       * <code>optional string a = 1 [default = "*&#47; &lt;- Neither should this."];</code>
-       * @return The a.
-       */
-      @java.lang.Override
-      public java.lang.String getA() {
-        return instance.getA();
-      }
-      /**
-       * <pre>
-       * *&#47; &lt;- This should not close the generated doc comment
-       * </pre>
-       *
-       * <code>optional string a = 1 [default = "*&#47; &lt;- Neither should this."];</code>
-       * @return The bytes for a.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getABytes() {
-        return instance.getABytes();
-      }
-      /**
-       * <pre>
-       * *&#47; &lt;- This should not close the generated doc comment
-       * </pre>
-       *
-       * <code>optional string a = 1 [default = "*&#47; &lt;- Neither should this."];</code>
-       * @param value The a to set.
-       * @return This builder for chaining.
-       */
-      public Builder setA(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setA(value);
-        return this;
-      }
-      /**
-       * <pre>
-       * *&#47; &lt;- This should not close the generated doc comment
-       * </pre>
-       *
-       * <code>optional string a = 1 [default = "*&#47; &lt;- Neither should this."];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearA() {
-        copyOnWrite();
-        instance.clearA();
-        return this;
-      }
-      /**
-       * <pre>
-       * *&#47; &lt;- This should not close the generated doc comment
-       * </pre>
-       *
-       * <code>optional string a = 1 [default = "*&#47; &lt;- Neither should this."];</code>
-       * @param value The bytes for a to set.
-       * @return This builder for chaining.
-       */
-      public Builder setABytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setABytes(value);
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestCommentInjectionMessage)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestCommentInjectionMessage();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "a_",
-            };
-            java.lang.String info =
-                "\u0001\u0001\u0000\u0001\u0001\u0001\u0001\u0000\u0000\u0000\u0001\u1008\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestCommentInjectionMessage> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestCommentInjectionMessage.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestCommentInjectionMessage>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestCommentInjectionMessage)
-    private static final protobuf_unittest.UnittestProto.TestCommentInjectionMessage DEFAULT_INSTANCE;
-    static {
-      TestCommentInjectionMessage defaultInstance = new TestCommentInjectionMessage();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestCommentInjectionMessage.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestCommentInjectionMessage getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestCommentInjectionMessage> PARSER;
-
-    public static com.google.protobuf.Parser<TestCommentInjectionMessage> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface FooRequestOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.FooRequest)
-      com.google.protobuf.MessageLiteOrBuilder {
-  }
-  /**
-   * <pre>
-   * Test that RPC services work.
-   * </pre>
-   *
-   * Protobuf type {@code protobuf_unittest.FooRequest}
-   */
-  public  static final class FooRequest extends
-      com.google.protobuf.GeneratedMessageLite<
-          FooRequest, FooRequest.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.FooRequest)
-      FooRequestOrBuilder {
-    private FooRequest() {
-    }
-    public static protobuf_unittest.UnittestProto.FooRequest parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.FooRequest parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooRequest parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.FooRequest parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooRequest parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.FooRequest parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooRequest parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.FooRequest parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooRequest parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.FooRequest parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooRequest parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.FooRequest parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.FooRequest prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * <pre>
-     * Test that RPC services work.
-     * </pre>
-     *
-     * Protobuf type {@code protobuf_unittest.FooRequest}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.FooRequest, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.FooRequest)
-        protobuf_unittest.UnittestProto.FooRequestOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.FooRequest.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.FooRequest)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.FooRequest();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.FooRequest> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.FooRequest.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.FooRequest>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.FooRequest)
-    private static final protobuf_unittest.UnittestProto.FooRequest DEFAULT_INSTANCE;
-    static {
-      FooRequest defaultInstance = new FooRequest();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        FooRequest.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.FooRequest getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<FooRequest> PARSER;
-
-    public static com.google.protobuf.Parser<FooRequest> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface FooResponseOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.FooResponse)
-      com.google.protobuf.MessageLiteOrBuilder {
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.FooResponse}
-   */
-  public  static final class FooResponse extends
-      com.google.protobuf.GeneratedMessageLite<
-          FooResponse, FooResponse.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.FooResponse)
-      FooResponseOrBuilder {
-    private FooResponse() {
-    }
-    public static protobuf_unittest.UnittestProto.FooResponse parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.FooResponse parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooResponse parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.FooResponse parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooResponse parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.FooResponse parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooResponse parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.FooResponse parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooResponse parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.FooResponse parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooResponse parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.FooResponse parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.FooResponse prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.FooResponse}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.FooResponse, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.FooResponse)
-        protobuf_unittest.UnittestProto.FooResponseOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.FooResponse.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.FooResponse)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.FooResponse();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.FooResponse> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.FooResponse.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.FooResponse>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.FooResponse)
-    private static final protobuf_unittest.UnittestProto.FooResponse DEFAULT_INSTANCE;
-    static {
-      FooResponse defaultInstance = new FooResponse();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        FooResponse.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.FooResponse getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<FooResponse> PARSER;
-
-    public static com.google.protobuf.Parser<FooResponse> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface FooClientMessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.FooClientMessage)
-      com.google.protobuf.MessageLiteOrBuilder {
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.FooClientMessage}
-   */
-  public  static final class FooClientMessage extends
-      com.google.protobuf.GeneratedMessageLite<
-          FooClientMessage, FooClientMessage.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.FooClientMessage)
-      FooClientMessageOrBuilder {
-    private FooClientMessage() {
-    }
-    public static protobuf_unittest.UnittestProto.FooClientMessage parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.FooClientMessage parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooClientMessage parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.FooClientMessage parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooClientMessage parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.FooClientMessage parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooClientMessage parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.FooClientMessage parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooClientMessage parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.FooClientMessage parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooClientMessage parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.FooClientMessage parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.FooClientMessage prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.FooClientMessage}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.FooClientMessage, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.FooClientMessage)
-        protobuf_unittest.UnittestProto.FooClientMessageOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.FooClientMessage.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.FooClientMessage)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.FooClientMessage();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.FooClientMessage> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.FooClientMessage.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.FooClientMessage>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.FooClientMessage)
-    private static final protobuf_unittest.UnittestProto.FooClientMessage DEFAULT_INSTANCE;
-    static {
-      FooClientMessage defaultInstance = new FooClientMessage();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        FooClientMessage.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.FooClientMessage getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<FooClientMessage> PARSER;
-
-    public static com.google.protobuf.Parser<FooClientMessage> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface FooServerMessageOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.FooServerMessage)
-      com.google.protobuf.MessageLiteOrBuilder {
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.FooServerMessage}
-   */
-  public  static final class FooServerMessage extends
-      com.google.protobuf.GeneratedMessageLite<
-          FooServerMessage, FooServerMessage.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.FooServerMessage)
-      FooServerMessageOrBuilder {
-    private FooServerMessage() {
-    }
-    public static protobuf_unittest.UnittestProto.FooServerMessage parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.FooServerMessage parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooServerMessage parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.FooServerMessage parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooServerMessage parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.FooServerMessage parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooServerMessage parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.FooServerMessage parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooServerMessage parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.FooServerMessage parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.FooServerMessage parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.FooServerMessage parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.FooServerMessage prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.FooServerMessage}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.FooServerMessage, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.FooServerMessage)
-        protobuf_unittest.UnittestProto.FooServerMessageOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.FooServerMessage.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.FooServerMessage)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.FooServerMessage();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.FooServerMessage> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.FooServerMessage.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.FooServerMessage>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.FooServerMessage)
-    private static final protobuf_unittest.UnittestProto.FooServerMessage DEFAULT_INSTANCE;
-    static {
-      FooServerMessage defaultInstance = new FooServerMessage();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        FooServerMessage.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.FooServerMessage getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<FooServerMessage> PARSER;
-
-    public static com.google.protobuf.Parser<FooServerMessage> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface BarRequestOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.BarRequest)
-      com.google.protobuf.MessageLiteOrBuilder {
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.BarRequest}
-   */
-  public  static final class BarRequest extends
-      com.google.protobuf.GeneratedMessageLite<
-          BarRequest, BarRequest.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.BarRequest)
-      BarRequestOrBuilder {
-    private BarRequest() {
-    }
-    public static protobuf_unittest.UnittestProto.BarRequest parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.BarRequest parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.BarRequest parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.BarRequest parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.BarRequest parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.BarRequest parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.BarRequest parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.BarRequest parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.BarRequest parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.BarRequest parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.BarRequest parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.BarRequest parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.BarRequest prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.BarRequest}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.BarRequest, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.BarRequest)
-        protobuf_unittest.UnittestProto.BarRequestOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.BarRequest.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.BarRequest)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.BarRequest();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.BarRequest> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.BarRequest.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.BarRequest>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.BarRequest)
-    private static final protobuf_unittest.UnittestProto.BarRequest DEFAULT_INSTANCE;
-    static {
-      BarRequest defaultInstance = new BarRequest();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        BarRequest.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.BarRequest getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<BarRequest> PARSER;
-
-    public static com.google.protobuf.Parser<BarRequest> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface BarResponseOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.BarResponse)
-      com.google.protobuf.MessageLiteOrBuilder {
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.BarResponse}
-   */
-  public  static final class BarResponse extends
-      com.google.protobuf.GeneratedMessageLite<
-          BarResponse, BarResponse.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.BarResponse)
-      BarResponseOrBuilder {
-    private BarResponse() {
-    }
-    public static protobuf_unittest.UnittestProto.BarResponse parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.BarResponse parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.BarResponse parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.BarResponse parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.BarResponse parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.BarResponse parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.BarResponse parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.BarResponse parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.BarResponse parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.BarResponse parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.BarResponse parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.BarResponse parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.BarResponse prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.BarResponse}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.BarResponse, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.BarResponse)
-        protobuf_unittest.UnittestProto.BarResponseOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.BarResponse.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.BarResponse)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.BarResponse();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = null;java.lang.String info =
-                "\u0001\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.BarResponse> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.BarResponse.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.BarResponse>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.BarResponse)
-    private static final protobuf_unittest.UnittestProto.BarResponse DEFAULT_INSTANCE;
-    static {
-      BarResponse defaultInstance = new BarResponse();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        BarResponse.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.BarResponse getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<BarResponse> PARSER;
-
-    public static com.google.protobuf.Parser<BarResponse> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestJsonNameOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestJsonName)
-      com.google.protobuf.MessageLiteOrBuilder {
-
-    /**
-     * <code>optional int32 field_name1 = 1;</code>
-     * @return Whether the fieldName1 field is set.
-     */
-    boolean hasFieldName1();
-    /**
-     * <code>optional int32 field_name1 = 1;</code>
-     * @return The fieldName1.
-     */
-    int getFieldName1();
-
-    /**
-     * <code>optional int32 fieldName2 = 2;</code>
-     * @return Whether the fieldName2 field is set.
-     */
-    boolean hasFieldName2();
-    /**
-     * <code>optional int32 fieldName2 = 2;</code>
-     * @return The fieldName2.
-     */
-    int getFieldName2();
-
-    /**
-     * <code>optional int32 FieldName3 = 3;</code>
-     * @return Whether the fieldName3 field is set.
-     */
-    boolean hasFieldName3();
-    /**
-     * <code>optional int32 FieldName3 = 3;</code>
-     * @return The fieldName3.
-     */
-    int getFieldName3();
-
-    /**
-     * <code>optional int32 _field_name4 = 4;</code>
-     * @return Whether the fieldName4 field is set.
-     */
-    boolean hasFieldName4();
-    /**
-     * <code>optional int32 _field_name4 = 4;</code>
-     * @return The fieldName4.
-     */
-    int getFieldName4();
-
-    /**
-     * <code>optional int32 FIELD_NAME5 = 5;</code>
-     * @return Whether the fIELDNAME5 field is set.
-     */
-    boolean hasFIELDNAME5();
-    /**
-     * <code>optional int32 FIELD_NAME5 = 5;</code>
-     * @return The fIELDNAME5.
-     */
-    int getFIELDNAME5();
-
-    /**
-     * <code>optional int32 field_name6 = 6 [json_name = "&#64;type"];</code>
-     * @return Whether the fieldName6 field is set.
-     */
-    boolean hasFieldName6();
-    /**
-     * <code>optional int32 field_name6 = 6 [json_name = "&#64;type"];</code>
-     * @return The fieldName6.
-     */
-    int getFieldName6();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestJsonName}
-   */
-  public  static final class TestJsonName extends
-      com.google.protobuf.GeneratedMessageLite<
-          TestJsonName, TestJsonName.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestJsonName)
-      TestJsonNameOrBuilder {
-    private TestJsonName() {
-    }
-    private int bitField0_;
-    public static final int FIELD_NAME1_FIELD_NUMBER = 1;
-    private int fieldName1_;
-    /**
-     * <code>optional int32 field_name1 = 1;</code>
-     * @return Whether the fieldName1 field is set.
-     */
-    @java.lang.Override
-    public boolean hasFieldName1() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 field_name1 = 1;</code>
-     * @return The fieldName1.
-     */
-    @java.lang.Override
-    public int getFieldName1() {
-      return fieldName1_;
-    }
-    /**
-     * <code>optional int32 field_name1 = 1;</code>
-     * @param value The fieldName1 to set.
-     */
-    private void setFieldName1(int value) {
-      bitField0_ |= 0x00000001;
-      fieldName1_ = value;
-    }
-    /**
-     * <code>optional int32 field_name1 = 1;</code>
-     */
-    private void clearFieldName1() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      fieldName1_ = 0;
-    }
-
-    public static final int FIELDNAME2_FIELD_NUMBER = 2;
-    private int fieldName2_;
-    /**
-     * <code>optional int32 fieldName2 = 2;</code>
-     * @return Whether the fieldName2 field is set.
-     */
-    @java.lang.Override
-    public boolean hasFieldName2() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional int32 fieldName2 = 2;</code>
-     * @return The fieldName2.
-     */
-    @java.lang.Override
-    public int getFieldName2() {
-      return fieldName2_;
-    }
-    /**
-     * <code>optional int32 fieldName2 = 2;</code>
-     * @param value The fieldName2 to set.
-     */
-    private void setFieldName2(int value) {
-      bitField0_ |= 0x00000002;
-      fieldName2_ = value;
-    }
-    /**
-     * <code>optional int32 fieldName2 = 2;</code>
-     */
-    private void clearFieldName2() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      fieldName2_ = 0;
-    }
-
-    public static final int FIELDNAME3_FIELD_NUMBER = 3;
-    private int fieldName3_;
-    /**
-     * <code>optional int32 FieldName3 = 3;</code>
-     * @return Whether the fieldName3 field is set.
-     */
-    @java.lang.Override
-    public boolean hasFieldName3() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional int32 FieldName3 = 3;</code>
-     * @return The fieldName3.
-     */
-    @java.lang.Override
-    public int getFieldName3() {
-      return fieldName3_;
-    }
-    /**
-     * <code>optional int32 FieldName3 = 3;</code>
-     * @param value The fieldName3 to set.
-     */
-    private void setFieldName3(int value) {
-      bitField0_ |= 0x00000004;
-      fieldName3_ = value;
-    }
-    /**
-     * <code>optional int32 FieldName3 = 3;</code>
-     */
-    private void clearFieldName3() {
-      bitField0_ = (bitField0_ & ~0x00000004);
-      fieldName3_ = 0;
-    }
-
-    public static final int _FIELD_NAME4_FIELD_NUMBER = 4;
-    private int FieldName4_;
-    /**
-     * <code>optional int32 _field_name4 = 4;</code>
-     * @return Whether the fieldName4 field is set.
-     */
-    @java.lang.Override
-    public boolean hasFieldName4() {
-      return ((bitField0_ & 0x00000008) != 0);
-    }
-    /**
-     * <code>optional int32 _field_name4 = 4;</code>
-     * @return The fieldName4.
-     */
-    @java.lang.Override
-    public int getFieldName4() {
-      return FieldName4_;
-    }
-    /**
-     * <code>optional int32 _field_name4 = 4;</code>
-     * @param value The fieldName4 to set.
-     */
-    private void setFieldName4(int value) {
-      bitField0_ |= 0x00000008;
-      FieldName4_ = value;
-    }
-    /**
-     * <code>optional int32 _field_name4 = 4;</code>
-     */
-    private void clearFieldName4() {
-      bitField0_ = (bitField0_ & ~0x00000008);
-      FieldName4_ = 0;
-    }
-
-    public static final int FIELD_NAME5_FIELD_NUMBER = 5;
-    private int fIELDNAME5_;
-    /**
-     * <code>optional int32 FIELD_NAME5 = 5;</code>
-     * @return Whether the fIELDNAME5 field is set.
-     */
-    @java.lang.Override
-    public boolean hasFIELDNAME5() {
-      return ((bitField0_ & 0x00000010) != 0);
-    }
-    /**
-     * <code>optional int32 FIELD_NAME5 = 5;</code>
-     * @return The fIELDNAME5.
-     */
-    @java.lang.Override
-    public int getFIELDNAME5() {
-      return fIELDNAME5_;
-    }
-    /**
-     * <code>optional int32 FIELD_NAME5 = 5;</code>
-     * @param value The fIELDNAME5 to set.
-     */
-    private void setFIELDNAME5(int value) {
-      bitField0_ |= 0x00000010;
-      fIELDNAME5_ = value;
-    }
-    /**
-     * <code>optional int32 FIELD_NAME5 = 5;</code>
-     */
-    private void clearFIELDNAME5() {
-      bitField0_ = (bitField0_ & ~0x00000010);
-      fIELDNAME5_ = 0;
-    }
-
-    public static final int FIELD_NAME6_FIELD_NUMBER = 6;
-    private int fieldName6_;
-    /**
-     * <code>optional int32 field_name6 = 6 [json_name = "&#64;type"];</code>
-     * @return Whether the fieldName6 field is set.
-     */
-    @java.lang.Override
-    public boolean hasFieldName6() {
-      return ((bitField0_ & 0x00000020) != 0);
-    }
-    /**
-     * <code>optional int32 field_name6 = 6 [json_name = "&#64;type"];</code>
-     * @return The fieldName6.
-     */
-    @java.lang.Override
-    public int getFieldName6() {
-      return fieldName6_;
-    }
-    /**
-     * <code>optional int32 field_name6 = 6 [json_name = "&#64;type"];</code>
-     * @param value The fieldName6 to set.
-     */
-    private void setFieldName6(int value) {
-      bitField0_ |= 0x00000020;
-      fieldName6_ = value;
-    }
-    /**
-     * <code>optional int32 field_name6 = 6 [json_name = "&#64;type"];</code>
-     */
-    private void clearFieldName6() {
-      bitField0_ = (bitField0_ & ~0x00000020);
-      fieldName6_ = 0;
-    }
-
-    public static protobuf_unittest.UnittestProto.TestJsonName parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestJsonName parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestJsonName parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestJsonName parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestJsonName parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestJsonName parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestJsonName parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestJsonName parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestJsonName parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestJsonName parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestJsonName parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestJsonName parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestJsonName prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestJsonName}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.Builder<
-          protobuf_unittest.UnittestProto.TestJsonName, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestJsonName)
-        protobuf_unittest.UnittestProto.TestJsonNameOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestJsonName.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int32 field_name1 = 1;</code>
-       * @return Whether the fieldName1 field is set.
-       */
-      @java.lang.Override
-      public boolean hasFieldName1() {
-        return instance.hasFieldName1();
-      }
-      /**
-       * <code>optional int32 field_name1 = 1;</code>
-       * @return The fieldName1.
-       */
-      @java.lang.Override
-      public int getFieldName1() {
-        return instance.getFieldName1();
-      }
-      /**
-       * <code>optional int32 field_name1 = 1;</code>
-       * @param value The fieldName1 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFieldName1(int value) {
-        copyOnWrite();
-        instance.setFieldName1(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 field_name1 = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFieldName1() {
-        copyOnWrite();
-        instance.clearFieldName1();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 fieldName2 = 2;</code>
-       * @return Whether the fieldName2 field is set.
-       */
-      @java.lang.Override
-      public boolean hasFieldName2() {
-        return instance.hasFieldName2();
-      }
-      /**
-       * <code>optional int32 fieldName2 = 2;</code>
-       * @return The fieldName2.
-       */
-      @java.lang.Override
-      public int getFieldName2() {
-        return instance.getFieldName2();
-      }
-      /**
-       * <code>optional int32 fieldName2 = 2;</code>
-       * @param value The fieldName2 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFieldName2(int value) {
-        copyOnWrite();
-        instance.setFieldName2(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 fieldName2 = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFieldName2() {
-        copyOnWrite();
-        instance.clearFieldName2();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 FieldName3 = 3;</code>
-       * @return Whether the fieldName3 field is set.
-       */
-      @java.lang.Override
-      public boolean hasFieldName3() {
-        return instance.hasFieldName3();
-      }
-      /**
-       * <code>optional int32 FieldName3 = 3;</code>
-       * @return The fieldName3.
-       */
-      @java.lang.Override
-      public int getFieldName3() {
-        return instance.getFieldName3();
-      }
-      /**
-       * <code>optional int32 FieldName3 = 3;</code>
-       * @param value The fieldName3 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFieldName3(int value) {
-        copyOnWrite();
-        instance.setFieldName3(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 FieldName3 = 3;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFieldName3() {
-        copyOnWrite();
-        instance.clearFieldName3();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 _field_name4 = 4;</code>
-       * @return Whether the fieldName4 field is set.
-       */
-      @java.lang.Override
-      public boolean hasFieldName4() {
-        return instance.hasFieldName4();
-      }
-      /**
-       * <code>optional int32 _field_name4 = 4;</code>
-       * @return The fieldName4.
-       */
-      @java.lang.Override
-      public int getFieldName4() {
-        return instance.getFieldName4();
-      }
-      /**
-       * <code>optional int32 _field_name4 = 4;</code>
-       * @param value The fieldName4 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFieldName4(int value) {
-        copyOnWrite();
-        instance.setFieldName4(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 _field_name4 = 4;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFieldName4() {
-        copyOnWrite();
-        instance.clearFieldName4();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 FIELD_NAME5 = 5;</code>
-       * @return Whether the fIELDNAME5 field is set.
-       */
-      @java.lang.Override
-      public boolean hasFIELDNAME5() {
-        return instance.hasFIELDNAME5();
-      }
-      /**
-       * <code>optional int32 FIELD_NAME5 = 5;</code>
-       * @return The fIELDNAME5.
-       */
-      @java.lang.Override
-      public int getFIELDNAME5() {
-        return instance.getFIELDNAME5();
-      }
-      /**
-       * <code>optional int32 FIELD_NAME5 = 5;</code>
-       * @param value The fIELDNAME5 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFIELDNAME5(int value) {
-        copyOnWrite();
-        instance.setFIELDNAME5(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 FIELD_NAME5 = 5;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFIELDNAME5() {
-        copyOnWrite();
-        instance.clearFIELDNAME5();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 field_name6 = 6 [json_name = "&#64;type"];</code>
-       * @return Whether the fieldName6 field is set.
-       */
-      @java.lang.Override
-      public boolean hasFieldName6() {
-        return instance.hasFieldName6();
-      }
-      /**
-       * <code>optional int32 field_name6 = 6 [json_name = "&#64;type"];</code>
-       * @return The fieldName6.
-       */
-      @java.lang.Override
-      public int getFieldName6() {
-        return instance.getFieldName6();
-      }
-      /**
-       * <code>optional int32 field_name6 = 6 [json_name = "&#64;type"];</code>
-       * @param value The fieldName6 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFieldName6(int value) {
-        copyOnWrite();
-        instance.setFieldName6(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 field_name6 = 6 [json_name = "&#64;type"];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFieldName6() {
-        copyOnWrite();
-        instance.clearFieldName6();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestJsonName)
-    }
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestJsonName();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "fieldName1_",
-              "fieldName2_",
-              "fieldName3_",
-              "FieldName4_",
-              "fIELDNAME5_",
-              "fieldName6_",
-            };
-            java.lang.String info =
-                "\u0001\u0006\u0000\u0001\u0001\u0006\u0006\u0000\u0000\u0000\u0001\u1004\u0000\u0002" +
-                "\u1004\u0001\u0003\u1004\u0002\u0004\u1004\u0003\u0005\u1004\u0004\u0006\u1004\u0005" +
-                "";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestJsonName> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestJsonName.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestJsonName>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return (byte) 1;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestJsonName)
-    private static final protobuf_unittest.UnittestProto.TestJsonName DEFAULT_INSTANCE;
-    static {
-      TestJsonName defaultInstance = new TestJsonName();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestJsonName.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestJsonName getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestJsonName> PARSER;
-
-    public static com.google.protobuf.Parser<TestJsonName> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestHugeFieldNumbersOrBuilder extends 
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestHugeFieldNumbers)
-       com.google.protobuf.GeneratedMessageLite.
-            ExtendableMessageOrBuilder<
-                TestHugeFieldNumbers, TestHugeFieldNumbers.Builder> {
-
-    /**
-     * <code>optional int32 optional_int32 = 536870000;</code>
-     * @return Whether the optionalInt32 field is set.
-     */
-    boolean hasOptionalInt32();
-    /**
-     * <code>optional int32 optional_int32 = 536870000;</code>
-     * @return The optionalInt32.
-     */
-    int getOptionalInt32();
-
-    /**
-     * <code>optional int32 fixed_32 = 536870001;</code>
-     * @return Whether the fixed32 field is set.
-     */
-    boolean hasFixed32();
-    /**
-     * <code>optional int32 fixed_32 = 536870001;</code>
-     * @return The fixed32.
-     */
-    int getFixed32();
-
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @return A list containing the repeatedInt32.
-     */
-    java.util.List<java.lang.Integer> getRepeatedInt32List();
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @return The count of repeatedInt32.
-     */
-    int getRepeatedInt32Count();
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt32 at the given index.
-     */
-    int getRepeatedInt32(int index);
-
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @return A list containing the packedInt32.
-     */
-    java.util.List<java.lang.Integer> getPackedInt32List();
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @return The count of packedInt32.
-     */
-    int getPackedInt32Count();
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedInt32 at the given index.
-     */
-    int getPackedInt32(int index);
-
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum optional_enum = 536870004;</code>
-     * @return Whether the optionalEnum field is set.
-     */
-    boolean hasOptionalEnum();
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum optional_enum = 536870004;</code>
-     * @return The optionalEnum.
-     */
-    protobuf_unittest.UnittestProto.ForeignEnum getOptionalEnum();
-
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     * @return Whether the optionalString field is set.
-     */
-    boolean hasOptionalString();
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     * @return The optionalString.
-     */
-    java.lang.String getOptionalString();
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     * @return The bytes for optionalString.
-     */
-    com.google.protobuf.ByteString
-        getOptionalStringBytes();
-
-    /**
-     * <code>optional bytes optional_bytes = 536870006;</code>
-     * @return Whether the optionalBytes field is set.
-     */
-    boolean hasOptionalBytes();
-    /**
-     * <code>optional bytes optional_bytes = 536870006;</code>
-     * @return The optionalBytes.
-     */
-    com.google.protobuf.ByteString getOptionalBytes();
-
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage optional_message = 536870007;</code>
-     * @return Whether the optionalMessage field is set.
-     */
-    boolean hasOptionalMessage();
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage optional_message = 536870007;</code>
-     * @return The optionalMessage.
-     */
-    protobuf_unittest.UnittestProto.ForeignMessage getOptionalMessage();
-
-    /**
-     * <code>optional group OptionalGroup = 536870008 { ... }</code>
-     * @return Whether the optionalgroup field is set.
-     */
-    boolean hasOptionalGroup();
-    /**
-     * <code>optional group OptionalGroup = 536870008 { ... }</code>
-     * @return The optionalgroup.
-     */
-    protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup getOptionalGroup();
-
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    int getStringStringMapCount();
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    boolean containsStringStringMap(
-        java.lang.String key);
-    /**
-     * Use {@link #getStringStringMapMap()} instead.
-     */
-    @java.lang.Deprecated
-    java.util.Map<java.lang.String, java.lang.String>
-    getStringStringMap();
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    java.util.Map<java.lang.String, java.lang.String>
-    getStringStringMapMap();
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-
-    java.lang.String getStringStringMapOrDefault(
-        java.lang.String key,
-        java.lang.String defaultValue);
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-
-    java.lang.String getStringStringMapOrThrow(
-        java.lang.String key);
-
-    /**
-     * <code>uint32 oneof_uint32 = 536870011;</code>
-     * @return Whether the oneofUint32 field is set.
-     */
-    boolean hasOneofUint32();
-    /**
-     * <code>uint32 oneof_uint32 = 536870011;</code>
-     * @return The oneofUint32.
-     */
-    int getOneofUint32();
-
-    /**
-     * <code>.protobuf_unittest.TestAllTypes oneof_test_all_types = 536870012;</code>
-     * @return Whether the oneofTestAllTypes field is set.
-     */
-    boolean hasOneofTestAllTypes();
-    /**
-     * <code>.protobuf_unittest.TestAllTypes oneof_test_all_types = 536870012;</code>
-     * @return The oneofTestAllTypes.
-     */
-    protobuf_unittest.UnittestProto.TestAllTypes getOneofTestAllTypes();
-
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     * @return Whether the oneofString field is set.
-     */
-    boolean hasOneofString();
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     * @return The oneofString.
-     */
-    java.lang.String getOneofString();
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     * @return The bytes for oneofString.
-     */
-    com.google.protobuf.ByteString
-        getOneofStringBytes();
-
-    /**
-     * <code>bytes oneof_bytes = 536870014;</code>
-     * @return Whether the oneofBytes field is set.
-     */
-    boolean hasOneofBytes();
-    /**
-     * <code>bytes oneof_bytes = 536870014;</code>
-     * @return The oneofBytes.
-     */
-    com.google.protobuf.ByteString getOneofBytes();
-
-    public protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OneofFieldCase getOneofFieldCase();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestHugeFieldNumbers}
-   */
-  public  static final class TestHugeFieldNumbers extends
-      com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
-        TestHugeFieldNumbers, TestHugeFieldNumbers.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestHugeFieldNumbers)
-      TestHugeFieldNumbersOrBuilder {
-    private TestHugeFieldNumbers() {
-      repeatedInt32_ = emptyIntList();
-      packedInt32_ = emptyIntList();
-      optionalEnum_ = 4;
-      optionalString_ = "";
-      optionalBytes_ = com.google.protobuf.ByteString.EMPTY;
-    }
-    public interface OptionalGroupOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestHugeFieldNumbers.OptionalGroup)
-        com.google.protobuf.MessageLiteOrBuilder {
-
-      /**
-       * <code>optional int32 group_a = 536870009;</code>
-       * @return Whether the groupA field is set.
-       */
-      boolean hasGroupA();
-      /**
-       * <code>optional int32 group_a = 536870009;</code>
-       * @return The groupA.
-       */
-      int getGroupA();
-    }
-    /**
-     * Protobuf type {@code protobuf_unittest.TestHugeFieldNumbers.OptionalGroup}
-     */
-    public  static final class OptionalGroup extends
-        com.google.protobuf.GeneratedMessageLite<
-            OptionalGroup, OptionalGroup.Builder> implements
-        // @@protoc_insertion_point(message_implements:protobuf_unittest.TestHugeFieldNumbers.OptionalGroup)
-        OptionalGroupOrBuilder {
-      private OptionalGroup() {
-      }
-      private int bitField0_;
-      public static final int GROUP_A_FIELD_NUMBER = 536870009;
-      private int groupA_;
-      /**
-       * <code>optional int32 group_a = 536870009;</code>
-       * @return Whether the groupA field is set.
-       */
-      @java.lang.Override
-      public boolean hasGroupA() {
-        return ((bitField0_ & 0x00000001) != 0);
-      }
-      /**
-       * <code>optional int32 group_a = 536870009;</code>
-       * @return The groupA.
-       */
-      @java.lang.Override
-      public int getGroupA() {
-        return groupA_;
-      }
-      /**
-       * <code>optional int32 group_a = 536870009;</code>
-       * @param value The groupA to set.
-       */
-      private void setGroupA(int value) {
-        bitField0_ |= 0x00000001;
-        groupA_ = value;
-      }
-      /**
-       * <code>optional int32 group_a = 536870009;</code>
-       */
-      private void clearGroupA() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        groupA_ = 0;
-      }
-
-      public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup parseFrom(
-          java.nio.ByteBuffer data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup parseFrom(
-          java.nio.ByteBuffer data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data);
-      }
-      public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, data, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-      public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input);
-      }
-      public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return com.google.protobuf.GeneratedMessageLite.parseFrom(
-            DEFAULT_INSTANCE, input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() {
-        return (Builder) DEFAULT_INSTANCE.createBuilder();
-      }
-      public static Builder newBuilder(protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup prototype) {
-        return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-      }
-
-      /**
-       * Protobuf type {@code protobuf_unittest.TestHugeFieldNumbers.OptionalGroup}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessageLite.Builder<
-            protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup, Builder> implements
-          // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestHugeFieldNumbers.OptionalGroup)
-          protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroupOrBuilder {
-        // Construct using protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup.newBuilder()
-        private Builder() {
-          super(DEFAULT_INSTANCE);
-        }
-
-
-        /**
-         * <code>optional int32 group_a = 536870009;</code>
-         * @return Whether the groupA field is set.
-         */
-        @java.lang.Override
-        public boolean hasGroupA() {
-          return instance.hasGroupA();
-        }
-        /**
-         * <code>optional int32 group_a = 536870009;</code>
-         * @return The groupA.
-         */
-        @java.lang.Override
-        public int getGroupA() {
-          return instance.getGroupA();
-        }
-        /**
-         * <code>optional int32 group_a = 536870009;</code>
-         * @param value The groupA to set.
-         * @return This builder for chaining.
-         */
-        public Builder setGroupA(int value) {
-          copyOnWrite();
-          instance.setGroupA(value);
-          return this;
-        }
-        /**
-         * <code>optional int32 group_a = 536870009;</code>
-         * @return This builder for chaining.
-         */
-        public Builder clearGroupA() {
-          copyOnWrite();
-          instance.clearGroupA();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestHugeFieldNumbers.OptionalGroup)
-      }
-      @java.lang.Override
-      @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-      protected final java.lang.Object dynamicMethod(
-          com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-          java.lang.Object arg0, java.lang.Object arg1) {
-        switch (method) {
-          case NEW_MUTABLE_INSTANCE: {
-            return new protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup();
-          }
-          case NEW_BUILDER: {
-            return new Builder();
-          }
-          case BUILD_MESSAGE_INFO: {
-              java.lang.Object[] objects = new java.lang.Object[] {
-                "bitField0_",
-                "groupA_",
-              };
-              java.lang.String info =
-                  "\u0001\u0001\u0000\u0001\ufc79\uffff\u0007\ufc79\uffff\u0007\u0001\u0000\u0000\u0000" +
-                  "\ufc79\uffff\u0007\u1004\u0000";
-              return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-          }
-          // fall through
-          case GET_DEFAULT_INSTANCE: {
-            return DEFAULT_INSTANCE;
-          }
-          case GET_PARSER: {
-            com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup> parser = PARSER;
-            if (parser == null) {
-              synchronized (protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup.class) {
-                parser = PARSER;
-                if (parser == null) {
-                  parser =
-                      new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup>(
-                          DEFAULT_INSTANCE);
-                  PARSER = parser;
-                }
-              }
-            }
-            return parser;
-        }
-        case GET_MEMOIZED_IS_INITIALIZED: {
-          return (byte) 1;
-        }
-        case SET_MEMOIZED_IS_INITIALIZED: {
-          return null;
-        }
-        }
-        throw new UnsupportedOperationException();
-      }
-
-
-      // @@protoc_insertion_point(class_scope:protobuf_unittest.TestHugeFieldNumbers.OptionalGroup)
-      private static final protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup DEFAULT_INSTANCE;
-      static {
-        OptionalGroup defaultInstance = new OptionalGroup();
-        // New instances are implicitly immutable so no need to make
-        // immutable.
-        DEFAULT_INSTANCE = defaultInstance;
-        com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-          OptionalGroup.class, defaultInstance);
-      }
-
-      public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      private static volatile com.google.protobuf.Parser<OptionalGroup> PARSER;
-
-      public static com.google.protobuf.Parser<OptionalGroup> parser() {
-        return DEFAULT_INSTANCE.getParserForType();
-      }
-    }
-
-    private int bitField0_;
-    private int oneofFieldCase_ = 0;
-    private java.lang.Object oneofField_;
-    public enum OneofFieldCase {
-      ONEOF_UINT32(536870011),
-      ONEOF_TEST_ALL_TYPES(536870012),
-      ONEOF_STRING(536870013),
-      ONEOF_BYTES(536870014),
-      ONEOFFIELD_NOT_SET(0);
-      private final int value;
-      private OneofFieldCase(int value) {
-        this.value = value;
-      }
-      /**
-       * @deprecated Use {@link #forNumber(int)} instead.
-       */
-      @java.lang.Deprecated
-      public static OneofFieldCase valueOf(int value) {
-        return forNumber(value);
-      }
-
-      public static OneofFieldCase forNumber(int value) {
-        switch (value) {
-          case 536870011: return ONEOF_UINT32;
-          case 536870012: return ONEOF_TEST_ALL_TYPES;
-          case 536870013: return ONEOF_STRING;
-          case 536870014: return ONEOF_BYTES;
-          case 0: return ONEOFFIELD_NOT_SET;
-          default: return null;
-        }
-      }
-      public int getNumber() {
-        return this.value;
-      }
-    };
-
-    @java.lang.Override
-    public OneofFieldCase
-    getOneofFieldCase() {
-      return OneofFieldCase.forNumber(
-          oneofFieldCase_);
-    }
-
-    private void clearOneofField() {
-      oneofFieldCase_ = 0;
-      oneofField_ = null;
-    }
-
-    public static final int OPTIONAL_INT32_FIELD_NUMBER = 536870000;
-    private int optionalInt32_;
-    /**
-     * <code>optional int32 optional_int32 = 536870000;</code>
-     * @return Whether the optionalInt32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalInt32() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 optional_int32 = 536870000;</code>
-     * @return The optionalInt32.
-     */
-    @java.lang.Override
-    public int getOptionalInt32() {
-      return optionalInt32_;
-    }
-    /**
-     * <code>optional int32 optional_int32 = 536870000;</code>
-     * @param value The optionalInt32 to set.
-     */
-    private void setOptionalInt32(int value) {
-      bitField0_ |= 0x00000001;
-      optionalInt32_ = value;
-    }
-    /**
-     * <code>optional int32 optional_int32 = 536870000;</code>
-     */
-    private void clearOptionalInt32() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      optionalInt32_ = 0;
-    }
-
-    public static final int FIXED_32_FIELD_NUMBER = 536870001;
-    private int fixed32_;
-    /**
-     * <code>optional int32 fixed_32 = 536870001;</code>
-     * @return Whether the fixed32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasFixed32() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional int32 fixed_32 = 536870001;</code>
-     * @return The fixed32.
-     */
-    @java.lang.Override
-    public int getFixed32() {
-      return fixed32_;
-    }
-    /**
-     * <code>optional int32 fixed_32 = 536870001;</code>
-     * @param value The fixed32 to set.
-     */
-    private void setFixed32(int value) {
-      bitField0_ |= 0x00000002;
-      fixed32_ = value;
-    }
-    /**
-     * <code>optional int32 fixed_32 = 536870001;</code>
-     */
-    private void clearFixed32() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      fixed32_ = 0;
-    }
-
-    public static final int REPEATED_INT32_FIELD_NUMBER = 536870002;
-    private com.google.protobuf.Internal.IntList repeatedInt32_;
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @return A list containing the repeatedInt32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getRepeatedInt32List() {
-      return repeatedInt32_;
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @return The count of repeatedInt32.
-     */
-    @java.lang.Override
-    public int getRepeatedInt32Count() {
-      return repeatedInt32_.size();
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @param index The index of the element to return.
-     * @return The repeatedInt32 at the given index.
-     */
-    @java.lang.Override
-    public int getRepeatedInt32(int index) {
-      return repeatedInt32_.getInt(index);
-    }
-    private void ensureRepeatedInt32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = repeatedInt32_;
-      if (!tmp.isModifiable()) {
-        repeatedInt32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @param index The index to set the value at.
-     * @param value The repeatedInt32 to set.
-     */
-    private void setRepeatedInt32(
-        int index, int value) {
-      ensureRepeatedInt32IsMutable();
-      repeatedInt32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @param value The repeatedInt32 to add.
-     */
-    private void addRepeatedInt32(int value) {
-      ensureRepeatedInt32IsMutable();
-      repeatedInt32_.addInt(value);
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     * @param values The repeatedInt32 to add.
-     */
-    private void addAllRepeatedInt32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensureRepeatedInt32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, repeatedInt32_);
-    }
-    /**
-     * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-     */
-    private void clearRepeatedInt32() {
-      repeatedInt32_ = emptyIntList();
-    }
-
-    public static final int PACKED_INT32_FIELD_NUMBER = 536870003;
-    private com.google.protobuf.Internal.IntList packedInt32_;
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @return A list containing the packedInt32.
-     */
-    @java.lang.Override
-    public java.util.List<java.lang.Integer>
-        getPackedInt32List() {
-      return packedInt32_;
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @return The count of packedInt32.
-     */
-    @java.lang.Override
-    public int getPackedInt32Count() {
-      return packedInt32_.size();
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @param index The index of the element to return.
-     * @return The packedInt32 at the given index.
-     */
-    @java.lang.Override
-    public int getPackedInt32(int index) {
-      return packedInt32_.getInt(index);
-    }
-    private int packedInt32MemoizedSerializedSize = -1;
-    private void ensurePackedInt32IsMutable() {
-      com.google.protobuf.Internal.IntList tmp = packedInt32_;
-      if (!tmp.isModifiable()) {
-        packedInt32_ =
-            com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);
-       }
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @param index The index to set the value at.
-     * @param value The packedInt32 to set.
-     */
-    private void setPackedInt32(
-        int index, int value) {
-      ensurePackedInt32IsMutable();
-      packedInt32_.setInt(index, value);
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @param value The packedInt32 to add.
-     */
-    private void addPackedInt32(int value) {
-      ensurePackedInt32IsMutable();
-      packedInt32_.addInt(value);
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     * @param values The packedInt32 to add.
-     */
-    private void addAllPackedInt32(
-        java.lang.Iterable<? extends java.lang.Integer> values) {
-      ensurePackedInt32IsMutable();
-      com.google.protobuf.AbstractMessageLite.addAll(
-          values, packedInt32_);
-    }
-    /**
-     * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-     */
-    private void clearPackedInt32() {
-      packedInt32_ = emptyIntList();
-    }
-
-    public static final int OPTIONAL_ENUM_FIELD_NUMBER = 536870004;
-    private int optionalEnum_;
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum optional_enum = 536870004;</code>
-     * @return Whether the optionalEnum field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalEnum() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum optional_enum = 536870004;</code>
-     * @return The optionalEnum.
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.ForeignEnum getOptionalEnum() {
-      protobuf_unittest.UnittestProto.ForeignEnum result = protobuf_unittest.UnittestProto.ForeignEnum.forNumber(optionalEnum_);
-      return result == null ? protobuf_unittest.UnittestProto.ForeignEnum.FOREIGN_FOO : result;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum optional_enum = 536870004;</code>
-     * @param value The optionalEnum to set.
-     */
-    private void setOptionalEnum(protobuf_unittest.UnittestProto.ForeignEnum value) {
-      optionalEnum_ = value.getNumber();
-      bitField0_ |= 0x00000004;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignEnum optional_enum = 536870004;</code>
-     */
-    private void clearOptionalEnum() {
-      bitField0_ = (bitField0_ & ~0x00000004);
-      optionalEnum_ = 4;
-    }
-
-    public static final int OPTIONAL_STRING_FIELD_NUMBER = 536870005;
-    private java.lang.String optionalString_;
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     * @return Whether the optionalString field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalString() {
-      return ((bitField0_ & 0x00000008) != 0);
-    }
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     * @return The optionalString.
-     */
-    @java.lang.Override
-    public java.lang.String getOptionalString() {
-      return optionalString_;
-    }
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     * @return The bytes for optionalString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOptionalStringBytes() {
-      return com.google.protobuf.ByteString.copyFromUtf8(optionalString_);
-    }
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     * @param value The optionalString to set.
-     */
-    private void setOptionalString(
-        java.lang.String value) {
-      value.getClass();
-  bitField0_ |= 0x00000008;
-      optionalString_ = value;
-    }
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     */
-    private void clearOptionalString() {
-      bitField0_ = (bitField0_ & ~0x00000008);
-      optionalString_ = getDefaultInstance().getOptionalString();
-    }
-    /**
-     * <code>optional string optional_string = 536870005;</code>
-     * @param value The bytes for optionalString to set.
-     */
-    private void setOptionalStringBytes(
-        com.google.protobuf.ByteString value) {
-      optionalString_ = value.toStringUtf8();
-      bitField0_ |= 0x00000008;
-    }
-
-    public static final int OPTIONAL_BYTES_FIELD_NUMBER = 536870006;
-    private com.google.protobuf.ByteString optionalBytes_;
-    /**
-     * <code>optional bytes optional_bytes = 536870006;</code>
-     * @return Whether the optionalBytes field is set.
-     */
-    @java.lang.Override
-    public boolean hasOptionalBytes() {
-      return ((bitField0_ & 0x00000010) != 0);
-    }
-    /**
-     * <code>optional bytes optional_bytes = 536870006;</code>
-     * @return The optionalBytes.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getOptionalBytes() {
-      return optionalBytes_;
-    }
-    /**
-     * <code>optional bytes optional_bytes = 536870006;</code>
-     * @param value The optionalBytes to set.
-     */
-    private void setOptionalBytes(com.google.protobuf.ByteString value) {
-      value.getClass();
-  bitField0_ |= 0x00000010;
-      optionalBytes_ = value;
-    }
-    /**
-     * <code>optional bytes optional_bytes = 536870006;</code>
-     */
-    private void clearOptionalBytes() {
-      bitField0_ = (bitField0_ & ~0x00000010);
-      optionalBytes_ = getDefaultInstance().getOptionalBytes();
-    }
-
-    public static final int OPTIONAL_MESSAGE_FIELD_NUMBER = 536870007;
-    private protobuf_unittest.UnittestProto.ForeignMessage optionalMessage_;
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage optional_message = 536870007;</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalMessage() {
-      return ((bitField0_ & 0x00000020) != 0);
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage optional_message = 536870007;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.ForeignMessage getOptionalMessage() {
-      return optionalMessage_ == null ? protobuf_unittest.UnittestProto.ForeignMessage.getDefaultInstance() : optionalMessage_;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage optional_message = 536870007;</code>
-     */
-    private void setOptionalMessage(protobuf_unittest.UnittestProto.ForeignMessage value) {
-      value.getClass();
-  optionalMessage_ = value;
-      bitField0_ |= 0x00000020;
-      }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage optional_message = 536870007;</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalMessage(protobuf_unittest.UnittestProto.ForeignMessage value) {
-      value.getClass();
-  if (optionalMessage_ != null &&
-          optionalMessage_ != protobuf_unittest.UnittestProto.ForeignMessage.getDefaultInstance()) {
-        optionalMessage_ =
-          protobuf_unittest.UnittestProto.ForeignMessage.newBuilder(optionalMessage_).mergeFrom(value).buildPartial();
-      } else {
-        optionalMessage_ = value;
-      }
-      bitField0_ |= 0x00000020;
-    }
-    /**
-     * <code>optional .protobuf_unittest.ForeignMessage optional_message = 536870007;</code>
-     */
-    private void clearOptionalMessage() {  optionalMessage_ = null;
-      bitField0_ = (bitField0_ & ~0x00000020);
-    }
-
-    public static final int OPTIONALGROUP_FIELD_NUMBER = 536870008;
-    private protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup optionalGroup_;
-    /**
-     * <code>optional group OptionalGroup = 536870008 { ... }</code>
-     */
-    @java.lang.Override
-    public boolean hasOptionalGroup() {
-      return ((bitField0_ & 0x00000040) != 0);
-    }
-    /**
-     * <code>optional group OptionalGroup = 536870008 { ... }</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup getOptionalGroup() {
-      return optionalGroup_ == null ? protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup.getDefaultInstance() : optionalGroup_;
-    }
-    /**
-     * <code>optional group OptionalGroup = 536870008 { ... }</code>
-     */
-    private void setOptionalGroup(protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup value) {
-      value.getClass();
-  optionalGroup_ = value;
-      bitField0_ |= 0x00000040;
-      }
-    /**
-     * <code>optional group OptionalGroup = 536870008 { ... }</code>
-     */
-    @java.lang.SuppressWarnings({"ReferenceEquality"})
-    private void mergeOptionalGroup(protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup value) {
-      value.getClass();
-  if (optionalGroup_ != null &&
-          optionalGroup_ != protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup.getDefaultInstance()) {
-        optionalGroup_ =
-          protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup.newBuilder(optionalGroup_).mergeFrom(value).buildPartial();
-      } else {
-        optionalGroup_ = value;
-      }
-      bitField0_ |= 0x00000040;
-    }
-    /**
-     * <code>optional group OptionalGroup = 536870008 { ... }</code>
-     */
-    private void clearOptionalGroup() {  optionalGroup_ = null;
-      bitField0_ = (bitField0_ & ~0x00000040);
-    }
-
-    public static final int STRING_STRING_MAP_FIELD_NUMBER = 536870010;
-    private static final class StringStringMapDefaultEntryHolder {
-      static final com.google.protobuf.MapEntryLite<
-          java.lang.String, java.lang.String> defaultEntry =
-              com.google.protobuf.MapEntryLite
-              .<java.lang.String, java.lang.String>newDefaultInstance(
-                  com.google.protobuf.WireFormat.FieldType.STRING,
-                  "",
-                  com.google.protobuf.WireFormat.FieldType.STRING,
-                  "");
-    }
-    private com.google.protobuf.MapFieldLite<
-        java.lang.String, java.lang.String> stringStringMap_ =
-            com.google.protobuf.MapFieldLite.emptyMapField();
-    private com.google.protobuf.MapFieldLite<java.lang.String, java.lang.String>
-    internalGetStringStringMap() {
-      return stringStringMap_;
-    }
-    private com.google.protobuf.MapFieldLite<java.lang.String, java.lang.String>
-    internalGetMutableStringStringMap() {
-      if (!stringStringMap_.isMutable()) {
-        stringStringMap_ = stringStringMap_.mutableCopy();
-      }
-      return stringStringMap_;
-    }
-    @java.lang.Override
-
-    public int getStringStringMapCount() {
-      return internalGetStringStringMap().size();
-    }
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    @java.lang.Override
-
-    public boolean containsStringStringMap(
-        java.lang.String key) {
-      key.getClass();
-      return internalGetStringStringMap().containsKey(key);
-    }
-    /**
-     * Use {@link #getStringStringMapMap()} instead.
-     */
-    @java.lang.Override
-    @java.lang.Deprecated
-    public java.util.Map<java.lang.String, java.lang.String> getStringStringMap() {
-      return getStringStringMapMap();
-    }
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    @java.lang.Override
-
-    public java.util.Map<java.lang.String, java.lang.String> getStringStringMapMap() {
-      return java.util.Collections.unmodifiableMap(
-          internalGetStringStringMap());
-    }
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    @java.lang.Override
-
-    public java.lang.String getStringStringMapOrDefault(
-        java.lang.String key,
-        java.lang.String defaultValue) {
-      key.getClass();
-      java.util.Map<java.lang.String, java.lang.String> map =
-          internalGetStringStringMap();
-      return map.containsKey(key) ? map.get(key) : defaultValue;
-    }
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    @java.lang.Override
-
-    public java.lang.String getStringStringMapOrThrow(
-        java.lang.String key) {
-      key.getClass();
-      java.util.Map<java.lang.String, java.lang.String> map =
-          internalGetStringStringMap();
-      if (!map.containsKey(key)) {
-        throw new java.lang.IllegalArgumentException();
-      }
-      return map.get(key);
-    }
-    /**
-     * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-     */
-    private java.util.Map<java.lang.String, java.lang.String>
-    getMutableStringStringMapMap() {
-      return internalGetMutableStringStringMap();
-    }
-
-    public static final int ONEOF_UINT32_FIELD_NUMBER = 536870011;
-    /**
-     * <code>uint32 oneof_uint32 = 536870011;</code>
-     * @return Whether the oneofUint32 field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofUint32() {
-      return oneofFieldCase_ == 536870011;
-    }
-    /**
-     * <code>uint32 oneof_uint32 = 536870011;</code>
-     * @return The oneofUint32.
-     */
-    @java.lang.Override
-    public int getOneofUint32() {
-      if (oneofFieldCase_ == 536870011) {
-        return (java.lang.Integer) oneofField_;
-      }
-      return 0;
-    }
-    /**
-     * <code>uint32 oneof_uint32 = 536870011;</code>
-     * @param value The oneofUint32 to set.
-     */
-    private void setOneofUint32(int value) {
-      oneofFieldCase_ = 536870011;
-      oneofField_ = value;
-    }
-    /**
-     * <code>uint32 oneof_uint32 = 536870011;</code>
-     */
-    private void clearOneofUint32() {
-      if (oneofFieldCase_ == 536870011) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static final int ONEOF_TEST_ALL_TYPES_FIELD_NUMBER = 536870012;
-    /**
-     * <code>.protobuf_unittest.TestAllTypes oneof_test_all_types = 536870012;</code>
-     */
-    @java.lang.Override
-    public boolean hasOneofTestAllTypes() {
-      return oneofFieldCase_ == 536870012;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypes oneof_test_all_types = 536870012;</code>
-     */
-    @java.lang.Override
-    public protobuf_unittest.UnittestProto.TestAllTypes getOneofTestAllTypes() {
-      if (oneofFieldCase_ == 536870012) {
-         return (protobuf_unittest.UnittestProto.TestAllTypes) oneofField_;
-      }
-      return protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance();
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypes oneof_test_all_types = 536870012;</code>
-     */
-    private void setOneofTestAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-      value.getClass();
-  oneofField_ = value;
-      oneofFieldCase_ = 536870012;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypes oneof_test_all_types = 536870012;</code>
-     */
-    private void mergeOneofTestAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-      value.getClass();
-  if (oneofFieldCase_ == 536870012 &&
-          oneofField_ != protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance()) {
-        oneofField_ = protobuf_unittest.UnittestProto.TestAllTypes.newBuilder((protobuf_unittest.UnittestProto.TestAllTypes) oneofField_)
-            .mergeFrom(value).buildPartial();
-      } else {
-        oneofField_ = value;
-      }
-      oneofFieldCase_ = 536870012;
-    }
-    /**
-     * <code>.protobuf_unittest.TestAllTypes oneof_test_all_types = 536870012;</code>
-     */
-    private void clearOneofTestAllTypes() {
-      if (oneofFieldCase_ == 536870012) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static final int ONEOF_STRING_FIELD_NUMBER = 536870013;
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     * @return Whether the oneofString field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofString() {
-      return oneofFieldCase_ == 536870013;
-    }
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     * @return The oneofString.
-     */
-    @java.lang.Override
-    public java.lang.String getOneofString() {
-      java.lang.String ref = "";
-      if (oneofFieldCase_ == 536870013) {
-        ref = (java.lang.String) oneofField_;
-      }
-      return ref;
-    }
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     * @return The bytes for oneofString.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getOneofStringBytes() {
-      java.lang.String ref = "";
-      if (oneofFieldCase_ == 536870013) {
-        ref = (java.lang.String) oneofField_;
-      }
-      return com.google.protobuf.ByteString.copyFromUtf8(ref);
-    }
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     * @param value The oneofString to set.
-     */
-    private void setOneofString(
-        java.lang.String value) {
-      value.getClass();
-  oneofFieldCase_ = 536870013;
-      oneofField_ = value;
-    }
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     */
-    private void clearOneofString() {
-      if (oneofFieldCase_ == 536870013) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-    /**
-     * <code>string oneof_string = 536870013;</code>
-     * @param value The bytes for oneofString to set.
-     */
-    private void setOneofStringBytes(
-        com.google.protobuf.ByteString value) {
-      oneofField_ = value.toStringUtf8();
-      oneofFieldCase_ = 536870013;
-    }
-
-    public static final int ONEOF_BYTES_FIELD_NUMBER = 536870014;
-    /**
-     * <code>bytes oneof_bytes = 536870014;</code>
-     * @return Whether the oneofBytes field is set.
-     */
-    @java.lang.Override
-    public boolean hasOneofBytes() {
-      return oneofFieldCase_ == 536870014;
-    }
-    /**
-     * <code>bytes oneof_bytes = 536870014;</code>
-     * @return The oneofBytes.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString getOneofBytes() {
-      if (oneofFieldCase_ == 536870014) {
-        return (com.google.protobuf.ByteString) oneofField_;
-      }
-      return com.google.protobuf.ByteString.EMPTY;
-    }
-    /**
-     * <code>bytes oneof_bytes = 536870014;</code>
-     * @param value The oneofBytes to set.
-     */
-    private void setOneofBytes(com.google.protobuf.ByteString value) {
-      value.getClass();
-  oneofFieldCase_ = 536870014;
-      oneofField_ = value;
-    }
-    /**
-     * <code>bytes oneof_bytes = 536870014;</code>
-     */
-    private void clearOneofBytes() {
-      if (oneofFieldCase_ == 536870014) {
-        oneofFieldCase_ = 0;
-        oneofField_ = null;
-      }
-    }
-
-    public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestHugeFieldNumbers prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestHugeFieldNumbers}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
-          protobuf_unittest.UnittestProto.TestHugeFieldNumbers, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestHugeFieldNumbers)
-        protobuf_unittest.UnittestProto.TestHugeFieldNumbersOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestHugeFieldNumbers.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-      @java.lang.Override
-      public OneofFieldCase
-          getOneofFieldCase() {
-        return instance.getOneofFieldCase();
-      }
-
-      public Builder clearOneofField() {
-        copyOnWrite();
-        instance.clearOneofField();
-        return this;
-      }
-
-
-      /**
-       * <code>optional int32 optional_int32 = 536870000;</code>
-       * @return Whether the optionalInt32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalInt32() {
-        return instance.hasOptionalInt32();
-      }
-      /**
-       * <code>optional int32 optional_int32 = 536870000;</code>
-       * @return The optionalInt32.
-       */
-      @java.lang.Override
-      public int getOptionalInt32() {
-        return instance.getOptionalInt32();
-      }
-      /**
-       * <code>optional int32 optional_int32 = 536870000;</code>
-       * @param value The optionalInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalInt32(int value) {
-        copyOnWrite();
-        instance.setOptionalInt32(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 optional_int32 = 536870000;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalInt32() {
-        copyOnWrite();
-        instance.clearOptionalInt32();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 fixed_32 = 536870001;</code>
-       * @return Whether the fixed32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasFixed32() {
-        return instance.hasFixed32();
-      }
-      /**
-       * <code>optional int32 fixed_32 = 536870001;</code>
-       * @return The fixed32.
-       */
-      @java.lang.Override
-      public int getFixed32() {
-        return instance.getFixed32();
-      }
-      /**
-       * <code>optional int32 fixed_32 = 536870001;</code>
-       * @param value The fixed32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFixed32(int value) {
-        copyOnWrite();
-        instance.setFixed32(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 fixed_32 = 536870001;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFixed32() {
-        copyOnWrite();
-        instance.clearFixed32();
-        return this;
-      }
-
-      /**
-       * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-       * @return A list containing the repeatedInt32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getRepeatedInt32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getRepeatedInt32List());
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-       * @return The count of repeatedInt32.
-       */
-      @java.lang.Override
-      public int getRepeatedInt32Count() {
-        return instance.getRepeatedInt32Count();
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-       * @param index The index of the element to return.
-       * @return The repeatedInt32 at the given index.
-       */
-      @java.lang.Override
-      public int getRepeatedInt32(int index) {
-        return instance.getRepeatedInt32(index);
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-       * @param value The repeatedInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setRepeatedInt32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setRepeatedInt32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-       * @param value The repeatedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addRepeatedInt32(int value) {
-        copyOnWrite();
-        instance.addRepeatedInt32(value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-       * @param values The repeatedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllRepeatedInt32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllRepeatedInt32(values);
-        return this;
-      }
-      /**
-       * <code>repeated int32 repeated_int32 = 536870002 [packed = false];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearRepeatedInt32() {
-        copyOnWrite();
-        instance.clearRepeatedInt32();
-        return this;
-      }
-
-      /**
-       * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-       * @return A list containing the packedInt32.
-       */
-      @java.lang.Override
-      public java.util.List<java.lang.Integer>
-          getPackedInt32List() {
-        return java.util.Collections.unmodifiableList(
-            instance.getPackedInt32List());
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-       * @return The count of packedInt32.
-       */
-      @java.lang.Override
-      public int getPackedInt32Count() {
-        return instance.getPackedInt32Count();
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-       * @param index The index of the element to return.
-       * @return The packedInt32 at the given index.
-       */
-      @java.lang.Override
-      public int getPackedInt32(int index) {
-        return instance.getPackedInt32(index);
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-       * @param value The packedInt32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPackedInt32(
-          int index, int value) {
-        copyOnWrite();
-        instance.setPackedInt32(index, value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-       * @param value The packedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addPackedInt32(int value) {
-        copyOnWrite();
-        instance.addPackedInt32(value);
-        return this;
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-       * @param values The packedInt32 to add.
-       * @return This builder for chaining.
-       */
-      public Builder addAllPackedInt32(
-          java.lang.Iterable<? extends java.lang.Integer> values) {
-        copyOnWrite();
-        instance.addAllPackedInt32(values);
-        return this;
-      }
-      /**
-       * <code>repeated int32 packed_int32 = 536870003 [packed = true];</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPackedInt32() {
-        copyOnWrite();
-        instance.clearPackedInt32();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum optional_enum = 536870004;</code>
-       * @return Whether the optionalEnum field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalEnum() {
-        return instance.hasOptionalEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum optional_enum = 536870004;</code>
-       * @return The optionalEnum.
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.ForeignEnum getOptionalEnum() {
-        return instance.getOptionalEnum();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum optional_enum = 536870004;</code>
-       * @param value The enum numeric value on the wire for optionalEnum to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalEnum(protobuf_unittest.UnittestProto.ForeignEnum value) {
-        copyOnWrite();
-        instance.setOptionalEnum(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignEnum optional_enum = 536870004;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalEnum() {
-        copyOnWrite();
-        instance.clearOptionalEnum();
-        return this;
-      }
-
-      /**
-       * <code>optional string optional_string = 536870005;</code>
-       * @return Whether the optionalString field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalString() {
-        return instance.hasOptionalString();
-      }
-      /**
-       * <code>optional string optional_string = 536870005;</code>
-       * @return The optionalString.
-       */
-      @java.lang.Override
-      public java.lang.String getOptionalString() {
-        return instance.getOptionalString();
-      }
-      /**
-       * <code>optional string optional_string = 536870005;</code>
-       * @return The bytes for optionalString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getOptionalStringBytes() {
-        return instance.getOptionalStringBytes();
-      }
-      /**
-       * <code>optional string optional_string = 536870005;</code>
-       * @param value The optionalString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setOptionalString(value);
-        return this;
-      }
-      /**
-       * <code>optional string optional_string = 536870005;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalString() {
-        copyOnWrite();
-        instance.clearOptionalString();
-        return this;
-      }
-      /**
-       * <code>optional string optional_string = 536870005;</code>
-       * @param value The bytes for optionalString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOptionalStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>optional bytes optional_bytes = 536870006;</code>
-       * @return Whether the optionalBytes field is set.
-       */
-      @java.lang.Override
-      public boolean hasOptionalBytes() {
-        return instance.hasOptionalBytes();
-      }
-      /**
-       * <code>optional bytes optional_bytes = 536870006;</code>
-       * @return The optionalBytes.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getOptionalBytes() {
-        return instance.getOptionalBytes();
-      }
-      /**
-       * <code>optional bytes optional_bytes = 536870006;</code>
-       * @param value The optionalBytes to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOptionalBytes(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOptionalBytes(value);
-        return this;
-      }
-      /**
-       * <code>optional bytes optional_bytes = 536870006;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOptionalBytes() {
-        copyOnWrite();
-        instance.clearOptionalBytes();
-        return this;
-      }
-
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage optional_message = 536870007;</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalMessage() {
-        return instance.hasOptionalMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage optional_message = 536870007;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.ForeignMessage getOptionalMessage() {
-        return instance.getOptionalMessage();
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage optional_message = 536870007;</code>
-       */
-      public Builder setOptionalMessage(protobuf_unittest.UnittestProto.ForeignMessage value) {
-        copyOnWrite();
-        instance.setOptionalMessage(value);
-        return this;
-        }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage optional_message = 536870007;</code>
-       */
-      public Builder setOptionalMessage(
-          protobuf_unittest.UnittestProto.ForeignMessage.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalMessage(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage optional_message = 536870007;</code>
-       */
-      public Builder mergeOptionalMessage(protobuf_unittest.UnittestProto.ForeignMessage value) {
-        copyOnWrite();
-        instance.mergeOptionalMessage(value);
-        return this;
-      }
-      /**
-       * <code>optional .protobuf_unittest.ForeignMessage optional_message = 536870007;</code>
-       */
-      public Builder clearOptionalMessage() {  copyOnWrite();
-        instance.clearOptionalMessage();
-        return this;
-      }
-
-      /**
-       * <code>optional group OptionalGroup = 536870008 { ... }</code>
-       */
-      @java.lang.Override
-      public boolean hasOptionalGroup() {
-        return instance.hasOptionalGroup();
-      }
-      /**
-       * <code>optional group OptionalGroup = 536870008 { ... }</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup getOptionalGroup() {
-        return instance.getOptionalGroup();
-      }
-      /**
-       * <code>optional group OptionalGroup = 536870008 { ... }</code>
-       */
-      public Builder setOptionalGroup(protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup value) {
-        copyOnWrite();
-        instance.setOptionalGroup(value);
-        return this;
-        }
-      /**
-       * <code>optional group OptionalGroup = 536870008 { ... }</code>
-       */
-      public Builder setOptionalGroup(
-          protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOptionalGroup(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>optional group OptionalGroup = 536870008 { ... }</code>
-       */
-      public Builder mergeOptionalGroup(protobuf_unittest.UnittestProto.TestHugeFieldNumbers.OptionalGroup value) {
-        copyOnWrite();
-        instance.mergeOptionalGroup(value);
-        return this;
-      }
-      /**
-       * <code>optional group OptionalGroup = 536870008 { ... }</code>
-       */
-      public Builder clearOptionalGroup() {  copyOnWrite();
-        instance.clearOptionalGroup();
-        return this;
-      }
-
-      @java.lang.Override
-
-      public int getStringStringMapCount() {
-        return instance.getStringStringMapMap().size();
-      }
-      /**
-       * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-       */
-      @java.lang.Override
-
-      public boolean containsStringStringMap(
-          java.lang.String key) {
-        key.getClass();
-        return instance.getStringStringMapMap().containsKey(key);
-      }
-
-      public Builder clearStringStringMap() {
-        copyOnWrite();
-        instance.getMutableStringStringMapMap().clear();
-        return this;
-      }
-      /**
-       * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-       */
-
-      public Builder removeStringStringMap(
-          java.lang.String key) {
-        key.getClass();
-        copyOnWrite();
-        instance.getMutableStringStringMapMap().remove(key);
-        return this;
-      }
-      /**
-       * Use {@link #getStringStringMapMap()} instead.
-       */
-      @java.lang.Override
-      @java.lang.Deprecated
-      public java.util.Map<java.lang.String, java.lang.String> getStringStringMap() {
-        return getStringStringMapMap();
-      }
-      /**
-       * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-       */
-      @java.lang.Override
-      public java.util.Map<java.lang.String, java.lang.String> getStringStringMapMap() {
-        return java.util.Collections.unmodifiableMap(
-            instance.getStringStringMapMap());
-      }
-      /**
-       * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-       */
-      @java.lang.Override
-
-      public java.lang.String getStringStringMapOrDefault(
-          java.lang.String key,
-          java.lang.String defaultValue) {
-        key.getClass();
-        java.util.Map<java.lang.String, java.lang.String> map =
-            instance.getStringStringMapMap();
-        return map.containsKey(key) ? map.get(key) : defaultValue;
-      }
-      /**
-       * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-       */
-      @java.lang.Override
-
-      public java.lang.String getStringStringMapOrThrow(
-          java.lang.String key) {
-        key.getClass();
-        java.util.Map<java.lang.String, java.lang.String> map =
-            instance.getStringStringMapMap();
-        if (!map.containsKey(key)) {
-          throw new java.lang.IllegalArgumentException();
-        }
-        return map.get(key);
-      }
-      /**
-       * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-       */
-      public Builder putStringStringMap(
-          java.lang.String key,
-          java.lang.String value) {
-        key.getClass();
-        value.getClass();
-        copyOnWrite();
-        instance.getMutableStringStringMapMap().put(key, value);
-        return this;
-      }
-      /**
-       * <code>map&lt;string, string&gt; string_string_map = 536870010;</code>
-       */
-      public Builder putAllStringStringMap(
-          java.util.Map<java.lang.String, java.lang.String> values) {
-        copyOnWrite();
-        instance.getMutableStringStringMapMap().putAll(values);
-        return this;
-      }
-
-      /**
-       * <code>uint32 oneof_uint32 = 536870011;</code>
-       * @return Whether the oneofUint32 field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofUint32() {
-        return instance.hasOneofUint32();
-      }
-      /**
-       * <code>uint32 oneof_uint32 = 536870011;</code>
-       * @return The oneofUint32.
-       */
-      @java.lang.Override
-      public int getOneofUint32() {
-        return instance.getOneofUint32();
-      }
-      /**
-       * <code>uint32 oneof_uint32 = 536870011;</code>
-       * @param value The oneofUint32 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofUint32(int value) {
-        copyOnWrite();
-        instance.setOneofUint32(value);
-        return this;
-      }
-      /**
-       * <code>uint32 oneof_uint32 = 536870011;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofUint32() {
-        copyOnWrite();
-        instance.clearOneofUint32();
-        return this;
-      }
-
-      /**
-       * <code>.protobuf_unittest.TestAllTypes oneof_test_all_types = 536870012;</code>
-       */
-      @java.lang.Override
-      public boolean hasOneofTestAllTypes() {
-        return instance.hasOneofTestAllTypes();
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypes oneof_test_all_types = 536870012;</code>
-       */
-      @java.lang.Override
-      public protobuf_unittest.UnittestProto.TestAllTypes getOneofTestAllTypes() {
-        return instance.getOneofTestAllTypes();
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypes oneof_test_all_types = 536870012;</code>
-       */
-      public Builder setOneofTestAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        copyOnWrite();
-        instance.setOneofTestAllTypes(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypes oneof_test_all_types = 536870012;</code>
-       */
-      public Builder setOneofTestAllTypes(
-          protobuf_unittest.UnittestProto.TestAllTypes.Builder builderForValue) {
-        copyOnWrite();
-        instance.setOneofTestAllTypes(builderForValue.build());
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypes oneof_test_all_types = 536870012;</code>
-       */
-      public Builder mergeOneofTestAllTypes(protobuf_unittest.UnittestProto.TestAllTypes value) {
-        copyOnWrite();
-        instance.mergeOneofTestAllTypes(value);
-        return this;
-      }
-      /**
-       * <code>.protobuf_unittest.TestAllTypes oneof_test_all_types = 536870012;</code>
-       */
-      public Builder clearOneofTestAllTypes() {
-        copyOnWrite();
-        instance.clearOneofTestAllTypes();
-        return this;
-      }
-
-      /**
-       * <code>string oneof_string = 536870013;</code>
-       * @return Whether the oneofString field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofString() {
-        return instance.hasOneofString();
-      }
-      /**
-       * <code>string oneof_string = 536870013;</code>
-       * @return The oneofString.
-       */
-      @java.lang.Override
-      public java.lang.String getOneofString() {
-        return instance.getOneofString();
-      }
-      /**
-       * <code>string oneof_string = 536870013;</code>
-       * @return The bytes for oneofString.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString
-          getOneofStringBytes() {
-        return instance.getOneofStringBytes();
-      }
-      /**
-       * <code>string oneof_string = 536870013;</code>
-       * @param value The oneofString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofString(
-          java.lang.String value) {
-        copyOnWrite();
-        instance.setOneofString(value);
-        return this;
-      }
-      /**
-       * <code>string oneof_string = 536870013;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofString() {
-        copyOnWrite();
-        instance.clearOneofString();
-        return this;
-      }
-      /**
-       * <code>string oneof_string = 536870013;</code>
-       * @param value The bytes for oneofString to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofStringBytes(
-          com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOneofStringBytes(value);
-        return this;
-      }
-
-      /**
-       * <code>bytes oneof_bytes = 536870014;</code>
-       * @return Whether the oneofBytes field is set.
-       */
-      @java.lang.Override
-      public boolean hasOneofBytes() {
-        return instance.hasOneofBytes();
-      }
-      /**
-       * <code>bytes oneof_bytes = 536870014;</code>
-       * @return The oneofBytes.
-       */
-      @java.lang.Override
-      public com.google.protobuf.ByteString getOneofBytes() {
-        return instance.getOneofBytes();
-      }
-      /**
-       * <code>bytes oneof_bytes = 536870014;</code>
-       * @param value The oneofBytes to set.
-       * @return This builder for chaining.
-       */
-      public Builder setOneofBytes(com.google.protobuf.ByteString value) {
-        copyOnWrite();
-        instance.setOneofBytes(value);
-        return this;
-      }
-      /**
-       * <code>bytes oneof_bytes = 536870014;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearOneofBytes() {
-        copyOnWrite();
-        instance.clearOneofBytes();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestHugeFieldNumbers)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestHugeFieldNumbers();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "oneofField_",
-              "oneofFieldCase_",
-              "bitField0_",
-              "optionalInt32_",
-              "fixed32_",
-              "repeatedInt32_",
-              "packedInt32_",
-              "optionalEnum_",
-              protobuf_unittest.UnittestProto.ForeignEnum.internalGetVerifier(),
-              "optionalString_",
-              "optionalBytes_",
-              "optionalMessage_",
-              "optionalGroup_",
-              "stringStringMap_",
-              StringStringMapDefaultEntryHolder.defaultEntry,
-              protobuf_unittest.UnittestProto.TestAllTypes.class,
-            };
-            java.lang.String info =
-                "\u0001\u000e\u0001\u0001\ufc70\uffff\u0007\ufc7e\uffff\u0007\u000e\u0001\u0002\u0000" +
-                "\ufc70\uffff\u0007\u1004\u0000\ufc71\uffff\u0007\u1004\u0001\ufc72\uffff\u0007\u0016" +
-                "\ufc73\uffff\u0007\'\ufc74\uffff\u0007\u100c\u0002\ufc75\uffff\u0007\u1008\u0003" +
-                "\ufc76\uffff\u0007\u100a\u0004\ufc77\uffff\u0007\u1009\u0005\ufc78\uffff\u0007\u1011" +
-                "\u0006\ufc7a\uffff\u00072\ufc7b\uffff\u0007\u103e\u0000\ufc7c\uffff\u0007\u103c\u0000" +
-                "\ufc7d\uffff\u0007\u103b\u0000\ufc7e\uffff\u0007\u103d\u0000";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestHugeFieldNumbers> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestHugeFieldNumbers.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestHugeFieldNumbers>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestHugeFieldNumbers)
-    private static final protobuf_unittest.UnittestProto.TestHugeFieldNumbers DEFAULT_INSTANCE;
-    static {
-      TestHugeFieldNumbers defaultInstance = new TestHugeFieldNumbers();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestHugeFieldNumbers.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestHugeFieldNumbers getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestHugeFieldNumbers> PARSER;
-
-    public static com.google.protobuf.Parser<TestHugeFieldNumbers> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestExtensionInsideTableOrBuilder extends 
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestExtensionInsideTable)
-       com.google.protobuf.GeneratedMessageLite.
-            ExtendableMessageOrBuilder<
-                TestExtensionInsideTable, TestExtensionInsideTable.Builder> {
-
-    /**
-     * <code>optional int32 field1 = 1;</code>
-     * @return Whether the field1 field is set.
-     */
-    boolean hasField1();
-    /**
-     * <code>optional int32 field1 = 1;</code>
-     * @return The field1.
-     */
-    int getField1();
-
-    /**
-     * <code>optional int32 field2 = 2;</code>
-     * @return Whether the field2 field is set.
-     */
-    boolean hasField2();
-    /**
-     * <code>optional int32 field2 = 2;</code>
-     * @return The field2.
-     */
-    int getField2();
-
-    /**
-     * <code>optional int32 field3 = 3;</code>
-     * @return Whether the field3 field is set.
-     */
-    boolean hasField3();
-    /**
-     * <code>optional int32 field3 = 3;</code>
-     * @return The field3.
-     */
-    int getField3();
-
-    /**
-     * <code>optional int32 field4 = 4;</code>
-     * @return Whether the field4 field is set.
-     */
-    boolean hasField4();
-    /**
-     * <code>optional int32 field4 = 4;</code>
-     * @return The field4.
-     */
-    int getField4();
-
-    /**
-     * <code>optional int32 field6 = 6;</code>
-     * @return Whether the field6 field is set.
-     */
-    boolean hasField6();
-    /**
-     * <code>optional int32 field6 = 6;</code>
-     * @return The field6.
-     */
-    int getField6();
-
-    /**
-     * <code>optional int32 field7 = 7;</code>
-     * @return Whether the field7 field is set.
-     */
-    boolean hasField7();
-    /**
-     * <code>optional int32 field7 = 7;</code>
-     * @return The field7.
-     */
-    int getField7();
-
-    /**
-     * <code>optional int32 field8 = 8;</code>
-     * @return Whether the field8 field is set.
-     */
-    boolean hasField8();
-    /**
-     * <code>optional int32 field8 = 8;</code>
-     * @return The field8.
-     */
-    int getField8();
-
-    /**
-     * <code>optional int32 field9 = 9;</code>
-     * @return Whether the field9 field is set.
-     */
-    boolean hasField9();
-    /**
-     * <code>optional int32 field9 = 9;</code>
-     * @return The field9.
-     */
-    int getField9();
-
-    /**
-     * <code>optional int32 field10 = 10;</code>
-     * @return Whether the field10 field is set.
-     */
-    boolean hasField10();
-    /**
-     * <code>optional int32 field10 = 10;</code>
-     * @return The field10.
-     */
-    int getField10();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestExtensionInsideTable}
-   */
-  public  static final class TestExtensionInsideTable extends
-      com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
-        TestExtensionInsideTable, TestExtensionInsideTable.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestExtensionInsideTable)
-      TestExtensionInsideTableOrBuilder {
-    private TestExtensionInsideTable() {
-    }
-    private int bitField0_;
-    public static final int FIELD1_FIELD_NUMBER = 1;
-    private int field1_;
-    /**
-     * <code>optional int32 field1 = 1;</code>
-     * @return Whether the field1 field is set.
-     */
-    @java.lang.Override
-    public boolean hasField1() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 field1 = 1;</code>
-     * @return The field1.
-     */
-    @java.lang.Override
-    public int getField1() {
-      return field1_;
-    }
-    /**
-     * <code>optional int32 field1 = 1;</code>
-     * @param value The field1 to set.
-     */
-    private void setField1(int value) {
-      bitField0_ |= 0x00000001;
-      field1_ = value;
-    }
-    /**
-     * <code>optional int32 field1 = 1;</code>
-     */
-    private void clearField1() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      field1_ = 0;
-    }
-
-    public static final int FIELD2_FIELD_NUMBER = 2;
-    private int field2_;
-    /**
-     * <code>optional int32 field2 = 2;</code>
-     * @return Whether the field2 field is set.
-     */
-    @java.lang.Override
-    public boolean hasField2() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional int32 field2 = 2;</code>
-     * @return The field2.
-     */
-    @java.lang.Override
-    public int getField2() {
-      return field2_;
-    }
-    /**
-     * <code>optional int32 field2 = 2;</code>
-     * @param value The field2 to set.
-     */
-    private void setField2(int value) {
-      bitField0_ |= 0x00000002;
-      field2_ = value;
-    }
-    /**
-     * <code>optional int32 field2 = 2;</code>
-     */
-    private void clearField2() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      field2_ = 0;
-    }
-
-    public static final int FIELD3_FIELD_NUMBER = 3;
-    private int field3_;
-    /**
-     * <code>optional int32 field3 = 3;</code>
-     * @return Whether the field3 field is set.
-     */
-    @java.lang.Override
-    public boolean hasField3() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional int32 field3 = 3;</code>
-     * @return The field3.
-     */
-    @java.lang.Override
-    public int getField3() {
-      return field3_;
-    }
-    /**
-     * <code>optional int32 field3 = 3;</code>
-     * @param value The field3 to set.
-     */
-    private void setField3(int value) {
-      bitField0_ |= 0x00000004;
-      field3_ = value;
-    }
-    /**
-     * <code>optional int32 field3 = 3;</code>
-     */
-    private void clearField3() {
-      bitField0_ = (bitField0_ & ~0x00000004);
-      field3_ = 0;
-    }
-
-    public static final int FIELD4_FIELD_NUMBER = 4;
-    private int field4_;
-    /**
-     * <code>optional int32 field4 = 4;</code>
-     * @return Whether the field4 field is set.
-     */
-    @java.lang.Override
-    public boolean hasField4() {
-      return ((bitField0_ & 0x00000008) != 0);
-    }
-    /**
-     * <code>optional int32 field4 = 4;</code>
-     * @return The field4.
-     */
-    @java.lang.Override
-    public int getField4() {
-      return field4_;
-    }
-    /**
-     * <code>optional int32 field4 = 4;</code>
-     * @param value The field4 to set.
-     */
-    private void setField4(int value) {
-      bitField0_ |= 0x00000008;
-      field4_ = value;
-    }
-    /**
-     * <code>optional int32 field4 = 4;</code>
-     */
-    private void clearField4() {
-      bitField0_ = (bitField0_ & ~0x00000008);
-      field4_ = 0;
-    }
-
-    public static final int FIELD6_FIELD_NUMBER = 6;
-    private int field6_;
-    /**
-     * <code>optional int32 field6 = 6;</code>
-     * @return Whether the field6 field is set.
-     */
-    @java.lang.Override
-    public boolean hasField6() {
-      return ((bitField0_ & 0x00000010) != 0);
-    }
-    /**
-     * <code>optional int32 field6 = 6;</code>
-     * @return The field6.
-     */
-    @java.lang.Override
-    public int getField6() {
-      return field6_;
-    }
-    /**
-     * <code>optional int32 field6 = 6;</code>
-     * @param value The field6 to set.
-     */
-    private void setField6(int value) {
-      bitField0_ |= 0x00000010;
-      field6_ = value;
-    }
-    /**
-     * <code>optional int32 field6 = 6;</code>
-     */
-    private void clearField6() {
-      bitField0_ = (bitField0_ & ~0x00000010);
-      field6_ = 0;
-    }
-
-    public static final int FIELD7_FIELD_NUMBER = 7;
-    private int field7_;
-    /**
-     * <code>optional int32 field7 = 7;</code>
-     * @return Whether the field7 field is set.
-     */
-    @java.lang.Override
-    public boolean hasField7() {
-      return ((bitField0_ & 0x00000020) != 0);
-    }
-    /**
-     * <code>optional int32 field7 = 7;</code>
-     * @return The field7.
-     */
-    @java.lang.Override
-    public int getField7() {
-      return field7_;
-    }
-    /**
-     * <code>optional int32 field7 = 7;</code>
-     * @param value The field7 to set.
-     */
-    private void setField7(int value) {
-      bitField0_ |= 0x00000020;
-      field7_ = value;
-    }
-    /**
-     * <code>optional int32 field7 = 7;</code>
-     */
-    private void clearField7() {
-      bitField0_ = (bitField0_ & ~0x00000020);
-      field7_ = 0;
-    }
-
-    public static final int FIELD8_FIELD_NUMBER = 8;
-    private int field8_;
-    /**
-     * <code>optional int32 field8 = 8;</code>
-     * @return Whether the field8 field is set.
-     */
-    @java.lang.Override
-    public boolean hasField8() {
-      return ((bitField0_ & 0x00000040) != 0);
-    }
-    /**
-     * <code>optional int32 field8 = 8;</code>
-     * @return The field8.
-     */
-    @java.lang.Override
-    public int getField8() {
-      return field8_;
-    }
-    /**
-     * <code>optional int32 field8 = 8;</code>
-     * @param value The field8 to set.
-     */
-    private void setField8(int value) {
-      bitField0_ |= 0x00000040;
-      field8_ = value;
-    }
-    /**
-     * <code>optional int32 field8 = 8;</code>
-     */
-    private void clearField8() {
-      bitField0_ = (bitField0_ & ~0x00000040);
-      field8_ = 0;
-    }
-
-    public static final int FIELD9_FIELD_NUMBER = 9;
-    private int field9_;
-    /**
-     * <code>optional int32 field9 = 9;</code>
-     * @return Whether the field9 field is set.
-     */
-    @java.lang.Override
-    public boolean hasField9() {
-      return ((bitField0_ & 0x00000080) != 0);
-    }
-    /**
-     * <code>optional int32 field9 = 9;</code>
-     * @return The field9.
-     */
-    @java.lang.Override
-    public int getField9() {
-      return field9_;
-    }
-    /**
-     * <code>optional int32 field9 = 9;</code>
-     * @param value The field9 to set.
-     */
-    private void setField9(int value) {
-      bitField0_ |= 0x00000080;
-      field9_ = value;
-    }
-    /**
-     * <code>optional int32 field9 = 9;</code>
-     */
-    private void clearField9() {
-      bitField0_ = (bitField0_ & ~0x00000080);
-      field9_ = 0;
-    }
-
-    public static final int FIELD10_FIELD_NUMBER = 10;
-    private int field10_;
-    /**
-     * <code>optional int32 field10 = 10;</code>
-     * @return Whether the field10 field is set.
-     */
-    @java.lang.Override
-    public boolean hasField10() {
-      return ((bitField0_ & 0x00000100) != 0);
-    }
-    /**
-     * <code>optional int32 field10 = 10;</code>
-     * @return The field10.
-     */
-    @java.lang.Override
-    public int getField10() {
-      return field10_;
-    }
-    /**
-     * <code>optional int32 field10 = 10;</code>
-     * @param value The field10 to set.
-     */
-    private void setField10(int value) {
-      bitField0_ |= 0x00000100;
-      field10_ = value;
-    }
-    /**
-     * <code>optional int32 field10 = 10;</code>
-     */
-    private void clearField10() {
-      bitField0_ = (bitField0_ & ~0x00000100);
-      field10_ = 0;
-    }
-
-    public static protobuf_unittest.UnittestProto.TestExtensionInsideTable parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionInsideTable parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionInsideTable parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionInsideTable parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionInsideTable parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionInsideTable parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionInsideTable parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionInsideTable parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionInsideTable parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionInsideTable parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionInsideTable parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionInsideTable parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestExtensionInsideTable prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestExtensionInsideTable}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
-          protobuf_unittest.UnittestProto.TestExtensionInsideTable, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestExtensionInsideTable)
-        protobuf_unittest.UnittestProto.TestExtensionInsideTableOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestExtensionInsideTable.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int32 field1 = 1;</code>
-       * @return Whether the field1 field is set.
-       */
-      @java.lang.Override
-      public boolean hasField1() {
-        return instance.hasField1();
-      }
-      /**
-       * <code>optional int32 field1 = 1;</code>
-       * @return The field1.
-       */
-      @java.lang.Override
-      public int getField1() {
-        return instance.getField1();
-      }
-      /**
-       * <code>optional int32 field1 = 1;</code>
-       * @param value The field1 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setField1(int value) {
-        copyOnWrite();
-        instance.setField1(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 field1 = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearField1() {
-        copyOnWrite();
-        instance.clearField1();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 field2 = 2;</code>
-       * @return Whether the field2 field is set.
-       */
-      @java.lang.Override
-      public boolean hasField2() {
-        return instance.hasField2();
-      }
-      /**
-       * <code>optional int32 field2 = 2;</code>
-       * @return The field2.
-       */
-      @java.lang.Override
-      public int getField2() {
-        return instance.getField2();
-      }
-      /**
-       * <code>optional int32 field2 = 2;</code>
-       * @param value The field2 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setField2(int value) {
-        copyOnWrite();
-        instance.setField2(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 field2 = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearField2() {
-        copyOnWrite();
-        instance.clearField2();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 field3 = 3;</code>
-       * @return Whether the field3 field is set.
-       */
-      @java.lang.Override
-      public boolean hasField3() {
-        return instance.hasField3();
-      }
-      /**
-       * <code>optional int32 field3 = 3;</code>
-       * @return The field3.
-       */
-      @java.lang.Override
-      public int getField3() {
-        return instance.getField3();
-      }
-      /**
-       * <code>optional int32 field3 = 3;</code>
-       * @param value The field3 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setField3(int value) {
-        copyOnWrite();
-        instance.setField3(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 field3 = 3;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearField3() {
-        copyOnWrite();
-        instance.clearField3();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 field4 = 4;</code>
-       * @return Whether the field4 field is set.
-       */
-      @java.lang.Override
-      public boolean hasField4() {
-        return instance.hasField4();
-      }
-      /**
-       * <code>optional int32 field4 = 4;</code>
-       * @return The field4.
-       */
-      @java.lang.Override
-      public int getField4() {
-        return instance.getField4();
-      }
-      /**
-       * <code>optional int32 field4 = 4;</code>
-       * @param value The field4 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setField4(int value) {
-        copyOnWrite();
-        instance.setField4(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 field4 = 4;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearField4() {
-        copyOnWrite();
-        instance.clearField4();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 field6 = 6;</code>
-       * @return Whether the field6 field is set.
-       */
-      @java.lang.Override
-      public boolean hasField6() {
-        return instance.hasField6();
-      }
-      /**
-       * <code>optional int32 field6 = 6;</code>
-       * @return The field6.
-       */
-      @java.lang.Override
-      public int getField6() {
-        return instance.getField6();
-      }
-      /**
-       * <code>optional int32 field6 = 6;</code>
-       * @param value The field6 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setField6(int value) {
-        copyOnWrite();
-        instance.setField6(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 field6 = 6;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearField6() {
-        copyOnWrite();
-        instance.clearField6();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 field7 = 7;</code>
-       * @return Whether the field7 field is set.
-       */
-      @java.lang.Override
-      public boolean hasField7() {
-        return instance.hasField7();
-      }
-      /**
-       * <code>optional int32 field7 = 7;</code>
-       * @return The field7.
-       */
-      @java.lang.Override
-      public int getField7() {
-        return instance.getField7();
-      }
-      /**
-       * <code>optional int32 field7 = 7;</code>
-       * @param value The field7 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setField7(int value) {
-        copyOnWrite();
-        instance.setField7(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 field7 = 7;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearField7() {
-        copyOnWrite();
-        instance.clearField7();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 field8 = 8;</code>
-       * @return Whether the field8 field is set.
-       */
-      @java.lang.Override
-      public boolean hasField8() {
-        return instance.hasField8();
-      }
-      /**
-       * <code>optional int32 field8 = 8;</code>
-       * @return The field8.
-       */
-      @java.lang.Override
-      public int getField8() {
-        return instance.getField8();
-      }
-      /**
-       * <code>optional int32 field8 = 8;</code>
-       * @param value The field8 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setField8(int value) {
-        copyOnWrite();
-        instance.setField8(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 field8 = 8;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearField8() {
-        copyOnWrite();
-        instance.clearField8();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 field9 = 9;</code>
-       * @return Whether the field9 field is set.
-       */
-      @java.lang.Override
-      public boolean hasField9() {
-        return instance.hasField9();
-      }
-      /**
-       * <code>optional int32 field9 = 9;</code>
-       * @return The field9.
-       */
-      @java.lang.Override
-      public int getField9() {
-        return instance.getField9();
-      }
-      /**
-       * <code>optional int32 field9 = 9;</code>
-       * @param value The field9 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setField9(int value) {
-        copyOnWrite();
-        instance.setField9(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 field9 = 9;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearField9() {
-        copyOnWrite();
-        instance.clearField9();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 field10 = 10;</code>
-       * @return Whether the field10 field is set.
-       */
-      @java.lang.Override
-      public boolean hasField10() {
-        return instance.hasField10();
-      }
-      /**
-       * <code>optional int32 field10 = 10;</code>
-       * @return The field10.
-       */
-      @java.lang.Override
-      public int getField10() {
-        return instance.getField10();
-      }
-      /**
-       * <code>optional int32 field10 = 10;</code>
-       * @param value The field10 to set.
-       * @return This builder for chaining.
-       */
-      public Builder setField10(int value) {
-        copyOnWrite();
-        instance.setField10(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 field10 = 10;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearField10() {
-        copyOnWrite();
-        instance.clearField10();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestExtensionInsideTable)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestExtensionInsideTable();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "field1_",
-              "field2_",
-              "field3_",
-              "field4_",
-              "field6_",
-              "field7_",
-              "field8_",
-              "field9_",
-              "field10_",
-            };
-            java.lang.String info =
-                "\u0001\t\u0000\u0001\u0001\n\t\u0000\u0000\u0000\u0001\u1004\u0000\u0002\u1004\u0001" +
-                "\u0003\u1004\u0002\u0004\u1004\u0003\u0006\u1004\u0004\u0007\u1004\u0005\b\u1004" +
-                "\u0006\t\u1004\u0007\n\u1004\b";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestExtensionInsideTable> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestExtensionInsideTable.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestExtensionInsideTable>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestExtensionInsideTable)
-    private static final protobuf_unittest.UnittestProto.TestExtensionInsideTable DEFAULT_INSTANCE;
-    static {
-      TestExtensionInsideTable defaultInstance = new TestExtensionInsideTable();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestExtensionInsideTable.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestExtensionInsideTable getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestExtensionInsideTable> PARSER;
-
-    public static com.google.protobuf.Parser<TestExtensionInsideTable> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-  }
-
-  public interface TestExtensionRangeSerializeOrBuilder extends 
-      // @@protoc_insertion_point(interface_extends:protobuf_unittest.TestExtensionRangeSerialize)
-       com.google.protobuf.GeneratedMessageLite.
-            ExtendableMessageOrBuilder<
-                TestExtensionRangeSerialize, TestExtensionRangeSerialize.Builder> {
-
-    /**
-     * <code>optional int32 foo_one = 1;</code>
-     * @return Whether the fooOne field is set.
-     */
-    boolean hasFooOne();
-    /**
-     * <code>optional int32 foo_one = 1;</code>
-     * @return The fooOne.
-     */
-    int getFooOne();
-
-    /**
-     * <code>optional int32 foo_two = 6;</code>
-     * @return Whether the fooTwo field is set.
-     */
-    boolean hasFooTwo();
-    /**
-     * <code>optional int32 foo_two = 6;</code>
-     * @return The fooTwo.
-     */
-    int getFooTwo();
-
-    /**
-     * <code>optional int32 foo_three = 7;</code>
-     * @return Whether the fooThree field is set.
-     */
-    boolean hasFooThree();
-    /**
-     * <code>optional int32 foo_three = 7;</code>
-     * @return The fooThree.
-     */
-    int getFooThree();
-
-    /**
-     * <code>optional int32 foo_four = 13;</code>
-     * @return Whether the fooFour field is set.
-     */
-    boolean hasFooFour();
-    /**
-     * <code>optional int32 foo_four = 13;</code>
-     * @return The fooFour.
-     */
-    int getFooFour();
-  }
-  /**
-   * Protobuf type {@code protobuf_unittest.TestExtensionRangeSerialize}
-   */
-  public  static final class TestExtensionRangeSerialize extends
-      com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
-        TestExtensionRangeSerialize, TestExtensionRangeSerialize.Builder> implements
-      // @@protoc_insertion_point(message_implements:protobuf_unittest.TestExtensionRangeSerialize)
-      TestExtensionRangeSerializeOrBuilder {
-    private TestExtensionRangeSerialize() {
-    }
-    private int bitField0_;
-    public static final int FOO_ONE_FIELD_NUMBER = 1;
-    private int fooOne_;
-    /**
-     * <code>optional int32 foo_one = 1;</code>
-     * @return Whether the fooOne field is set.
-     */
-    @java.lang.Override
-    public boolean hasFooOne() {
-      return ((bitField0_ & 0x00000001) != 0);
-    }
-    /**
-     * <code>optional int32 foo_one = 1;</code>
-     * @return The fooOne.
-     */
-    @java.lang.Override
-    public int getFooOne() {
-      return fooOne_;
-    }
-    /**
-     * <code>optional int32 foo_one = 1;</code>
-     * @param value The fooOne to set.
-     */
-    private void setFooOne(int value) {
-      bitField0_ |= 0x00000001;
-      fooOne_ = value;
-    }
-    /**
-     * <code>optional int32 foo_one = 1;</code>
-     */
-    private void clearFooOne() {
-      bitField0_ = (bitField0_ & ~0x00000001);
-      fooOne_ = 0;
-    }
-
-    public static final int FOO_TWO_FIELD_NUMBER = 6;
-    private int fooTwo_;
-    /**
-     * <code>optional int32 foo_two = 6;</code>
-     * @return Whether the fooTwo field is set.
-     */
-    @java.lang.Override
-    public boolean hasFooTwo() {
-      return ((bitField0_ & 0x00000002) != 0);
-    }
-    /**
-     * <code>optional int32 foo_two = 6;</code>
-     * @return The fooTwo.
-     */
-    @java.lang.Override
-    public int getFooTwo() {
-      return fooTwo_;
-    }
-    /**
-     * <code>optional int32 foo_two = 6;</code>
-     * @param value The fooTwo to set.
-     */
-    private void setFooTwo(int value) {
-      bitField0_ |= 0x00000002;
-      fooTwo_ = value;
-    }
-    /**
-     * <code>optional int32 foo_two = 6;</code>
-     */
-    private void clearFooTwo() {
-      bitField0_ = (bitField0_ & ~0x00000002);
-      fooTwo_ = 0;
-    }
-
-    public static final int FOO_THREE_FIELD_NUMBER = 7;
-    private int fooThree_;
-    /**
-     * <code>optional int32 foo_three = 7;</code>
-     * @return Whether the fooThree field is set.
-     */
-    @java.lang.Override
-    public boolean hasFooThree() {
-      return ((bitField0_ & 0x00000004) != 0);
-    }
-    /**
-     * <code>optional int32 foo_three = 7;</code>
-     * @return The fooThree.
-     */
-    @java.lang.Override
-    public int getFooThree() {
-      return fooThree_;
-    }
-    /**
-     * <code>optional int32 foo_three = 7;</code>
-     * @param value The fooThree to set.
-     */
-    private void setFooThree(int value) {
-      bitField0_ |= 0x00000004;
-      fooThree_ = value;
-    }
-    /**
-     * <code>optional int32 foo_three = 7;</code>
-     */
-    private void clearFooThree() {
-      bitField0_ = (bitField0_ & ~0x00000004);
-      fooThree_ = 0;
-    }
-
-    public static final int FOO_FOUR_FIELD_NUMBER = 13;
-    private int fooFour_;
-    /**
-     * <code>optional int32 foo_four = 13;</code>
-     * @return Whether the fooFour field is set.
-     */
-    @java.lang.Override
-    public boolean hasFooFour() {
-      return ((bitField0_ & 0x00000008) != 0);
-    }
-    /**
-     * <code>optional int32 foo_four = 13;</code>
-     * @return The fooFour.
-     */
-    @java.lang.Override
-    public int getFooFour() {
-      return fooFour_;
-    }
-    /**
-     * <code>optional int32 foo_four = 13;</code>
-     * @param value The fooFour to set.
-     */
-    private void setFooFour(int value) {
-      bitField0_ |= 0x00000008;
-      fooFour_ = value;
-    }
-    /**
-     * <code>optional int32 foo_four = 13;</code>
-     */
-    private void clearFooFour() {
-      bitField0_ = (bitField0_ & ~0x00000008);
-      fooFour_ = 0;
-    }
-
-    public static protobuf_unittest.UnittestProto.TestExtensionRangeSerialize parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionRangeSerialize parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionRangeSerialize parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionRangeSerialize parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionRangeSerialize parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionRangeSerialize parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, data, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionRangeSerialize parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionRangeSerialize parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionRangeSerialize parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionRangeSerialize parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionRangeSerialize parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input);
-    }
-    public static protobuf_unittest.UnittestProto.TestExtensionRangeSerialize parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageLite.parseFrom(
-          DEFAULT_INSTANCE, input, extensionRegistry);
-    }
-
-    public static Builder newBuilder() {
-      return (Builder) DEFAULT_INSTANCE.createBuilder();
-    }
-    public static Builder newBuilder(protobuf_unittest.UnittestProto.TestExtensionRangeSerialize prototype) {
-      return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);
-    }
-
-    /**
-     * Protobuf type {@code protobuf_unittest.TestExtensionRangeSerialize}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
-          protobuf_unittest.UnittestProto.TestExtensionRangeSerialize, Builder> implements
-        // @@protoc_insertion_point(builder_implements:protobuf_unittest.TestExtensionRangeSerialize)
-        protobuf_unittest.UnittestProto.TestExtensionRangeSerializeOrBuilder {
-      // Construct using protobuf_unittest.UnittestProto.TestExtensionRangeSerialize.newBuilder()
-      private Builder() {
-        super(DEFAULT_INSTANCE);
-      }
-
-
-      /**
-       * <code>optional int32 foo_one = 1;</code>
-       * @return Whether the fooOne field is set.
-       */
-      @java.lang.Override
-      public boolean hasFooOne() {
-        return instance.hasFooOne();
-      }
-      /**
-       * <code>optional int32 foo_one = 1;</code>
-       * @return The fooOne.
-       */
-      @java.lang.Override
-      public int getFooOne() {
-        return instance.getFooOne();
-      }
-      /**
-       * <code>optional int32 foo_one = 1;</code>
-       * @param value The fooOne to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooOne(int value) {
-        copyOnWrite();
-        instance.setFooOne(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 foo_one = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFooOne() {
-        copyOnWrite();
-        instance.clearFooOne();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 foo_two = 6;</code>
-       * @return Whether the fooTwo field is set.
-       */
-      @java.lang.Override
-      public boolean hasFooTwo() {
-        return instance.hasFooTwo();
-      }
-      /**
-       * <code>optional int32 foo_two = 6;</code>
-       * @return The fooTwo.
-       */
-      @java.lang.Override
-      public int getFooTwo() {
-        return instance.getFooTwo();
-      }
-      /**
-       * <code>optional int32 foo_two = 6;</code>
-       * @param value The fooTwo to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooTwo(int value) {
-        copyOnWrite();
-        instance.setFooTwo(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 foo_two = 6;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFooTwo() {
-        copyOnWrite();
-        instance.clearFooTwo();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 foo_three = 7;</code>
-       * @return Whether the fooThree field is set.
-       */
-      @java.lang.Override
-      public boolean hasFooThree() {
-        return instance.hasFooThree();
-      }
-      /**
-       * <code>optional int32 foo_three = 7;</code>
-       * @return The fooThree.
-       */
-      @java.lang.Override
-      public int getFooThree() {
-        return instance.getFooThree();
-      }
-      /**
-       * <code>optional int32 foo_three = 7;</code>
-       * @param value The fooThree to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooThree(int value) {
-        copyOnWrite();
-        instance.setFooThree(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 foo_three = 7;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFooThree() {
-        copyOnWrite();
-        instance.clearFooThree();
-        return this;
-      }
-
-      /**
-       * <code>optional int32 foo_four = 13;</code>
-       * @return Whether the fooFour field is set.
-       */
-      @java.lang.Override
-      public boolean hasFooFour() {
-        return instance.hasFooFour();
-      }
-      /**
-       * <code>optional int32 foo_four = 13;</code>
-       * @return The fooFour.
-       */
-      @java.lang.Override
-      public int getFooFour() {
-        return instance.getFooFour();
-      }
-      /**
-       * <code>optional int32 foo_four = 13;</code>
-       * @param value The fooFour to set.
-       * @return This builder for chaining.
-       */
-      public Builder setFooFour(int value) {
-        copyOnWrite();
-        instance.setFooFour(value);
-        return this;
-      }
-      /**
-       * <code>optional int32 foo_four = 13;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearFooFour() {
-        copyOnWrite();
-        instance.clearFooFour();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:protobuf_unittest.TestExtensionRangeSerialize)
-    }
-    private byte memoizedIsInitialized = 2;
-    @java.lang.Override
-    @java.lang.SuppressWarnings({"unchecked", "fallthrough"})
-    protected final java.lang.Object dynamicMethod(
-        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
-        java.lang.Object arg0, java.lang.Object arg1) {
-      switch (method) {
-        case NEW_MUTABLE_INSTANCE: {
-          return new protobuf_unittest.UnittestProto.TestExtensionRangeSerialize();
-        }
-        case NEW_BUILDER: {
-          return new Builder();
-        }
-        case BUILD_MESSAGE_INFO: {
-            java.lang.Object[] objects = new java.lang.Object[] {
-              "bitField0_",
-              "fooOne_",
-              "fooTwo_",
-              "fooThree_",
-              "fooFour_",
-            };
-            java.lang.String info =
-                "\u0001\u0004\u0000\u0001\u0001\r\u0004\u0000\u0000\u0000\u0001\u1004\u0000\u0006" +
-                "\u1004\u0001\u0007\u1004\u0002\r\u1004\u0003";
-            return newMessageInfo(DEFAULT_INSTANCE, info, objects);
-        }
-        // fall through
-        case GET_DEFAULT_INSTANCE: {
-          return DEFAULT_INSTANCE;
-        }
-        case GET_PARSER: {
-          com.google.protobuf.Parser<protobuf_unittest.UnittestProto.TestExtensionRangeSerialize> parser = PARSER;
-          if (parser == null) {
-            synchronized (protobuf_unittest.UnittestProto.TestExtensionRangeSerialize.class) {
-              parser = PARSER;
-              if (parser == null) {
-                parser =
-                    new DefaultInstanceBasedParser<protobuf_unittest.UnittestProto.TestExtensionRangeSerialize>(
-                        DEFAULT_INSTANCE);
-                PARSER = parser;
-              }
-            }
-          }
-          return parser;
-      }
-      case GET_MEMOIZED_IS_INITIALIZED: {
-        return memoizedIsInitialized;
-      }
-      case SET_MEMOIZED_IS_INITIALIZED: {
-        memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);
-        return null;
-      }
-      }
-      throw new UnsupportedOperationException();
-    }
-
-
-    // @@protoc_insertion_point(class_scope:protobuf_unittest.TestExtensionRangeSerialize)
-    private static final protobuf_unittest.UnittestProto.TestExtensionRangeSerialize DEFAULT_INSTANCE;
-    static {
-      TestExtensionRangeSerialize defaultInstance = new TestExtensionRangeSerialize();
-      // New instances are implicitly immutable so no need to make
-      // immutable.
-      DEFAULT_INSTANCE = defaultInstance;
-      com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(
-        TestExtensionRangeSerialize.class, defaultInstance);
-    }
-
-    public static protobuf_unittest.UnittestProto.TestExtensionRangeSerialize getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static volatile com.google.protobuf.Parser<TestExtensionRangeSerialize> PARSER;
-
-    public static com.google.protobuf.Parser<TestExtensionRangeSerialize> parser() {
-      return DEFAULT_INSTANCE.getParserForType();
-    }
-    public static final int BAR_ONE_FIELD_NUMBER = 2;
-    /**
-     * <code>extend .protobuf_unittest.TestExtensionRangeSerialize { ... }</code>
-     */
-    public static final
-      com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-        protobuf_unittest.UnittestProto.TestExtensionRangeSerialize,
-        java.lang.Integer> barOne = com.google.protobuf.GeneratedMessageLite
-            .newSingularGeneratedExtension(
-          protobuf_unittest.UnittestProto.TestExtensionRangeSerialize.getDefaultInstance(),
-          0,
-          null,
-          null,
-          2,
-          com.google.protobuf.WireFormat.FieldType.INT32,
-          java.lang.Integer.class);
-    public static final int BAR_TWO_FIELD_NUMBER = 4;
-    /**
-     * <code>extend .protobuf_unittest.TestExtensionRangeSerialize { ... }</code>
-     */
-    public static final
-      com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-        protobuf_unittest.UnittestProto.TestExtensionRangeSerialize,
-        java.lang.Integer> barTwo = com.google.protobuf.GeneratedMessageLite
-            .newSingularGeneratedExtension(
-          protobuf_unittest.UnittestProto.TestExtensionRangeSerialize.getDefaultInstance(),
-          0,
-          null,
-          null,
-          4,
-          com.google.protobuf.WireFormat.FieldType.INT32,
-          java.lang.Integer.class);
-    public static final int BAR_THREE_FIELD_NUMBER = 10;
-    /**
-     * <code>extend .protobuf_unittest.TestExtensionRangeSerialize { ... }</code>
-     */
-    public static final
-      com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-        protobuf_unittest.UnittestProto.TestExtensionRangeSerialize,
-        java.lang.Integer> barThree = com.google.protobuf.GeneratedMessageLite
-            .newSingularGeneratedExtension(
-          protobuf_unittest.UnittestProto.TestExtensionRangeSerialize.getDefaultInstance(),
-          0,
-          null,
-          null,
-          10,
-          com.google.protobuf.WireFormat.FieldType.INT32,
-          java.lang.Integer.class);
-    public static final int BAR_FOUR_FIELD_NUMBER = 15;
-    /**
-     * <code>extend .protobuf_unittest.TestExtensionRangeSerialize { ... }</code>
-     */
-    public static final
-      com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-        protobuf_unittest.UnittestProto.TestExtensionRangeSerialize,
-        java.lang.Integer> barFour = com.google.protobuf.GeneratedMessageLite
-            .newSingularGeneratedExtension(
-          protobuf_unittest.UnittestProto.TestExtensionRangeSerialize.getDefaultInstance(),
-          0,
-          null,
-          null,
-          15,
-          com.google.protobuf.WireFormat.FieldType.INT32,
-          java.lang.Integer.class);
-    public static final int BAR_FIVE_FIELD_NUMBER = 19;
-    /**
-     * <code>extend .protobuf_unittest.TestExtensionRangeSerialize { ... }</code>
-     */
-    public static final
-      com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-        protobuf_unittest.UnittestProto.TestExtensionRangeSerialize,
-        java.lang.Integer> barFive = com.google.protobuf.GeneratedMessageLite
-            .newSingularGeneratedExtension(
-          protobuf_unittest.UnittestProto.TestExtensionRangeSerialize.getDefaultInstance(),
-          0,
-          null,
-          null,
-          19,
-          com.google.protobuf.WireFormat.FieldType.INT32,
-          java.lang.Integer.class);
-  }
-
-  public static final int OPTIONAL_INT32_EXTENSION_FIELD_NUMBER = 1;
-  /**
-   * <pre>
-   * Singular
-   * </pre>
-   *
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Integer> optionalInt32Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        0,
-        null,
-        null,
-        1,
-        com.google.protobuf.WireFormat.FieldType.INT32,
-        java.lang.Integer.class);
-  public static final int OPTIONAL_INT64_EXTENSION_FIELD_NUMBER = 2;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Long> optionalInt64Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        0L,
-        null,
-        null,
-        2,
-        com.google.protobuf.WireFormat.FieldType.INT64,
-        java.lang.Long.class);
-  public static final int OPTIONAL_UINT32_EXTENSION_FIELD_NUMBER = 3;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Integer> optionalUint32Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        0,
-        null,
-        null,
-        3,
-        com.google.protobuf.WireFormat.FieldType.UINT32,
-        java.lang.Integer.class);
-  public static final int OPTIONAL_UINT64_EXTENSION_FIELD_NUMBER = 4;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Long> optionalUint64Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        0L,
-        null,
-        null,
-        4,
-        com.google.protobuf.WireFormat.FieldType.UINT64,
-        java.lang.Long.class);
-  public static final int OPTIONAL_SINT32_EXTENSION_FIELD_NUMBER = 5;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Integer> optionalSint32Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        0,
-        null,
-        null,
-        5,
-        com.google.protobuf.WireFormat.FieldType.SINT32,
-        java.lang.Integer.class);
-  public static final int OPTIONAL_SINT64_EXTENSION_FIELD_NUMBER = 6;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Long> optionalSint64Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        0L,
-        null,
-        null,
-        6,
-        com.google.protobuf.WireFormat.FieldType.SINT64,
-        java.lang.Long.class);
-  public static final int OPTIONAL_FIXED32_EXTENSION_FIELD_NUMBER = 7;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Integer> optionalFixed32Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        0,
-        null,
-        null,
-        7,
-        com.google.protobuf.WireFormat.FieldType.FIXED32,
-        java.lang.Integer.class);
-  public static final int OPTIONAL_FIXED64_EXTENSION_FIELD_NUMBER = 8;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Long> optionalFixed64Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        0L,
-        null,
-        null,
-        8,
-        com.google.protobuf.WireFormat.FieldType.FIXED64,
-        java.lang.Long.class);
-  public static final int OPTIONAL_SFIXED32_EXTENSION_FIELD_NUMBER = 9;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Integer> optionalSfixed32Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        0,
-        null,
-        null,
-        9,
-        com.google.protobuf.WireFormat.FieldType.SFIXED32,
-        java.lang.Integer.class);
-  public static final int OPTIONAL_SFIXED64_EXTENSION_FIELD_NUMBER = 10;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Long> optionalSfixed64Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        0L,
-        null,
-        null,
-        10,
-        com.google.protobuf.WireFormat.FieldType.SFIXED64,
-        java.lang.Long.class);
-  public static final int OPTIONAL_FLOAT_EXTENSION_FIELD_NUMBER = 11;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Float> optionalFloatExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        0F,
-        null,
-        null,
-        11,
-        com.google.protobuf.WireFormat.FieldType.FLOAT,
-        java.lang.Float.class);
-  public static final int OPTIONAL_DOUBLE_EXTENSION_FIELD_NUMBER = 12;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Double> optionalDoubleExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        0D,
-        null,
-        null,
-        12,
-        com.google.protobuf.WireFormat.FieldType.DOUBLE,
-        java.lang.Double.class);
-  public static final int OPTIONAL_BOOL_EXTENSION_FIELD_NUMBER = 13;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Boolean> optionalBoolExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        false,
-        null,
-        null,
-        13,
-        com.google.protobuf.WireFormat.FieldType.BOOL,
-        java.lang.Boolean.class);
-  public static final int OPTIONAL_STRING_EXTENSION_FIELD_NUMBER = 14;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.String> optionalStringExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        "",
-        null,
-        null,
-        14,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        java.lang.String.class);
-  public static final int OPTIONAL_BYTES_EXTENSION_FIELD_NUMBER = 15;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      com.google.protobuf.ByteString> optionalBytesExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        com.google.protobuf.ByteString.EMPTY,
-        null,
-        null,
-        15,
-        com.google.protobuf.WireFormat.FieldType.BYTES,
-        com.google.protobuf.ByteString.class);
-  public static final int OPTIONALGROUP_EXTENSION_FIELD_NUMBER = 16;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      protobuf_unittest.UnittestProto.OptionalGroup_extension> optionalGroupExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.OptionalGroup_extension.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.OptionalGroup_extension.getDefaultInstance(),
-        null,
-        16,
-        com.google.protobuf.WireFormat.FieldType.GROUP,
-        protobuf_unittest.UnittestProto.OptionalGroup_extension.class);
-  public static final int OPTIONAL_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER = 18;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage> optionalNestedMessageExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.getDefaultInstance(),
-        null,
-        18,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.class);
-  public static final int OPTIONAL_FOREIGN_MESSAGE_EXTENSION_FIELD_NUMBER = 19;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      protobuf_unittest.UnittestProto.ForeignMessage> optionalForeignMessageExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.ForeignMessage.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.ForeignMessage.getDefaultInstance(),
-        null,
-        19,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        protobuf_unittest.UnittestProto.ForeignMessage.class);
-  public static final int OPTIONAL_IMPORT_MESSAGE_EXTENSION_FIELD_NUMBER = 20;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      com.google.protobuf.test.UnittestImport.ImportMessage> optionalImportMessageExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        com.google.protobuf.test.UnittestImport.ImportMessage.getDefaultInstance(),
-        com.google.protobuf.test.UnittestImport.ImportMessage.getDefaultInstance(),
-        null,
-        20,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        com.google.protobuf.test.UnittestImport.ImportMessage.class);
-  public static final int OPTIONAL_NESTED_ENUM_EXTENSION_FIELD_NUMBER = 21;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum> optionalNestedEnumExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum.FOO,
-        null,
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum.internalGetValueMap(),
-        21,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum.class);
-  public static final int OPTIONAL_FOREIGN_ENUM_EXTENSION_FIELD_NUMBER = 22;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      protobuf_unittest.UnittestProto.ForeignEnum> optionalForeignEnumExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.ForeignEnum.FOREIGN_FOO,
-        null,
-        protobuf_unittest.UnittestProto.ForeignEnum.internalGetValueMap(),
-        22,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        protobuf_unittest.UnittestProto.ForeignEnum.class);
-  public static final int OPTIONAL_IMPORT_ENUM_EXTENSION_FIELD_NUMBER = 23;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      com.google.protobuf.test.UnittestImport.ImportEnum> optionalImportEnumExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        com.google.protobuf.test.UnittestImport.ImportEnum.IMPORT_FOO,
-        null,
-        com.google.protobuf.test.UnittestImport.ImportEnum.internalGetValueMap(),
-        23,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        com.google.protobuf.test.UnittestImport.ImportEnum.class);
-  public static final int OPTIONAL_STRING_PIECE_EXTENSION_FIELD_NUMBER = 24;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.String> optionalStringPieceExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        "",
-        null,
-        null,
-        24,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        java.lang.String.class);
-  public static final int OPTIONAL_CORD_EXTENSION_FIELD_NUMBER = 25;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.String> optionalCordExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        "",
-        null,
-        null,
-        25,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        java.lang.String.class);
-  public static final int OPTIONAL_PUBLIC_IMPORT_MESSAGE_EXTENSION_FIELD_NUMBER = 26;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      com.google.protobuf.test.UnittestImportPublic.PublicImportMessage> optionalPublicImportMessageExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        com.google.protobuf.test.UnittestImportPublic.PublicImportMessage.getDefaultInstance(),
-        com.google.protobuf.test.UnittestImportPublic.PublicImportMessage.getDefaultInstance(),
-        null,
-        26,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        com.google.protobuf.test.UnittestImportPublic.PublicImportMessage.class);
-  public static final int OPTIONAL_LAZY_MESSAGE_EXTENSION_FIELD_NUMBER = 27;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage> optionalLazyMessageExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.getDefaultInstance(),
-        null,
-        27,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.class);
-  public static final int REPEATED_INT32_EXTENSION_FIELD_NUMBER = 31;
-  /**
-   * <pre>
-   * Repeated
-   * </pre>
-   *
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<java.lang.Integer>> repeatedInt32Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        null,
-        31,
-        com.google.protobuf.WireFormat.FieldType.INT32,
-        false,
-        java.lang.Integer.class);
-  public static final int REPEATED_INT64_EXTENSION_FIELD_NUMBER = 32;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<java.lang.Long>> repeatedInt64Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        null,
-        32,
-        com.google.protobuf.WireFormat.FieldType.INT64,
-        false,
-        java.lang.Long.class);
-  public static final int REPEATED_UINT32_EXTENSION_FIELD_NUMBER = 33;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<java.lang.Integer>> repeatedUint32Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        null,
-        33,
-        com.google.protobuf.WireFormat.FieldType.UINT32,
-        false,
-        java.lang.Integer.class);
-  public static final int REPEATED_UINT64_EXTENSION_FIELD_NUMBER = 34;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<java.lang.Long>> repeatedUint64Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        null,
-        34,
-        com.google.protobuf.WireFormat.FieldType.UINT64,
-        false,
-        java.lang.Long.class);
-  public static final int REPEATED_SINT32_EXTENSION_FIELD_NUMBER = 35;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<java.lang.Integer>> repeatedSint32Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        null,
-        35,
-        com.google.protobuf.WireFormat.FieldType.SINT32,
-        false,
-        java.lang.Integer.class);
-  public static final int REPEATED_SINT64_EXTENSION_FIELD_NUMBER = 36;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<java.lang.Long>> repeatedSint64Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        null,
-        36,
-        com.google.protobuf.WireFormat.FieldType.SINT64,
-        false,
-        java.lang.Long.class);
-  public static final int REPEATED_FIXED32_EXTENSION_FIELD_NUMBER = 37;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<java.lang.Integer>> repeatedFixed32Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        null,
-        37,
-        com.google.protobuf.WireFormat.FieldType.FIXED32,
-        false,
-        java.lang.Integer.class);
-  public static final int REPEATED_FIXED64_EXTENSION_FIELD_NUMBER = 38;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<java.lang.Long>> repeatedFixed64Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        null,
-        38,
-        com.google.protobuf.WireFormat.FieldType.FIXED64,
-        false,
-        java.lang.Long.class);
-  public static final int REPEATED_SFIXED32_EXTENSION_FIELD_NUMBER = 39;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<java.lang.Integer>> repeatedSfixed32Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        null,
-        39,
-        com.google.protobuf.WireFormat.FieldType.SFIXED32,
-        false,
-        java.lang.Integer.class);
-  public static final int REPEATED_SFIXED64_EXTENSION_FIELD_NUMBER = 40;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<java.lang.Long>> repeatedSfixed64Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        null,
-        40,
-        com.google.protobuf.WireFormat.FieldType.SFIXED64,
-        false,
-        java.lang.Long.class);
-  public static final int REPEATED_FLOAT_EXTENSION_FIELD_NUMBER = 41;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<java.lang.Float>> repeatedFloatExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        null,
-        41,
-        com.google.protobuf.WireFormat.FieldType.FLOAT,
-        false,
-        java.lang.Float.class);
-  public static final int REPEATED_DOUBLE_EXTENSION_FIELD_NUMBER = 42;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<java.lang.Double>> repeatedDoubleExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        null,
-        42,
-        com.google.protobuf.WireFormat.FieldType.DOUBLE,
-        false,
-        java.lang.Double.class);
-  public static final int REPEATED_BOOL_EXTENSION_FIELD_NUMBER = 43;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<java.lang.Boolean>> repeatedBoolExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        null,
-        43,
-        com.google.protobuf.WireFormat.FieldType.BOOL,
-        false,
-        java.lang.Boolean.class);
-  public static final int REPEATED_STRING_EXTENSION_FIELD_NUMBER = 44;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<java.lang.String>> repeatedStringExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        null,
-        44,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        false,
-        java.lang.String.class);
-  public static final int REPEATED_BYTES_EXTENSION_FIELD_NUMBER = 45;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<com.google.protobuf.ByteString>> repeatedBytesExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        null,
-        45,
-        com.google.protobuf.WireFormat.FieldType.BYTES,
-        false,
-        com.google.protobuf.ByteString.class);
-  public static final int REPEATEDGROUP_EXTENSION_FIELD_NUMBER = 46;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<protobuf_unittest.UnittestProto.RepeatedGroup_extension>> repeatedGroupExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.RepeatedGroup_extension.getDefaultInstance(),
-        null,
-        46,
-        com.google.protobuf.WireFormat.FieldType.GROUP,
-        false,
-        protobuf_unittest.UnittestProto.RepeatedGroup_extension.class);
-  public static final int REPEATED_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER = 48;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage>> repeatedNestedMessageExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.getDefaultInstance(),
-        null,
-        48,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        false,
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.class);
-  public static final int REPEATED_FOREIGN_MESSAGE_EXTENSION_FIELD_NUMBER = 49;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<protobuf_unittest.UnittestProto.ForeignMessage>> repeatedForeignMessageExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.ForeignMessage.getDefaultInstance(),
-        null,
-        49,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        false,
-        protobuf_unittest.UnittestProto.ForeignMessage.class);
-  public static final int REPEATED_IMPORT_MESSAGE_EXTENSION_FIELD_NUMBER = 50;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<com.google.protobuf.test.UnittestImport.ImportMessage>> repeatedImportMessageExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        com.google.protobuf.test.UnittestImport.ImportMessage.getDefaultInstance(),
-        null,
-        50,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        false,
-        com.google.protobuf.test.UnittestImport.ImportMessage.class);
-  public static final int REPEATED_NESTED_ENUM_EXTENSION_FIELD_NUMBER = 51;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum>> repeatedNestedEnumExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum.internalGetValueMap(),
-        51,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        false,
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum.class);
-  public static final int REPEATED_FOREIGN_ENUM_EXTENSION_FIELD_NUMBER = 52;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<protobuf_unittest.UnittestProto.ForeignEnum>> repeatedForeignEnumExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        protobuf_unittest.UnittestProto.ForeignEnum.internalGetValueMap(),
-        52,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        false,
-        protobuf_unittest.UnittestProto.ForeignEnum.class);
-  public static final int REPEATED_IMPORT_ENUM_EXTENSION_FIELD_NUMBER = 53;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<com.google.protobuf.test.UnittestImport.ImportEnum>> repeatedImportEnumExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        com.google.protobuf.test.UnittestImport.ImportEnum.internalGetValueMap(),
-        53,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        false,
-        com.google.protobuf.test.UnittestImport.ImportEnum.class);
-  public static final int REPEATED_STRING_PIECE_EXTENSION_FIELD_NUMBER = 54;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<java.lang.String>> repeatedStringPieceExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        null,
-        54,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        false,
-        java.lang.String.class);
-  public static final int REPEATED_CORD_EXTENSION_FIELD_NUMBER = 55;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<java.lang.String>> repeatedCordExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        null,
-        null,
-        55,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        false,
-        java.lang.String.class);
-  public static final int REPEATED_LAZY_MESSAGE_EXTENSION_FIELD_NUMBER = 57;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.util.List<protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage>> repeatedLazyMessageExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.getDefaultInstance(),
-        null,
-        57,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        false,
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.class);
-  public static final int DEFAULT_INT32_EXTENSION_FIELD_NUMBER = 61;
-  /**
-   * <pre>
-   * Singular with defaults
-   * </pre>
-   *
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Integer> defaultInt32Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        41,
-        null,
-        null,
-        61,
-        com.google.protobuf.WireFormat.FieldType.INT32,
-        java.lang.Integer.class);
-  public static final int DEFAULT_INT64_EXTENSION_FIELD_NUMBER = 62;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Long> defaultInt64Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        42L,
-        null,
-        null,
-        62,
-        com.google.protobuf.WireFormat.FieldType.INT64,
-        java.lang.Long.class);
-  public static final int DEFAULT_UINT32_EXTENSION_FIELD_NUMBER = 63;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Integer> defaultUint32Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        43,
-        null,
-        null,
-        63,
-        com.google.protobuf.WireFormat.FieldType.UINT32,
-        java.lang.Integer.class);
-  public static final int DEFAULT_UINT64_EXTENSION_FIELD_NUMBER = 64;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Long> defaultUint64Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        44L,
-        null,
-        null,
-        64,
-        com.google.protobuf.WireFormat.FieldType.UINT64,
-        java.lang.Long.class);
-  public static final int DEFAULT_SINT32_EXTENSION_FIELD_NUMBER = 65;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Integer> defaultSint32Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        -45,
-        null,
-        null,
-        65,
-        com.google.protobuf.WireFormat.FieldType.SINT32,
-        java.lang.Integer.class);
-  public static final int DEFAULT_SINT64_EXTENSION_FIELD_NUMBER = 66;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Long> defaultSint64Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        46L,
-        null,
-        null,
-        66,
-        com.google.protobuf.WireFormat.FieldType.SINT64,
-        java.lang.Long.class);
-  public static final int DEFAULT_FIXED32_EXTENSION_FIELD_NUMBER = 67;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Integer> defaultFixed32Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        47,
-        null,
-        null,
-        67,
-        com.google.protobuf.WireFormat.FieldType.FIXED32,
-        java.lang.Integer.class);
-  public static final int DEFAULT_FIXED64_EXTENSION_FIELD_NUMBER = 68;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Long> defaultFixed64Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        48L,
-        null,
-        null,
-        68,
-        com.google.protobuf.WireFormat.FieldType.FIXED64,
-        java.lang.Long.class);
-  public static final int DEFAULT_SFIXED32_EXTENSION_FIELD_NUMBER = 69;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Integer> defaultSfixed32Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        49,
-        null,
-        null,
-        69,
-        com.google.protobuf.WireFormat.FieldType.SFIXED32,
-        java.lang.Integer.class);
-  public static final int DEFAULT_SFIXED64_EXTENSION_FIELD_NUMBER = 70;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Long> defaultSfixed64Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        -50L,
-        null,
-        null,
-        70,
-        com.google.protobuf.WireFormat.FieldType.SFIXED64,
-        java.lang.Long.class);
-  public static final int DEFAULT_FLOAT_EXTENSION_FIELD_NUMBER = 71;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Float> defaultFloatExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        51.5F,
-        null,
-        null,
-        71,
-        com.google.protobuf.WireFormat.FieldType.FLOAT,
-        java.lang.Float.class);
-  public static final int DEFAULT_DOUBLE_EXTENSION_FIELD_NUMBER = 72;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Double> defaultDoubleExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        52000D,
-        null,
-        null,
-        72,
-        com.google.protobuf.WireFormat.FieldType.DOUBLE,
-        java.lang.Double.class);
-  public static final int DEFAULT_BOOL_EXTENSION_FIELD_NUMBER = 73;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Boolean> defaultBoolExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        true,
-        null,
-        null,
-        73,
-        com.google.protobuf.WireFormat.FieldType.BOOL,
-        java.lang.Boolean.class);
-  public static final int DEFAULT_STRING_EXTENSION_FIELD_NUMBER = 74;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.String> defaultStringExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        "hello",
-        null,
-        null,
-        74,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        java.lang.String.class);
-  public static final int DEFAULT_BYTES_EXTENSION_FIELD_NUMBER = 75;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      com.google.protobuf.ByteString> defaultBytesExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        com.google.protobuf.Internal.bytesDefaultValue("world"),
-        null,
-        null,
-        75,
-        com.google.protobuf.WireFormat.FieldType.BYTES,
-        com.google.protobuf.ByteString.class);
-  public static final int DEFAULT_NESTED_ENUM_EXTENSION_FIELD_NUMBER = 81;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum> defaultNestedEnumExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum.BAR,
-        null,
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum.internalGetValueMap(),
-        81,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedEnum.class);
-  public static final int DEFAULT_FOREIGN_ENUM_EXTENSION_FIELD_NUMBER = 82;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      protobuf_unittest.UnittestProto.ForeignEnum> defaultForeignEnumExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.ForeignEnum.FOREIGN_BAR,
-        null,
-        protobuf_unittest.UnittestProto.ForeignEnum.internalGetValueMap(),
-        82,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        protobuf_unittest.UnittestProto.ForeignEnum.class);
-  public static final int DEFAULT_IMPORT_ENUM_EXTENSION_FIELD_NUMBER = 83;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      com.google.protobuf.test.UnittestImport.ImportEnum> defaultImportEnumExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        com.google.protobuf.test.UnittestImport.ImportEnum.IMPORT_BAR,
-        null,
-        com.google.protobuf.test.UnittestImport.ImportEnum.internalGetValueMap(),
-        83,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        com.google.protobuf.test.UnittestImport.ImportEnum.class);
-  public static final int DEFAULT_STRING_PIECE_EXTENSION_FIELD_NUMBER = 84;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.String> defaultStringPieceExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        "abc",
-        null,
-        null,
-        84,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        java.lang.String.class);
-  public static final int DEFAULT_CORD_EXTENSION_FIELD_NUMBER = 85;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.String> defaultCordExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        "123",
-        null,
-        null,
-        85,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        java.lang.String.class);
-  public static final int ONEOF_UINT32_EXTENSION_FIELD_NUMBER = 111;
-  /**
-   * <pre>
-   * For oneof test
-   * </pre>
-   *
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.Integer> oneofUint32Extension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        0,
-        null,
-        null,
-        111,
-        com.google.protobuf.WireFormat.FieldType.UINT32,
-        java.lang.Integer.class);
-  public static final int ONEOF_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER = 112;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage> oneofNestedMessageExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.getDefaultInstance(),
-        null,
-        112,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage.class);
-  public static final int ONEOF_STRING_EXTENSION_FIELD_NUMBER = 113;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      java.lang.String> oneofStringExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        "",
-        null,
-        null,
-        113,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        java.lang.String.class);
-  public static final int ONEOF_BYTES_EXTENSION_FIELD_NUMBER = 114;
-  /**
-   * <code>extend .protobuf_unittest.TestAllExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestAllExtensions,
-      com.google.protobuf.ByteString> oneofBytesExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestAllExtensions.getDefaultInstance(),
-        com.google.protobuf.ByteString.EMPTY,
-        null,
-        null,
-        114,
-        com.google.protobuf.WireFormat.FieldType.BYTES,
-        com.google.protobuf.ByteString.class);
-  public static final int MY_EXTENSION_STRING_FIELD_NUMBER = 50;
-  /**
-   * <code>extend .protobuf_unittest.TestFieldOrderings { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestFieldOrderings,
-      java.lang.String> myExtensionString = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestFieldOrderings.getDefaultInstance(),
-        "",
-        null,
-        null,
-        50,
-        com.google.protobuf.WireFormat.FieldType.STRING,
-        java.lang.String.class);
-  public static final int MY_EXTENSION_INT_FIELD_NUMBER = 5;
-  /**
-   * <code>extend .protobuf_unittest.TestFieldOrderings { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestFieldOrderings,
-      java.lang.Integer> myExtensionInt = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestFieldOrderings.getDefaultInstance(),
-        0,
-        null,
-        null,
-        5,
-        com.google.protobuf.WireFormat.FieldType.INT32,
-        java.lang.Integer.class);
-  public static final int PACKED_INT32_EXTENSION_FIELD_NUMBER = 90;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestPackedExtensions,
-      java.util.List<java.lang.Integer>> packedInt32Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestPackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        90,
-        com.google.protobuf.WireFormat.FieldType.INT32,
-        true,
-        java.lang.Integer.class);
-  public static final int PACKED_INT64_EXTENSION_FIELD_NUMBER = 91;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestPackedExtensions,
-      java.util.List<java.lang.Long>> packedInt64Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestPackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        91,
-        com.google.protobuf.WireFormat.FieldType.INT64,
-        true,
-        java.lang.Long.class);
-  public static final int PACKED_UINT32_EXTENSION_FIELD_NUMBER = 92;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestPackedExtensions,
-      java.util.List<java.lang.Integer>> packedUint32Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestPackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        92,
-        com.google.protobuf.WireFormat.FieldType.UINT32,
-        true,
-        java.lang.Integer.class);
-  public static final int PACKED_UINT64_EXTENSION_FIELD_NUMBER = 93;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestPackedExtensions,
-      java.util.List<java.lang.Long>> packedUint64Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestPackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        93,
-        com.google.protobuf.WireFormat.FieldType.UINT64,
-        true,
-        java.lang.Long.class);
-  public static final int PACKED_SINT32_EXTENSION_FIELD_NUMBER = 94;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestPackedExtensions,
-      java.util.List<java.lang.Integer>> packedSint32Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestPackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        94,
-        com.google.protobuf.WireFormat.FieldType.SINT32,
-        true,
-        java.lang.Integer.class);
-  public static final int PACKED_SINT64_EXTENSION_FIELD_NUMBER = 95;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestPackedExtensions,
-      java.util.List<java.lang.Long>> packedSint64Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestPackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        95,
-        com.google.protobuf.WireFormat.FieldType.SINT64,
-        true,
-        java.lang.Long.class);
-  public static final int PACKED_FIXED32_EXTENSION_FIELD_NUMBER = 96;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestPackedExtensions,
-      java.util.List<java.lang.Integer>> packedFixed32Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestPackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        96,
-        com.google.protobuf.WireFormat.FieldType.FIXED32,
-        true,
-        java.lang.Integer.class);
-  public static final int PACKED_FIXED64_EXTENSION_FIELD_NUMBER = 97;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestPackedExtensions,
-      java.util.List<java.lang.Long>> packedFixed64Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestPackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        97,
-        com.google.protobuf.WireFormat.FieldType.FIXED64,
-        true,
-        java.lang.Long.class);
-  public static final int PACKED_SFIXED32_EXTENSION_FIELD_NUMBER = 98;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestPackedExtensions,
-      java.util.List<java.lang.Integer>> packedSfixed32Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestPackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        98,
-        com.google.protobuf.WireFormat.FieldType.SFIXED32,
-        true,
-        java.lang.Integer.class);
-  public static final int PACKED_SFIXED64_EXTENSION_FIELD_NUMBER = 99;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestPackedExtensions,
-      java.util.List<java.lang.Long>> packedSfixed64Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestPackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        99,
-        com.google.protobuf.WireFormat.FieldType.SFIXED64,
-        true,
-        java.lang.Long.class);
-  public static final int PACKED_FLOAT_EXTENSION_FIELD_NUMBER = 100;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestPackedExtensions,
-      java.util.List<java.lang.Float>> packedFloatExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestPackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        100,
-        com.google.protobuf.WireFormat.FieldType.FLOAT,
-        true,
-        java.lang.Float.class);
-  public static final int PACKED_DOUBLE_EXTENSION_FIELD_NUMBER = 101;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestPackedExtensions,
-      java.util.List<java.lang.Double>> packedDoubleExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestPackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        101,
-        com.google.protobuf.WireFormat.FieldType.DOUBLE,
-        true,
-        java.lang.Double.class);
-  public static final int PACKED_BOOL_EXTENSION_FIELD_NUMBER = 102;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestPackedExtensions,
-      java.util.List<java.lang.Boolean>> packedBoolExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestPackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        102,
-        com.google.protobuf.WireFormat.FieldType.BOOL,
-        true,
-        java.lang.Boolean.class);
-  public static final int PACKED_ENUM_EXTENSION_FIELD_NUMBER = 103;
-  /**
-   * <code>extend .protobuf_unittest.TestPackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestPackedExtensions,
-      java.util.List<protobuf_unittest.UnittestProto.ForeignEnum>> packedEnumExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestPackedExtensions.getDefaultInstance(),
-        null,
-        protobuf_unittest.UnittestProto.ForeignEnum.internalGetValueMap(),
-        103,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        true,
-        protobuf_unittest.UnittestProto.ForeignEnum.class);
-  public static final int UNPACKED_INT32_EXTENSION_FIELD_NUMBER = 90;
-  /**
-   * <code>extend .protobuf_unittest.TestUnpackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestUnpackedExtensions,
-      java.util.List<java.lang.Integer>> unpackedInt32Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestUnpackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        90,
-        com.google.protobuf.WireFormat.FieldType.INT32,
-        false,
-        java.lang.Integer.class);
-  public static final int UNPACKED_INT64_EXTENSION_FIELD_NUMBER = 91;
-  /**
-   * <code>extend .protobuf_unittest.TestUnpackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestUnpackedExtensions,
-      java.util.List<java.lang.Long>> unpackedInt64Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestUnpackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        91,
-        com.google.protobuf.WireFormat.FieldType.INT64,
-        false,
-        java.lang.Long.class);
-  public static final int UNPACKED_UINT32_EXTENSION_FIELD_NUMBER = 92;
-  /**
-   * <code>extend .protobuf_unittest.TestUnpackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestUnpackedExtensions,
-      java.util.List<java.lang.Integer>> unpackedUint32Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestUnpackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        92,
-        com.google.protobuf.WireFormat.FieldType.UINT32,
-        false,
-        java.lang.Integer.class);
-  public static final int UNPACKED_UINT64_EXTENSION_FIELD_NUMBER = 93;
-  /**
-   * <code>extend .protobuf_unittest.TestUnpackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestUnpackedExtensions,
-      java.util.List<java.lang.Long>> unpackedUint64Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestUnpackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        93,
-        com.google.protobuf.WireFormat.FieldType.UINT64,
-        false,
-        java.lang.Long.class);
-  public static final int UNPACKED_SINT32_EXTENSION_FIELD_NUMBER = 94;
-  /**
-   * <code>extend .protobuf_unittest.TestUnpackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestUnpackedExtensions,
-      java.util.List<java.lang.Integer>> unpackedSint32Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestUnpackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        94,
-        com.google.protobuf.WireFormat.FieldType.SINT32,
-        false,
-        java.lang.Integer.class);
-  public static final int UNPACKED_SINT64_EXTENSION_FIELD_NUMBER = 95;
-  /**
-   * <code>extend .protobuf_unittest.TestUnpackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestUnpackedExtensions,
-      java.util.List<java.lang.Long>> unpackedSint64Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestUnpackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        95,
-        com.google.protobuf.WireFormat.FieldType.SINT64,
-        false,
-        java.lang.Long.class);
-  public static final int UNPACKED_FIXED32_EXTENSION_FIELD_NUMBER = 96;
-  /**
-   * <code>extend .protobuf_unittest.TestUnpackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestUnpackedExtensions,
-      java.util.List<java.lang.Integer>> unpackedFixed32Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestUnpackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        96,
-        com.google.protobuf.WireFormat.FieldType.FIXED32,
-        false,
-        java.lang.Integer.class);
-  public static final int UNPACKED_FIXED64_EXTENSION_FIELD_NUMBER = 97;
-  /**
-   * <code>extend .protobuf_unittest.TestUnpackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestUnpackedExtensions,
-      java.util.List<java.lang.Long>> unpackedFixed64Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestUnpackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        97,
-        com.google.protobuf.WireFormat.FieldType.FIXED64,
-        false,
-        java.lang.Long.class);
-  public static final int UNPACKED_SFIXED32_EXTENSION_FIELD_NUMBER = 98;
-  /**
-   * <code>extend .protobuf_unittest.TestUnpackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestUnpackedExtensions,
-      java.util.List<java.lang.Integer>> unpackedSfixed32Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestUnpackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        98,
-        com.google.protobuf.WireFormat.FieldType.SFIXED32,
-        false,
-        java.lang.Integer.class);
-  public static final int UNPACKED_SFIXED64_EXTENSION_FIELD_NUMBER = 99;
-  /**
-   * <code>extend .protobuf_unittest.TestUnpackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestUnpackedExtensions,
-      java.util.List<java.lang.Long>> unpackedSfixed64Extension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestUnpackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        99,
-        com.google.protobuf.WireFormat.FieldType.SFIXED64,
-        false,
-        java.lang.Long.class);
-  public static final int UNPACKED_FLOAT_EXTENSION_FIELD_NUMBER = 100;
-  /**
-   * <code>extend .protobuf_unittest.TestUnpackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestUnpackedExtensions,
-      java.util.List<java.lang.Float>> unpackedFloatExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestUnpackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        100,
-        com.google.protobuf.WireFormat.FieldType.FLOAT,
-        false,
-        java.lang.Float.class);
-  public static final int UNPACKED_DOUBLE_EXTENSION_FIELD_NUMBER = 101;
-  /**
-   * <code>extend .protobuf_unittest.TestUnpackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestUnpackedExtensions,
-      java.util.List<java.lang.Double>> unpackedDoubleExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestUnpackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        101,
-        com.google.protobuf.WireFormat.FieldType.DOUBLE,
-        false,
-        java.lang.Double.class);
-  public static final int UNPACKED_BOOL_EXTENSION_FIELD_NUMBER = 102;
-  /**
-   * <code>extend .protobuf_unittest.TestUnpackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestUnpackedExtensions,
-      java.util.List<java.lang.Boolean>> unpackedBoolExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestUnpackedExtensions.getDefaultInstance(),
-        null,
-        null,
-        102,
-        com.google.protobuf.WireFormat.FieldType.BOOL,
-        false,
-        java.lang.Boolean.class);
-  public static final int UNPACKED_ENUM_EXTENSION_FIELD_NUMBER = 103;
-  /**
-   * <code>extend .protobuf_unittest.TestUnpackedExtensions { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestUnpackedExtensions,
-      java.util.List<protobuf_unittest.UnittestProto.ForeignEnum>> unpackedEnumExtension = com.google.protobuf.GeneratedMessageLite
-          .newRepeatedGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestUnpackedExtensions.getDefaultInstance(),
-        null,
-        protobuf_unittest.UnittestProto.ForeignEnum.internalGetValueMap(),
-        103,
-        com.google.protobuf.WireFormat.FieldType.ENUM,
-        false,
-        protobuf_unittest.UnittestProto.ForeignEnum.class);
-  public static final int TEST_ALL_TYPES_FIELD_NUMBER = 536860000;
-  /**
-   * <code>extend .protobuf_unittest.TestHugeFieldNumbers { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestHugeFieldNumbers,
-      protobuf_unittest.UnittestProto.TestAllTypes> testAllTypes = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestHugeFieldNumbers.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance(),
-        protobuf_unittest.UnittestProto.TestAllTypes.getDefaultInstance(),
-        null,
-        536860000,
-        com.google.protobuf.WireFormat.FieldType.MESSAGE,
-        protobuf_unittest.UnittestProto.TestAllTypes.class);
-  public static final int TEST_EXTENSION_INSIDE_TABLE_EXTENSION_FIELD_NUMBER = 5;
-  /**
-   * <code>extend .protobuf_unittest.TestExtensionInsideTable { ... }</code>
-   */
-  public static final
-    com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
-      protobuf_unittest.UnittestProto.TestExtensionInsideTable,
-      java.lang.Integer> testExtensionInsideTableExtension = com.google.protobuf.GeneratedMessageLite
-          .newSingularGeneratedExtension(
-        protobuf_unittest.UnittestProto.TestExtensionInsideTable.getDefaultInstance(),
-        0,
-        null,
-        null,
-        5,
-        com.google.protobuf.WireFormat.FieldType.INT32,
-        java.lang.Integer.class);
-
-  static {
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/java/kotlin-lite/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/java/kotlin-lite/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst
deleted file mode 100644
index c8996af..0000000
--- a/java/kotlin-lite/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst
+++ /dev/null
@@ -1,658 +0,0 @@
-proto3_unittest/UnittestProto3$TestOneof2$Builder.class
-protobuf_unittest/UnittestProto$TestDeprecatedMessageOrBuilder.class
-protobuf_unittest/MapLiteUnittest$TestMessageMapLiteOrBuilder.class
-protobuf_unittest/UnittestProto$Int32MessageOrBuilder.class
-evil_names_proto3/EvilNamesProto3OuterClass$Class$Builder.class
-protobuf_unittest/UnittestProto$TestDupFieldNumber.class
-proto3_unittest/UnittestProto3.class
-multiple_files_proto3/MultipleFilesMessageA.class
-protobuf_unittest/UnittestProto$TestMutualRecursionA$SubGroup.class
-protobuf_unittest/UnittestProto$FooRequest.class
-protobuf_unittest/UnittestProto$TestDeprecatedMessage$Builder.class
-protobuf_unittest/UnittestProto$TestRepeatedScalarDifferentTagSizes.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapBoolBoolDefaultEntryHolder.class
-protobuf_unittest/UnittestProto$ForeignMessage$Builder.class
-example_extensible_message/ExampleExtensibleMessageOuterClass.class
-com/google/protobuf/UnittestLite$TestEmptyMessageLite.class
-protobuf_unittest/UnittestProto$TestOneof2$BarCase.class
-com/google/protobuf/UnittestLite$TestDeprecatedLiteOrBuilder.class
-protobuf_unittest/UnittestProto$OneBytesOrBuilder.class
-protobuf_unittest/UnittestProto$TestReallyLargeTagNumberOrBuilder.class
-protobuf_unittest/UnittestProto.class
-protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32Int32DefaultEntryHolder.class
-proto3_unittest/UnittestProto3$TestEmptyMessage$Builder.class
-protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLite.class
-protobuf_unittest/MapLiteUnittest$TestEnumMapLiteOrBuilder.class
-protobuf_unittest/UnittestProto$TestPackedTypes.class
-protobuf_unittest/UnittestProto$TestEnumWithDupValue.class
-com/google/protobuf/UnittestLite$TestEmptyMessageWithExtensionsLiteOrBuilder.class
-protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedGroupOrBuilder.class
-protobuf_unittest/UnittestProto$FooClientMessage$Builder.class
-protobuf_unittest/UnittestProto$TestNestedMessageHasBits$NestedMessageOrBuilder.class
-protobuf_unittest/UnittestProto$FooServerMessageOrBuilder.class
-evil_names_proto2/EvilNamesProto2OuterClass$1.class
-protobuf_unittest/UnittestProto$TestExtensionOrderings2$Builder.class
-protobuf_unittest/UnittestProto$TestParsingMergeOrBuilder.class
-protobuf_unittest/UnittestProto$TestMutualRecursionB.class
-protobuf_unittest/UnittestProto$TestIsInitialized$Builder.class
-com/google/protobuf/UnittestLite$TestParsingMergeLite.class
-com/google/protobuf/TestUtil$TestLogHandler.class
-protobuf_unittest/UnittestProto$OneBytes.class
-proto3_unittest/UnittestProto3$NestedTestAllTypesOrBuilder.class
-evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypesOrBuilder.class
-com/google/protobuf/UnittestLite$OptionalGroup_extension_lite.class
-protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage$NestedNestedMessage$Builder.class
-com/google/protobuf/UnittestLite$TestPackedExtensionsLiteOrBuilder.class
-com/google/protobuf/UnittestLite$TestAllTypesLite.class
-protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group2$Builder.class
-protobuf_unittest/UnittestProto$TestEnumWithDupValue$1.class
-protobuf_unittest/MapLiteUnittest$TestEnumMapLite.class
-evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$VDefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestRepeatedScalarDifferentTagSizes$Builder.class
-com/google/protobuf/UnittestLite$RecursiveMessageOrBuilder.class
-protobuf_unittest/UnittestProto$TestCamelCaseFieldNamesOrBuilder.class
-protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32ForeignMessageDefaultEntryHolder.class
-evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedEnum$1.class
-protobuf_unittest/UnittestProto$TestNestedMessageHasBits$NestedMessage$Builder.class
-protobuf_unittest/UnittestProto$TestAllTypes$NestedMessage$Builder.class
-protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage$NestedNestedMessageOrBuilder.class
-evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2$Builder.class
-protobuf_unittest/UnittestProto$TestSparseEnum$TestSparseEnumVerifier.class
-protobuf_unittest/UnittestProto$Uint32MessageOrBuilder.class
-protobuf_unittest/UnittestProto$TestOneof2$Builder.class
-protobuf_unittest/UnittestProto$TestMultipleExtensionRangesOrBuilder.class
-com/google/protobuf/UnittestLite$V1MessageLite.class
-protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage$Builder.class
-protobuf_unittest/MapLiteUnittest$ForeignMessageArenaLiteOrBuilder.class
-protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible.class
-protobuf_unittest/UnittestProto$Uint32Message.class
-protobuf_unittest/UnittestProto$TestRecursiveMessageOrBuilder.class
-protobuf_unittest/UnittestProto$TestEmptyMessage$Builder.class
-protobuf_unittest/UnittestProto$TestDeprecatedFieldsOrBuilder.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32Int32DefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestRequiredMessage.class
-evil_names_proto3/EvilNamesProto3OuterClass$ClassOrBuilder.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapUint64Uint64DefaultEntryHolder.class
-protobuf_unittest/UnittestProto$MoreBytesOrBuilder.class
-protobuf_unittest/UnittestProto$TestHugeFieldNumbers$Builder.class
-protobuf_unittest/UnittestProto$MoreStringOrBuilder.class
-evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$MapDefaultEntryHolder.class
-com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$Builder.class
-example_extensible_message/ExampleExtensibleMessage.class
-evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3.class
-protobuf_unittest/UnittestProto$BarRequest.class
-protobuf_unittest/UnittestProto$TestExtensionRangeSerialize.class
-protobuf_unittest/UnittestProto$TestOneof2OrBuilder.class
-protobuf_unittest/MapLiteUnittest$Proto2MapEnumLite$Proto2MapEnumLiteVerifier.class
-protobuf_unittest/MapLiteUnittest$TestRequiredLite.class
-com/google/protobuf/UnittestLite$V2EnumLite$V2EnumLiteVerifier.class
-protobuf_unittest/UnittestProto$TestMultipleExtensionRanges$Builder.class
-com/google/protobuf/UnittestLite$RepeatedGroup_extension_liteOrBuilder.class
-protobuf_unittest/MapLiteUnittest.class
-proto3_unittest/UnittestProto3$TestUnpackedTypes.class
-protobuf_unittest/UnittestProto$TestAllTypes$2.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$RepeatedGroup.class
-protobuf_unittest/UnittestProto$OneString$Builder.class
-com/google/protobuf/UnittestLite$DupEnum.class
-com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group1.class
-protobuf_unittest/UnittestProto$TestDupFieldNumber$BarOrBuilder.class
-protobuf_unittest/UnittestProto$TestRepeatedScalarDifferentTagSizesOrBuilder.class
-protobuf_unittest/UnittestProto$RepeatedGroup_extension$Builder.class
-protobuf_unittest/MapLiteUnittest$1.class
-protobuf_unittest/UnittestProto$TestDupFieldNumber$FooOrBuilder.class
-protobuf_unittest/UnittestProto$ForeignEnum$ForeignEnumVerifier.class
-com/google/protobuf/test/UnittestImport$ImportEnum$ImportEnumVerifier.class
-protobuf_unittest/UnittestProto$TestParsingMerge$OptionalGroup$Builder.class
-protobuf_unittest/UnittestProto$TestExtensionRangeSerializeOrBuilder.class
-evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedMessage$Builder.class
-com/google/protobuf/test/UnittestImport$ImportEnum$1.class
-multiple_files_proto3/MultipleFilesMessageA$1.class
-protobuf_unittest/MapLiteUnittest$TestMapLite$MapFixed32Fixed32DefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestDeprecatedFields.class
-protobuf_unittest/UnittestProto$TestAllTypes.class
-protobuf_unittest/UnittestProto$TestDynamicExtensionsOrBuilder.class
-protobuf_unittest/UnittestProto$TestAllTypes$RepeatedGroup.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapUint32Uint32DefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicMessageType.class
-protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage$SubGroup.class
-proto3_unittest/UnittestProto3$TestAllTypes$NestedEnum.class
-multiple_files_proto3/NestedEnum.class
-protobuf_unittest/UnittestProto$TestPackedTypesOrBuilder.class
-protobuf_unittest/UnittestProto$TestExtensionOrderings2.class
-protobuf_unittest/UnittestProto$BoolMessage.class
-evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$PairsDefaultEntryHolder.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage2.class
-com/google/protobuf/UnittestLite$PackedFixed32.class
-com/google/protobuf/UnittestLite$TestNestedExtensionLiteOrBuilder.class
-protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicEnumType$DynamicEnumTypeVerifier.class
-protobuf_unittest/UnittestProto$TestPackedExtensionsOrBuilder.class
-proto3_unittest/UnittestProto3$ForeignEnum.class
-protobuf_unittest/UnittestProto$BarRequest$Builder.class
-protobuf_unittest/UnittestProto$OptionalGroup_extension$Builder.class
-evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes.class
-protobuf_unittest/UnittestProto$MoreString$Builder.class
-protobuf_unittest/UnittestProto$OptionalGroup_extensionOrBuilder.class
-protobuf_unittest/UnittestProto$TestHugeFieldNumbersOrBuilder.class
-protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLiteOrBuilder.class
-com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedGroup.class
-protobuf_unittest/MapLiteUnittest$TestMapLite$MapBoolBoolDefaultEntryHolder.class
-com/google/protobuf/UnittestImportPublicLite.class
-com/google/protobuf/test/UnittestImportPublic$PublicImportMessage.class
-proto3_unittest/UnittestProto3$TestAllTypes$NestedMessage.class
-protobuf_unittest/UnittestProto$TestExtensionInsideTable.class
-com/google/protobuf/UnittestLite$TestEmptyMessageWithExtensionsLite$Builder.class
-protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessageOrBuilder.class
-proto3_unittest/UnittestProto3$TestMessageWithDummy.class
-protobuf_unittest/UnittestProto$TestPickleNestedMessage$Builder.class
-protobuf_unittest/UnittestProto$TestRecursiveMessage.class
-protobuf_unittest/MapLiteUnittest$TestMapLite$MapUint64Uint64DefaultEntryHolder.class
-com/google/protobuf/UnittestLite$DupEnum$TestEnumWithDupValueLite$TestEnumWithDupValueLiteVerifier.class
-protobuf_unittest/UnittestProto$TestOneof.class
-com/google/protobuf/UnittestImportPublicLite$PublicImportMessageLite.class
-protobuf_unittest/UnittestProto$BarResponse.class
-protobuf_unittest/MapLiteUnittest$MapEnumLite.class
-protobuf_unittest/UnittestProto$TestDeprecatedFields$Builder.class
-com/google/protobuf/UnittestLite$TestPackedTypesLiteOrBuilder.class
-protobuf_unittest/UnittestProto$TestOneof$FooCase.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapSfixed64Sfixed64DefaultEntryHolder.class
-protobuf_unittest/UnittestProto$Uint64MessageOrBuilder.class
-protobuf_unittest/MapLiteUnittest$Proto2MapEnumPlusExtraLite.class
-com/google/protobuf/UnittestLite$DupEnumOrBuilder.class
-protobuf_unittest/UnittestProto$Int32Message$Builder.class
-protobuf_unittest/UnittestProto$TestDynamicExtensions.class
-protobuf_unittest/UnittestProto$TestEmptyMessage.class
-protobuf_unittest/UnittestProto$BarResponse$Builder.class
-protobuf_unittest/MapLiteUnittest$TestRequiredMessageMapLite.class
-protobuf_unittest/UnittestProto$NestedTestAllTypes$Builder.class
-protobuf_unittest/UnittestProto$TestParsingMerge$OptionalGroupOrBuilder.class
-com/google/protobuf/UnittestLite$NonPackedInt32$Builder.class
-protobuf_unittest/UnittestProto$SparseEnumMessage.class
-com/google/protobuf/UnittestLite$NonPackedFixed32OrBuilder.class
-protobuf_unittest/UnittestProto$TestNestedExtension$Builder.class
-com/google/protobuf/UnittestLite$TestNestedExtensionLite$Builder.class
-protobuf_unittest/UnittestProto$TestMutualRecursionA$SubMessageOrBuilder.class
-proto3_unittest/UnittestProto3$NestedTestAllTypes.class
-protobuf_unittest/UnittestProto$TestIsInitializedOrBuilder.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$RepeatedGroupOrBuilder.class
-protobuf_unittest/MapLiteUnittest$Proto2MapEnumPlusExtraLite$Proto2MapEnumPlusExtraLiteVerifier.class
-protobuf_unittest/UnittestProto$ForeignMessage.class
-protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32DoubleDefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage$SubGroupOrBuilder.class
-protobuf_unittest/UnittestProto$Int64Message$Builder.class
-com/google/protobuf/UnittestLite$NonPackedFixed32$Builder.class
-protobuf_unittest/UnittestProto$TestAllTypes$NestedEnum$1.class
-protobuf_unittest/UnittestProto$TestRequiredForeignOrBuilder.class
-protobuf_unittest/MapLiteUnittest$TestRequiredLite$Builder.class
-protobuf_unittest/UnittestProto$TestOneof2$NestedEnum.class
-com/google/protobuf/UnittestLite$ForeignMessageLite.class
-com/google/protobuf/test/UnittestImport$ImportEnumForMap$1.class
-evil_names_proto3/EvilNamesProto3OuterClass$1.class
-com/google/protobuf/UnittestLite$DupEnum$TestEnumWithDupValueLite$1.class
-evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3OrBuilder.class
-protobuf_unittest/UnittestProto$TestReallyLargeTagNumber.class
-evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedMessageOrBuilder.class
-com/google/protobuf/test/UnittestImport$ImportMessage$Builder.class
-protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage.class
-evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2OrBuilder.class
-protobuf_unittest/UnittestProto$TestAllTypes$OneofFieldCase.class
-com/google/protobuf/UnittestLite$TestEmptyMessageLiteOrBuilder.class
-com/google/protobuf/UnittestLite$TestOneofParsingLite$OneofFieldCase.class
-protobuf_unittest/UnittestProto$TestExtensionOrderings2$TestExtensionOrderings3$Builder.class
-evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$ContinueDefaultEntryHolder.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$3.class
-protobuf_unittest/UnittestProto$OptionalGroup_extension.class
-proto3_unittest/UnittestProto3$NestedTestAllTypes$Builder.class
-evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2$ALLCAPSMAPDefaultEntryHolder.class
-proto3_unittest/UnittestProto3$ForeignMessageOrBuilder.class
-com/google/protobuf/UnittestImportLite$ImportEnumLite$1.class
-protobuf_unittest/UnittestProto$TestCommentInjectionMessageOrBuilder.class
-protobuf_unittest/UnittestProto$TestExtensionOrderings1OrBuilder.class
-protobuf_unittest/UnittestProto$FooRequest$Builder.class
-com/google/protobuf/UnittestLite$OptionalGroup_extension_lite$Builder.class
-protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group1OrBuilder.class
-protobuf_unittest/UnittestProto$TestNestedMessageHasBits$Builder.class
-evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$KDefaultEntryHolder.class
-proto3_unittest/UnittestProto3$TestUnpackedTypesOrBuilder.class
-protobuf_unittest/UnittestProto$RepeatedGroup_extension.class
-protobuf_unittest/MapLiteUnittest$TestMapLite$MapFixed64Fixed64DefaultEntryHolder.class
-com/google/protobuf/UnittestImportLite.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$2.class
-protobuf_unittest/UnittestProto$TestHugeFieldNumbers$OptionalGroup$Builder.class
-protobuf_unittest/UnittestProto$SparseEnumMessage$Builder.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLiteOrBuilder.class
-protobuf_unittest/UnittestProto$Uint32Message$Builder.class
-protobuf_unittest/UnittestProto$TestCamelCaseFieldNames.class
-protobuf_unittest/UnittestProto$TestParsingMerge$OptionalGroup.class
-com/google/protobuf/UnittestImportLite$1.class
-protobuf_unittest/UnittestProto$TestFieldOrderings$NestedMessage$Builder.class
-com/google/protobuf/UnittestImportLite$ImportMessageLite$Builder.class
-protobuf_unittest/UnittestProto$TestReservedFields.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$NestedEnum.class
-protobuf_unittest/MapLiteUnittest$TestMapLite$MapSint32Sint32DefaultEntryHolder.class
-multiple_files_proto3/NestedEnum$1.class
-protobuf_unittest/UnittestProto$TestRecursiveMessage$Builder.class
-protobuf_unittest/UnittestProto$TestRequiredOneofOrBuilder.class
-protobuf_unittest/UnittestProto$Int64MessageOrBuilder.class
-protobuf_unittest/UnittestProto$TestJsonNameOrBuilder.class
-protobuf_unittest/UnittestProto$OneStringOrBuilder.class
-protobuf_unittest/UnittestProto$TestLazyMessage.class
-multiple_files_proto3/MultipleFilesMessageAOrBuilder.class
-protobuf_unittest/UnittestProto$FooResponse.class
-protobuf_unittest/UnittestProto$TestGroupExtensionOrBuilder.class
-com/google/protobuf/UnittestLite$NonPackedInt32.class
-protobuf_unittest/UnittestProto$TestRequiredForeign$Builder.class
-com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite.class
-protobuf_unittest/UnittestProto$TestNestedExtension.class
-evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedMessage$Builder.class
-proto3_unittest/UnittestProto3$ForeignEnum$1.class
-com/google/protobuf/UnittestLite$RepeatedGroup_extension_lite.class
-protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Builder.class
-proto3_unittest/UnittestProto3$TestAllTypes$2.class
-com/google/protobuf/UnittestLite$TestAllExtensionsLite$Builder.class
-protobuf_unittest/UnittestProto$TestCamelCaseFieldNames$1.class
-evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2$CamelCaseCase.class
-protobuf_unittest/UnittestProto$TestExtremeDefaultValues$Builder.class
-protobuf_unittest/UnittestProto$ForeignEnum$1.class
-evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2.class
-protobuf_unittest/UnittestProto$TestAllTypesOrBuilder.class
-protobuf_unittest/UnittestProto$TestExtensionOrderings2OrBuilder.class
-protobuf_unittest/UnittestProto$MoreBytes.class
-com/google/protobuf/test/UnittestImportPublic$1.class
-com/google/protobuf/UnittestLite$TestOneofParsingLite$Builder.class
-protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLite$UnknownMapFieldDefaultEntryHolder.class
-com/google/protobuf/UnittestLite$V1MessageLiteOrBuilder.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$1.class
-protobuf_unittest/UnittestProto$TestAllTypes$NestedMessage.class
-protobuf_unittest/UnittestProto$TestExtensionOrderings1$Builder.class
-protobuf_unittest/UnittestProto$TestUnpackedExtensions.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32EnumDefaultEntryHolder.class
-protobuf_unittest/MapLiteUnittest$TestMapLite$MapSfixed32Sfixed32DefaultEntryHolder.class
-com/google/protobuf/UnittestLite$V1EnumLite$V1EnumLiteVerifier.class
-protobuf_unittest/UnittestProto$TestReallyLargeTagNumber$Builder.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32DoubleDefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group2OrBuilder.class
-com/google/protobuf/UnittestLite$TestEmptyMessageWithExtensionsLite.class
-com/google/protobuf/test/UnittestImport$ImportMessage.class
-protobuf_unittest/MapLiteUnittest$ForeignMessageArenaLite.class
-protobuf_unittest/MapLiteUnittest$TestMapLite$MapStringStringDefaultEntryHolder.class
-protobuf_unittest/MapLiteUnittest$TestMapLite.class
-protobuf_unittest/MapLiteUnittest$TestEnumMapLite$UnknownMapFieldDefaultEntryHolder.class
-evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedEnum.class
-protobuf_unittest/UnittestProto$TestFieldOrderings.class
-protobuf_unittest/UnittestProto$TestAllExtensionsOrBuilder.class
-com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group2$Builder.class
-com/google/protobuf/UnittestLite$V2EnumLite$1.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapSfixed32Sfixed32DefaultEntryHolder.class
-protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLite$KnownMapFieldDefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestDeprecatedMessage.class
-protobuf_unittest/MapLiteUnittest$TestRequiredMessageMapLite$MapFieldDefaultEntryHolder.class
-protobuf_unittest/UnittestProto$RepeatedGroup_extensionOrBuilder.class
-protobuf_unittest/UnittestProto$TestOneof$FooGroupOrBuilder.class
-protobuf_unittest/UnittestProto$TestFieldOrderings$Builder.class
-protobuf_unittest/UnittestProto$TestDupFieldNumber$Foo.class
-evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes.class
-protobuf_unittest/UnittestProto$TestGroup$Builder.class
-protobuf_unittest/UnittestProto$TestOneofBackwardsCompatibleOrBuilder.class
-protobuf_unittest/UnittestProto$Uint64Message.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$RepeatedGroup$Builder.class
-protobuf_unittest/UnittestProto$MoreBytes$Builder.class
-protobuf_unittest/UnittestProto$TestAllTypes$NestedEnum.class
-protobuf_unittest/UnittestProto$TestMultipleExtensionRanges.class
-com/google/protobuf/UnittestLite$TestEmptyMessageLite$Builder.class
-protobuf_unittest/UnittestProto$TestReservedFields$Builder.class
-protobuf_unittest/UnittestProto$TestExtensionInsideTable$Builder.class
-proto3_unittest/UnittestProto3$TestOneof2$NestedEnum$NestedEnumVerifier.class
-protobuf_unittest/UnittestProto$TestUnpackedTypesOrBuilder.class
-com/google/protobuf/UnittestImportLite$ImportEnumLite$ImportEnumLiteVerifier.class
-protobuf_unittest/MapLiteUnittest$TestEnumMapLite$KnownMapFieldDefaultEntryHolder.class
-com/google/protobuf/TestUtilLite.class
-protobuf_unittest/UnittestProto$TestUnpackedTypes$1.class
-protobuf_unittest/UnittestProto$TestRequiredOneof$NestedMessage.class
-protobuf_unittest/MapLiteUnittest$TestRequiredMessageMapLiteOrBuilder.class
-protobuf_unittest/UnittestProto$SparseEnumMessageOrBuilder.class
-com/google/protobuf/UnittestLite$ForeignMessageLiteOrBuilder.class
-proto3_unittest/UnittestProto3$TestAllTypes$NestedMessageOrBuilder.class
-protobuf_unittest/UnittestProto$TestAllTypes$OptionalGroupOrBuilder.class
-com/google/protobuf/UnittestLite$TestAllExtensionsLiteOrBuilder.class
-com/google/protobuf/test/UnittestImportPublic.class
-proto3_unittest/UnittestProto3$TestAllTypes$1.class
-multiple_files_proto3/MultipleFilesMessageBOrBuilder.class
-multiple_files_proto3/MultipleFilesMessageB.class
-protobuf_unittest/UnittestProto$TestUnpackedTypes.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage$Builder.class
-multiple_files_proto3/MultipleFilesProto3.class
-proto3_unittest/UnittestProto3$TestAllTypes$Builder.class
-protobuf_unittest/UnittestProto$TestEagerMessageOrBuilder.class
-protobuf_unittest/UnittestProto$TestEagerMessage.class
-com/google/protobuf/UnittestLite$ForeignMessageLite$Builder.class
-evil_names_proto2/EvilNamesProto2OuterClass$Interface.class
-protobuf_unittest/UnittestProto$TestUnpackedExtensions$Builder.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$OptionalGroup.class
-proto3_unittest/UnittestProto3$TestAllTypes$NestedEnum$NestedEnumVerifier.class
-protobuf_unittest/UnittestProto$TestUnpackedTypes$Builder.class
-protobuf_unittest/UnittestProto$TestRequiredMessageOrBuilder.class
-protobuf_unittest/MapLiteUnittest$TestMapLiteOrBuilder.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapFixed32Fixed32DefaultEntryHolder.class
-com/google/protobuf/UnittestLite$TestNestedExtensionLite.class
-proto3_unittest/UnittestProto3$TestOneof2$NestedEnum.class
-com/google/protobuf/UnittestLite$V2EnumLite.class
-com/google/protobuf/UnittestLite$V1EnumLite$1.class
-protobuf_unittest/UnittestProto$Int32Message.class
-com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$OptionalGroup.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$OptionalGroupOrBuilder.class
-com/google/protobuf/UnittestLite.class
-protobuf_unittest/UnittestProto$TestOneof$Builder.class
-proto3_unittest/UnittestProto3$TestUnpackedTypes$1.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLite$Builder.class
-evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$Builder.class
-proto3_unittest/UnittestProto3$TestOneof2$FooCase.class
-protobuf_unittest/UnittestProto$TestDupFieldNumber$Bar.class
-protobuf_unittest/UnittestProto$BoolMessageOrBuilder.class
-evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$KeyDefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestFieldOrderings$NestedMessage.class
-protobuf_unittest/MapLiteUnittest$Proto2MapEnumLite$1.class
-protobuf_unittest/UnittestProto$NestedTestAllTypesOrBuilder.class
-multiple_files_proto3/MultipleFilesMessageA$Builder.class
-proto3_unittest/UnittestProto3$TestOneof2.class
-protobuf_unittest/UnittestProto$TestHugeFieldNumbers$OptionalGroup.class
-proto3_unittest/UnittestProto3$TestMessageWithDummyOrBuilder.class
-evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedEnum$1.class
-com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group1$Builder.class
-protobuf_unittest/UnittestProto$VeryLargeEnum.class
-protobuf_unittest/MapLiteUnittest$Proto2MapEnumPlusExtraLite$1.class
-protobuf_unittest/UnittestProto$FooResponse$Builder.class
-protobuf_unittest/UnittestProto$TestForeignNested$Builder.class
-com/google/protobuf/test/UnittestImport$ImportEnum.class
-proto3_unittest/UnittestProto3$TestAllTypes$NestedEnum$1.class
-protobuf_unittest/UnittestProto$TestGroupExtension.class
-protobuf_unittest/UnittestProto$TestRequiredOneof$NestedMessage$Builder.class
-evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$Builder.class
-protobuf_unittest/UnittestProto$FooClientMessage.class
-com/google/protobuf/UnittestImportLite$ImportMessageLite.class
-evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedMessage.class
-protobuf_unittest/MapLiteUnittest$TestMapLite$MapSint64Sint64DefaultEntryHolder.class
-protobuf_unittest/UnittestProto$Uint64Message$Builder.class
-protobuf_unittest/UnittestProto$TestRequired.class
-protobuf_unittest/UnittestProto$TestOneof2$FooGroup.class
-com/google/protobuf/UnittestLite$PackedInt32OrBuilder.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$OneofFieldCase.class
-com/google/protobuf/UnittestLite$TestDeprecatedLite$Builder.class
-com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$StringStringMapDefaultEntryHolder.class
-protobuf_unittest/MapLiteUnittest$TestMessageMapLite.class
-protobuf_unittest/UnittestProto$TestPickleNestedMessage.class
-protobuf_unittest/UnittestProto$TestOneof2$FooGroupOrBuilder.class
-com/google/protobuf/UnittestLite$TestDeprecatedLite.class
-multiple_files_proto3/MultipleFilesMessageB$Builder.class
-example_extensible_message/ExampleExtensibleMessage$Builder.class
-protobuf_unittest/UnittestProto$TestOneof2$NestedMessage.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapSint64Sint64DefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestCommentInjectionMessage.class
-protobuf_unittest/UnittestProto$TestEmptyMessageWithExtensions$Builder.class
-protobuf_unittest/UnittestProto$TestNestedExtension$OptionalGroup_extension$Builder.class
-protobuf_unittest/UnittestProto$TestLazyMessageOrBuilder.class
-com/google/protobuf/test/UnittestImport$ImportEnumForMap$ImportEnumForMapVerifier.class
-com/google/protobuf/UnittestImportPublicLite$PublicImportMessageLiteOrBuilder.class
-com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage2$Builder.class
-com/google/protobuf/UnittestLite$RepeatedGroup_extension_lite$Builder.class
-com/google/protobuf/UnittestLite$1.class
-com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGeneratorOrBuilder.class
-protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGeneratorOrBuilder.class
-evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedEnum.class
-protobuf_unittest/UnittestProto$TestMutualRecursionA.class
-protobuf_unittest/UnittestProto$FooResponseOrBuilder.class
-protobuf_unittest/UnittestProto$TestDupFieldNumberOrBuilder.class
-protobuf_unittest/UnittestProto$TestAllTypes$RepeatedGroup$Builder.class
-protobuf_unittest/UnittestProto$TestUnpackedExtensionsOrBuilder.class
-proto3_unittest/UnittestProto3$TestEmptyMessageOrBuilder.class
-protobuf_unittest/UnittestProto$BarRequestOrBuilder.class
-protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicMessageType$Builder.class
-protobuf_unittest/UnittestProto$TestGroup$OptionalGroupOrBuilder.class
-protobuf_unittest/UnittestProto$TestEagerMessage$Builder.class
-proto3_unittest/UnittestProto3$TestPackedTypes$1.class
-com/google/protobuf/UnittestLite$DupEnum$Builder.class
-com/google/protobuf/UnittestLite$DupEnum$TestEnumWithDupValueLite.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$NestedEnum$1.class
-proto3_unittest/UnittestProto3$ForeignEnum$ForeignEnumVerifier.class
-protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt64Int64DefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestExtremeDefaultValues.class
-protobuf_unittest/UnittestProto$TestExtensionRangeSerialize$Builder.class
-protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32BytesDefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestJsonName$Builder.class
-com/google/protobuf/UnittestLite$TestParsingMergeLite$OptionalGroup$Builder.class
-protobuf_unittest/MapLiteUnittest$MapEnumLite$MapEnumLiteVerifier.class
-protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedGroup$Builder.class
-protobuf_unittest/UnittestProto$TestCommentInjectionMessage$Builder.class
-protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage$Builder.class
-com/google/protobuf/UnittestLite$TestPackedTypesLite$1.class
-com/google/protobuf/UnittestLite$RecursiveMessage$Builder.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapSint32Sint32DefaultEntryHolder.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32ForeignMessageDefaultEntryHolder.class
-com/google/protobuf/UnittestLite$TestParsingMergeLite$OptionalGroupOrBuilder.class
-protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage.class
-com/google/protobuf/UnittestLite$V1EnumLite.class
-protobuf_unittest/UnittestProto$TestForeignNested.class
-com/google/protobuf/UnittestLite$NonPackedInt32OrBuilder.class
-evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$Builder.class
-protobuf_unittest/UnittestProto$TestExtremeDefaultValuesOrBuilder.class
-protobuf_unittest/UnittestProto$TestNestedExtension$OptionalGroup_extensionOrBuilder.class
-protobuf_unittest/UnittestProto$TestHugeFieldNumbers.class
-protobuf_unittest/UnittestProto$TestOneof2$NestedEnum$NestedEnumVerifier.class
-protobuf_unittest/UnittestProto$TestSparseEnum.class
-protobuf_unittest/UnittestProto$Int64Message.class
-evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedMessage.class
-com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedGroup$Builder.class
-com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Builder.class
-com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group1OrBuilder.class
-protobuf_unittest/UnittestProto$TestPackedExtensions.class
-com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$OneofFieldCase.class
-com/google/protobuf/UnittestImportLite$ImportMessageLiteOrBuilder.class
-protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32EnumDefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestMutualRecursionA$SubMessage$Builder.class
-protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator.class
-protobuf_unittest/UnittestProto$TestOneof2$NestedEnum$1.class
-proto3_unittest/UnittestProto3$TestOneof2OrBuilder.class
-protobuf_unittest/UnittestProto$OneBytes$Builder.class
-protobuf_unittest/UnittestProto$BoolMessage$Builder.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$Builder.class
-protobuf_unittest/UnittestProto$TestParsingMerge$Builder.class
-protobuf_unittest/UnittestProto$1.class
-protobuf_unittest/UnittestProto$TestAllTypes$OptionalGroup$Builder.class
-com/google/protobuf/UnittestImportLite$ImportEnumLite.class
-protobuf_unittest/UnittestProto$TestGroupOrBuilder.class
-protobuf_unittest/UnittestProto$FooServerMessage$Builder.class
-protobuf_unittest/UnittestProto$TestAllTypes$NestedMessageOrBuilder.class
-protobuf_unittest/UnittestProto$TestAllTypes$NestedEnum$NestedEnumVerifier.class
-protobuf_unittest/UnittestProto$TestOneof2.class
-protobuf_unittest/UnittestProto$TestDeprecatedFields$OneofFieldsCase.class
-protobuf_unittest/MapLiteUnittest$TestRequiredLiteOrBuilder.class
-protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage$SubGroup$Builder.class
-protobuf_unittest/UnittestProto$FooServerMessage.class
-protobuf_unittest/UnittestProto$TestExtensionOrderings1.class
-proto3_unittest/UnittestProto3$TestUnpackedTypes$Builder.class
-protobuf_unittest/MapLiteUnittest$TestMapLite$MapSfixed64Sfixed64DefaultEntryHolder.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt64Int64DefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestPackedTypes$Builder.class
-protobuf_unittest/MapLiteUnittest$TestMessageMapLite$Builder.class
-com/google/protobuf/UnittestLite$TestPackedTypesLite$Builder.class
-protobuf_unittest/UnittestProto$TestMutualRecursionB$Builder.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32BytesDefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestDupFieldNumber$Bar$Builder.class
-evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypesOrBuilder.class
-protobuf_unittest/UnittestProto$TestOneof2$FooCase.class
-com/google/protobuf/UnittestLite$PackedFixed32$Builder.class
-com/google/protobuf/UnittestLite$TestParsingMergeLiteOrBuilder.class
-com/google/protobuf/UnittestLite$V2MessageLite.class
-protobuf_unittest/UnittestProto$FooClientMessageOrBuilder.class
-com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$OptionalGroup$Builder.class
-protobuf_unittest/UnittestProto$TestNestedExtension$OptionalGroup_extension.class
-protobuf_unittest/UnittestProto$TestHugeFieldNumbers$OptionalGroupOrBuilder.class
-com/google/protobuf/UnittestLite$ForeignEnumLite$ForeignEnumLiteVerifier.class
-com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group2.class
-protobuf_unittest/UnittestProto$TestOneof$FooGroup.class
-protobuf_unittest/UnittestProto$TestGroupExtension$Builder.class
-protobuf_unittest/UnittestProto$TestAllTypes$3.class
-protobuf_unittest/UnittestProto$TestMutualRecursionA$Builder.class
-protobuf_unittest/UnittestProto$TestNestedMessageHasBits.class
-evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$ContinueDefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestFieldOrderingsOrBuilder.class
-com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group2OrBuilder.class
-protobuf_unittest/MapLiteUnittest$TestMapLite$MapUint32Uint32DefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage$NestedNestedMessage.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapFixed64Fixed64DefaultEntryHolder.class
-evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$1.class
-com/google/protobuf/UnittestLite$TestAllExtensionsLite.class
-proto3_unittest/UnittestProto3$ForeignMessage$Builder.class
-evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedEnum$NestedEnumVerifier.class
-protobuf_unittest/UnittestProto$TestMutualRecursionBOrBuilder.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapStringStringDefaultEntryHolder.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLite.class
-protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedGroup.class
-protobuf_unittest/UnittestProto$TestExtensionInsideTableOrBuilder.class
-protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group2.class
-protobuf_unittest/MapLiteUnittest$TestMapLite$TeboringDefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestIsInitialized$SubMessageOrBuilder.class
-com/google/protobuf/UnittestLite$TestHugeFieldNumbersLiteOrBuilder.class
-protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32FloatDefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestMutualRecursionA$SubGroup$Builder.class
-com/google/protobuf/UnittestLite$V2MessageLiteOrBuilder.class
-proto3_unittest/UnittestProto3$TestPackedTypes$Builder.class
-com/google/protobuf/test/UnittestImport.class
-evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$ALLCAPSMAPDefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestEmptyMessageWithExtensions.class
-protobuf_unittest/UnittestProto$ForeignMessageOrBuilder.class
-protobuf_unittest/MapLiteUnittest$MapEnumLite$1.class
-com/google/protobuf/UnittestLite$ForeignEnumLite$1.class
-protobuf_unittest/UnittestProto$TestRequiredOneof.class
-protobuf_unittest/UnittestProto$TestAllTypes$RepeatedGroupOrBuilder.class
-protobuf_unittest/UnittestProto$NestedTestAllTypes.class
-protobuf_unittest/MapLiteUnittest$TestMapLite$Builder.class
-protobuf_unittest/UnittestProto$TestFieldOrderings$NestedMessageOrBuilder.class
-protobuf_unittest/UnittestProto$TestNestedMessageHasBitsOrBuilder.class
-protobuf_unittest/UnittestProto$TestAllExtensions$Builder.class
-protobuf_unittest/UnittestProto$TestAllTypes$1.class
-com/google/protobuf/UnittestLite$V2MessageLite$Builder.class
-proto3_unittest/UnittestProto3$ForeignMessage.class
-com/google/protobuf/UnittestLite$TestPackedExtensionsLite.class
-evil_names_proto2/EvilNamesProto2OuterClass$InterfaceOrBuilder.class
-evil_names_proto2/EvilNamesProto2OuterClass$Interface$Builder.class
-com/google/protobuf/test/UnittestImport$ImportMessageOrBuilder.class
-protobuf_unittest/UnittestProto$TestDupFieldNumber$Foo$Builder.class
-protobuf_unittest/UnittestProto$TestAllTypes$Builder.class
-protobuf_unittest/UnittestProto$OneString.class
-com/google/protobuf/test/UnittestImport$ImportEnumForMap.class
-com/google/protobuf/UnittestLite$RecursiveMessage.class
-protobuf_unittest/UnittestProto$TestGroup$OptionalGroup$Builder.class
-com/google/protobuf/TestUtil.class
-proto3_unittest/UnittestProto3$TestAllTypes$NestedMessage$Builder.class
-proto3_unittest/UnittestProto3$TestAllTypes$OneofFieldCase.class
-protobuf_unittest/UnittestProto$TestDupFieldNumber$Builder.class
-protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicEnumType.class
-example_extensible_message/ExampleExtensibleMessage$1.class
-evil_names_proto2/EvilNamesProto2OuterClass.class
-evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedEnum$NestedEnumVerifier.class
-com/google/protobuf/UnittestLite$PackedInt32.class
-protobuf_unittest/UnittestProto$TestPackedTypes$1.class
-protobuf_unittest/UnittestProto$TestRequiredOneof$Builder.class
-com/google/protobuf/UnittestLite$PackedFixed32OrBuilder.class
-protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLite$Builder.class
-protobuf_unittest/UnittestProto$TestMutualRecursionAOrBuilder.class
-example_extensible_message/ExampleExtensibleMessageOrBuilder.class
-protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group1$Builder.class
-evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$LeadingUnderscoreOneofCase.class
-protobuf_unittest/UnittestProto$TestHugeFieldNumbers$StringStringMapDefaultEntryHolder.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$NestedEnum$NestedEnumVerifier.class
-protobuf_unittest/UnittestProto$TestExtensionOrderings2$TestExtensionOrderings3.class
-protobuf_unittest/UnittestProto$TestEmptyMessageOrBuilder.class
-proto3_unittest/UnittestProto3$TestPackedTypesOrBuilder.class
-multiple_files_proto3/MultipleFilesMessageB$1.class
-protobuf_unittest/UnittestProto$TestIsInitialized.class
-protobuf_unittest/UnittestProto$TestRequiredOrBuilder.class
-protobuf_unittest/UnittestProto$TestAllExtensions.class
-evil_names_proto3/EvilNamesProto3OuterClass$Class.class
-evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedMessageOrBuilder.class
-com/google/protobuf/UnittestLite$OptionalGroup_extension_liteOrBuilder.class
-com/google/protobuf/TestUtil$1.class
-protobuf_unittest/UnittestProto$TestOneof2$FooGroup$Builder.class
-protobuf_unittest/UnittestProto$TestGroup$OptionalGroup.class
-protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible$FooGroup.class
-com/google/protobuf/UnittestLite$TestPackedExtensionsLite$Builder.class
-protobuf_unittest/UnittestProto$TestParsingMerge.class
-com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$OptionalGroupOrBuilder.class
-protobuf_unittest/UnittestProto$TestNestedMessageHasBits$NestedMessage.class
-protobuf_unittest/UnittestProto$TestRequired$Builder.class
-protobuf_unittest/MapLiteUnittest$TestMessageMapLite$MapInt32MessageDefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestPackedExtensions$Builder.class
-protobuf_unittest/UnittestProto$TestExtensionOrderings2$TestExtensionOrderings3OrBuilder.class
-protobuf_unittest/UnittestProto$VeryLargeEnum$VeryLargeEnumVerifier.class
-evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$CamelCaseCase.class
-com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedGroupOrBuilder.class
-protobuf_unittest/UnittestProto$MoreString.class
-com/google/protobuf/UnittestLite$NonPackedFixed32.class
-protobuf_unittest/UnittestProto$TestGroup.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage2OrBuilder.class
-protobuf_unittest/UnittestProto$TestRequiredForeign.class
-com/google/protobuf/UnittestLite$TestOneofParsingLiteOrBuilder.class
-protobuf_unittest/UnittestProto$TestSparseEnum$1.class
-protobuf_unittest/MapLiteUnittest$Proto2MapEnumLite.class
-protobuf_unittest/UnittestProto$TestPickleNestedMessageOrBuilder.class
-protobuf_unittest/UnittestProto$TestNestedExtensionOrBuilder.class
-protobuf_unittest/MapLiteUnittest$TestRequiredMessageMapLite$Builder.class
-proto3_unittest/UnittestProto3$TestEmptyMessage.class
-protobuf_unittest/UnittestProto$BarResponseOrBuilder.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessageOrBuilder.class
-com/google/protobuf/test/UnittestImportPublic$PublicImportMessageOrBuilder.class
-protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32FloatDefaultEntryHolder.class
-protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicMessageTypeOrBuilder.class
-com/google/protobuf/test/UnittestImportPublic$PublicImportMessage$Builder.class
-protobuf_unittest/UnittestProto$TestCamelCaseFieldNames$Builder.class
-com/google/protobuf/UnittestLite$V1MessageLite$Builder.class
-evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$1.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage.class
-protobuf_unittest/UnittestProto$ForeignEnum.class
-com/google/protobuf/UnittestLite$ForeignEnumLite.class
-proto3_unittest/UnittestProto3$TestMessageWithDummy$Builder.class
-protobuf_unittest/UnittestProto$TestRequiredOneof$NestedMessageOrBuilder.class
-protobuf_unittest/UnittestProto$TestOneof2$NestedMessageOrBuilder.class
-com/google/protobuf/UnittestLite$TestAllTypesLite$OptionalGroup$Builder.class
-com/google/protobuf/UnittestLite$TestParsingMergeLite$OptionalGroup.class
-proto3_unittest/UnittestProto3$TestPackedTypes.class
-proto3_unittest/UnittestProto3$1.class
-protobuf_unittest/UnittestProto$FooRequestOrBuilder.class
-protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible$FooGroup$Builder.class
-protobuf_unittest/UnittestProto$TestReservedFieldsOrBuilder.class
-protobuf_unittest/UnittestProto$TestForeignNestedOrBuilder.class
-proto3_unittest/UnittestProto3$TestAllTypes.class
-protobuf_unittest/UnittestProto$TestOneofOrBuilder.class
-com/google/protobuf/UnittestImportPublicLite$1.class
-protobuf_unittest/UnittestProto$TestHugeFieldNumbers$OneofFieldCase.class
-protobuf_unittest/UnittestProto$TestRequiredOneof$FooCase.class
-protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group1.class
-protobuf_unittest/UnittestProto$TestAllTypes$OptionalGroup.class
-evil_names_proto3/EvilNamesProto3OuterClass.class
-protobuf_unittest/UnittestProto$TestMutualRecursionA$SubGroupOrBuilder.class
-protobuf_unittest/UnittestProto$TestEnumWithDupValue$TestEnumWithDupValueVerifier.class
-protobuf_unittest/MapLiteUnittest$TestEnumMapLite$Builder.class
-protobuf_unittest/UnittestProto$TestOneof2$NestedMessage$Builder.class
-protobuf_unittest/UnittestProto$TestLazyMessage$Builder.class
-com/google/protobuf/UnittestLite$TestAllTypesLiteOrBuilder.class
-com/google/protobuf/test/UnittestImport$1.class
-protobuf_unittest/UnittestProto$VeryLargeEnum$1.class
-proto3_unittest/UnittestProto3$TestAllTypesOrBuilder.class
-protobuf_unittest/UnittestProto$TestMutualRecursionA$SubMessage.class
-com/google/protobuf/UnittestLite$TestOneofParsingLite.class
-protobuf_unittest/UnittestProto$TestOneof$FooGroup$Builder.class
-protobuf_unittest/UnittestProto$TestJsonName.class
-protobuf_unittest/UnittestProto$TestRequiredMessage$Builder.class
-protobuf_unittest/MapLiteUnittest$ForeignMessageArenaLite$Builder.class
-protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible$Builder.class
-protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible$FooGroupOrBuilder.class
-protobuf_unittest/UnittestProto$TestDynamicExtensions$Builder.class
-com/google/protobuf/UnittestLite$TestPackedTypesLite.class
-multiple_files_proto3/NestedEnum$NestedEnumVerifier.class
-com/google/protobuf/UnittestImportPublicLite$PublicImportMessageLite$Builder.class
-protobuf_unittest/UnittestProto$TestEmptyMessageWithExtensionsOrBuilder.class
-proto3_unittest/UnittestProto3$TestOneof2$NestedEnum$1.class
-com/google/protobuf/UnittestLite$TestParsingMergeLite$Builder.class
-protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicEnumType$1.class
-com/google/protobuf/UnittestLite$PackedInt32$Builder.class
diff --git a/java/kotlin-lite/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/java/kotlin-lite/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
deleted file mode 100644
index d6c5e4f..0000000
--- a/java/kotlin-lite/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
+++ /dev/null
@@ -1,21 +0,0 @@
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/UnittestLite.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageA.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestUtilLite.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/example_extensible_message/ExampleExtensibleMessageOrBuilder.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/TestUtil.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageAOrBuilder.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/NestedEnum.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/test/UnittestImport.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageBOrBuilder.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/example_extensible_message/ExampleExtensibleMessage.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/MapLiteUnittest.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/evil_names_proto3/EvilNamesProto3OuterClass.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/evil_names_proto2/EvilNamesProto2OuterClass.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/proto3_unittest/UnittestProto3.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/example_extensible_message/ExampleExtensibleMessageOuterClass.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesProto3.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/multiple_files_proto3/MultipleFilesMessageB.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/test/UnittestImportPublic.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/protobuf_unittest/UnittestProto.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/UnittestImportPublicLite.java
-/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/generated-test-sources/com/google/protobuf/UnittestImportLite.java
diff --git a/java/kotlin-lite/target/protobuf-javalite-3.15.6.jar b/java/kotlin-lite/target/protobuf-javalite-3.15.6.jar
deleted file mode 100644
index 2588ada..0000000
--- a/java/kotlin-lite/target/protobuf-javalite-3.15.6.jar
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/surefire-reports/TEST-com.google.protobuf.kotlin.DslListTest.xml b/java/kotlin-lite/target/surefire-reports/TEST-com.google.protobuf.kotlin.DslListTest.xml
deleted file mode 100644
index 675d601..0000000
--- a/java/kotlin-lite/target/surefire-reports/TEST-com.google.protobuf.kotlin.DslListTest.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<testsuite xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://maven.apache.org/surefire/maven-surefire-plugin/xsd/surefire-test-report-3.0.xsd" version="3.0" name="com.google.protobuf.kotlin.DslListTest" time="0.209" tests="9" errors="0" skipped="0" failures="0">
-  <properties>
-    <property name="sun.desktop" value="gnome"/>
-    <property name="awt.toolkit" value="sun.awt.X11.XToolkit"/>
-    <property name="java.specification.version" value="11"/>
-    <property name="sun.cpu.isalist" value=""/>
-    <property name="sun.jnu.encoding" value="UTF-8"/>
-    <property name="java.class.path" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/test-classes:/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/classes:/usr/local/google/home/deannagarcia/.m2/repository/junit/junit/4.13.2/junit-4.13.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymock/2.2/easymock-2.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymockclassextension/2.2.1/easymockclassextension-2.2.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava/30.1-android/guava-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/errorprone/error_prone_annotations/2.3.4/error_prone_annotations-2.3.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava-testlib/30.1-android/guava-testlib-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/truth/truth/1.1.2/truth-1.1.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-qual/3.9.1/checker-qual-3.9.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/auto/value/auto-value-annotations/1.7.4/auto-value-annotations-1.7.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/ow2/asm/asm/9.0/asm-9.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.4.31/kotlin-stdlib-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-common/1.4.31/kotlin-stdlib-common-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/annotations/13.0/annotations-13.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test/1.4.31/kotlin-test-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test-common/1.4.31/kotlin-test-common-1.4.31.jar:"/>
-    <property name="java.vm.vendor" value="Google Inc."/>
-    <property name="sun.arch.data.model" value="64"/>
-    <property name="java.vendor.url" value="https://goto.google.com/java-platform"/>
-    <property name="user.timezone" value=""/>
-    <property name="java.vm.specification.version" value="11"/>
-    <property name="os.name" value="Linux"/>
-    <property name="sun.java.launcher" value="SUN_STANDARD"/>
-    <property name="user.country" value="US"/>
-    <property name="sun.boot.library.path" value="/usr/local/buildtools/java/jdk11/lib"/>
-    <property name="sun.java.command" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/surefire/surefirebooter15572213431693199165.jar /usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/surefire 2021-03-30T17-04-20_597-jvmRun1 surefire6258591630934235673tmp surefire_010158085988164019591tmp"/>
-    <property name="jdk.debug" value="release"/>
-    <property name="surefire.test.class.path" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/test-classes:/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/classes:/usr/local/google/home/deannagarcia/.m2/repository/junit/junit/4.13.2/junit-4.13.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymock/2.2/easymock-2.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymockclassextension/2.2.1/easymockclassextension-2.2.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava/30.1-android/guava-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/errorprone/error_prone_annotations/2.3.4/error_prone_annotations-2.3.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava-testlib/30.1-android/guava-testlib-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/truth/truth/1.1.2/truth-1.1.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-qual/3.9.1/checker-qual-3.9.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/auto/value/auto-value-annotations/1.7.4/auto-value-annotations-1.7.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/ow2/asm/asm/9.0/asm-9.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.4.31/kotlin-stdlib-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-common/1.4.31/kotlin-stdlib-common-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/annotations/13.0/annotations-13.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test/1.4.31/kotlin-test-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test-common/1.4.31/kotlin-test-common-1.4.31.jar:"/>
-    <property name="sun.cpu.endian" value="little"/>
-    <property name="user.home" value="/usr/local/google/home/deannagarcia"/>
-    <property name="user.language" value="en"/>
-    <property name="java.specification.vendor" value="Oracle Corporation"/>
-    <property name="java.version.date" value="2021-03-16"/>
-    <property name="java.home" value="/usr/local/buildtools/java/jdk11"/>
-    <property name="file.separator" value="/"/>
-    <property name="basedir" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite"/>
-    <property name="java.vm.compressedOopsMode" value="Zero based"/>
-    <property name="line.separator" value="&#10;"/>
-    <property name="java.specification.name" value="Java Platform API Specification"/>
-    <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
-    <property name="java.awt.graphicsenv" value="sun.awt.X11GraphicsEnvironment"/>
-    <property name="surefire.real.class.path" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/surefire/surefirebooter15572213431693199165.jar"/>
-    <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
-    <property name="java.runtime.version" value="11.0.10+9-google-release-363282249"/>
-    <property name="user.name" value="deannagarcia"/>
-    <property name="path.separator" value=":"/>
-    <property name="os.version" value="5.7.17-1rodete5-amd64"/>
-    <property name="java.runtime.name" value="OpenJDK Runtime Environment"/>
-    <property name="file.encoding" value="UTF-8"/>
-    <property name="java.vm.name" value="OpenJDK 64-Bit Server VM"/>
-    <property name="localRepository" value="/usr/local/google/home/deannagarcia/.m2/repository"/>
-    <property name="java.vendor.url.bug" value="http://b.corp.google.com/createIssue?component=32554"/>
-    <property name="java.io.tmpdir" value="/tmp"/>
-    <property name="java.version" value="11.0.10"/>
-    <property name="user.dir" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite"/>
-    <property name="os.arch" value="amd64"/>
-    <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
-    <property name="java.awt.printerjob" value="sun.print.PSPrinterJob"/>
-    <property name="sun.os.patch.level" value="unknown"/>
-    <property name="java.library.path" value="/usr/lib/mesa-diverted/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu/mesa:/usr/lib/x86_64-linux-gnu/dri:/usr/lib/x86_64-linux-gnu/gallium-pipe:/usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib"/>
-    <property name="java.vm.info" value="mixed mode, sharing"/>
-    <property name="java.vendor" value="Google Inc."/>
-    <property name="java.vm.version" value="11.0.10+9-google-release-363282249"/>
-    <property name="sun.io.unicode.encoding" value="UnicodeLittle"/>
-    <property name="java.class.version" value="55.0"/>
-  </properties>
-  <testcase name="matchesList" classname="com.google.protobuf.kotlin.DslListTest" time="0.066"/>
-  <testcase name="dslList_ListIteratorIsNotEvenSecretlyMutable" classname="com.google.protobuf.kotlin.DslListTest" time="0.044"/>
-  <testcase name="dslListIsNotMutable" classname="com.google.protobuf.kotlin.DslListTest" time="0.002"/>
-  <testcase name="dslListIsNotEvenSecretlyMutable" classname="com.google.protobuf.kotlin.DslListTest" time="0"/>
-  <testcase name="reflectsChangesInList" classname="com.google.protobuf.kotlin.DslListTest" time="0.001"/>
-  <testcase name="equality" classname="com.google.protobuf.kotlin.DslListTest" time="0.022"/>
-  <testcase name="dslList_ListIteratorIndexIsNotEvenSecretlyMutable" classname="com.google.protobuf.kotlin.DslListTest" time="0"/>
-  <testcase name="expectedToString" classname="com.google.protobuf.kotlin.DslListTest" time="0.002"/>
-  <testcase name="dslList_IteratorIsNotEvenSecretlyMutable" classname="com.google.protobuf.kotlin.DslListTest" time="0.001"/>
-</testsuite>
\ No newline at end of file
diff --git a/java/kotlin-lite/target/surefire-reports/TEST-com.google.protobuf.kotlin.DslMapTest.xml b/java/kotlin-lite/target/surefire-reports/TEST-com.google.protobuf.kotlin.DslMapTest.xml
deleted file mode 100644
index ef3d727..0000000
--- a/java/kotlin-lite/target/surefire-reports/TEST-com.google.protobuf.kotlin.DslMapTest.xml
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<testsuite xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://maven.apache.org/surefire/maven-surefire-plugin/xsd/surefire-test-report-3.0.xsd" version="3.0" name="com.google.protobuf.kotlin.DslMapTest" time="0.051" tests="17" errors="0" skipped="0" failures="0">
-  <properties>
-    <property name="sun.desktop" value="gnome"/>
-    <property name="awt.toolkit" value="sun.awt.X11.XToolkit"/>
-    <property name="java.specification.version" value="11"/>
-    <property name="sun.cpu.isalist" value=""/>
-    <property name="sun.jnu.encoding" value="UTF-8"/>
-    <property name="java.class.path" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/test-classes:/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/classes:/usr/local/google/home/deannagarcia/.m2/repository/junit/junit/4.13.2/junit-4.13.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymock/2.2/easymock-2.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymockclassextension/2.2.1/easymockclassextension-2.2.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava/30.1-android/guava-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/errorprone/error_prone_annotations/2.3.4/error_prone_annotations-2.3.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava-testlib/30.1-android/guava-testlib-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/truth/truth/1.1.2/truth-1.1.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-qual/3.9.1/checker-qual-3.9.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/auto/value/auto-value-annotations/1.7.4/auto-value-annotations-1.7.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/ow2/asm/asm/9.0/asm-9.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.4.31/kotlin-stdlib-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-common/1.4.31/kotlin-stdlib-common-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/annotations/13.0/annotations-13.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test/1.4.31/kotlin-test-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test-common/1.4.31/kotlin-test-common-1.4.31.jar:"/>
-    <property name="java.vm.vendor" value="Google Inc."/>
-    <property name="sun.arch.data.model" value="64"/>
-    <property name="java.vendor.url" value="https://goto.google.com/java-platform"/>
-    <property name="user.timezone" value=""/>
-    <property name="java.vm.specification.version" value="11"/>
-    <property name="os.name" value="Linux"/>
-    <property name="sun.java.launcher" value="SUN_STANDARD"/>
-    <property name="user.country" value="US"/>
-    <property name="sun.boot.library.path" value="/usr/local/buildtools/java/jdk11/lib"/>
-    <property name="sun.java.command" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/surefire/surefirebooter15572213431693199165.jar /usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/surefire 2021-03-30T17-04-20_597-jvmRun1 surefire6258591630934235673tmp surefire_010158085988164019591tmp"/>
-    <property name="jdk.debug" value="release"/>
-    <property name="surefire.test.class.path" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/test-classes:/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/classes:/usr/local/google/home/deannagarcia/.m2/repository/junit/junit/4.13.2/junit-4.13.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymock/2.2/easymock-2.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymockclassextension/2.2.1/easymockclassextension-2.2.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava/30.1-android/guava-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/errorprone/error_prone_annotations/2.3.4/error_prone_annotations-2.3.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava-testlib/30.1-android/guava-testlib-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/truth/truth/1.1.2/truth-1.1.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-qual/3.9.1/checker-qual-3.9.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/auto/value/auto-value-annotations/1.7.4/auto-value-annotations-1.7.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/ow2/asm/asm/9.0/asm-9.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.4.31/kotlin-stdlib-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-common/1.4.31/kotlin-stdlib-common-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/annotations/13.0/annotations-13.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test/1.4.31/kotlin-test-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test-common/1.4.31/kotlin-test-common-1.4.31.jar:"/>
-    <property name="sun.cpu.endian" value="little"/>
-    <property name="user.home" value="/usr/local/google/home/deannagarcia"/>
-    <property name="user.language" value="en"/>
-    <property name="java.specification.vendor" value="Oracle Corporation"/>
-    <property name="java.version.date" value="2021-03-16"/>
-    <property name="java.home" value="/usr/local/buildtools/java/jdk11"/>
-    <property name="file.separator" value="/"/>
-    <property name="basedir" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite"/>
-    <property name="java.vm.compressedOopsMode" value="Zero based"/>
-    <property name="line.separator" value="&#10;"/>
-    <property name="java.specification.name" value="Java Platform API Specification"/>
-    <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
-    <property name="java.awt.graphicsenv" value="sun.awt.X11GraphicsEnvironment"/>
-    <property name="surefire.real.class.path" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/surefire/surefirebooter15572213431693199165.jar"/>
-    <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
-    <property name="java.runtime.version" value="11.0.10+9-google-release-363282249"/>
-    <property name="user.name" value="deannagarcia"/>
-    <property name="path.separator" value=":"/>
-    <property name="os.version" value="5.7.17-1rodete5-amd64"/>
-    <property name="java.runtime.name" value="OpenJDK Runtime Environment"/>
-    <property name="file.encoding" value="UTF-8"/>
-    <property name="java.vm.name" value="OpenJDK 64-Bit Server VM"/>
-    <property name="localRepository" value="/usr/local/google/home/deannagarcia/.m2/repository"/>
-    <property name="java.vendor.url.bug" value="http://b.corp.google.com/createIssue?component=32554"/>
-    <property name="java.io.tmpdir" value="/tmp"/>
-    <property name="java.version" value="11.0.10"/>
-    <property name="user.dir" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite"/>
-    <property name="os.arch" value="amd64"/>
-    <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
-    <property name="java.awt.printerjob" value="sun.print.PSPrinterJob"/>
-    <property name="sun.os.patch.level" value="unknown"/>
-    <property name="java.library.path" value="/usr/lib/mesa-diverted/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu/mesa:/usr/lib/x86_64-linux-gnu/dri:/usr/lib/x86_64-linux-gnu/gallium-pipe:/usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib"/>
-    <property name="java.vm.info" value="mixed mode, sharing"/>
-    <property name="java.vendor" value="Google Inc."/>
-    <property name="java.vm.version" value="11.0.10+9-google-release-363282249"/>
-    <property name="sun.io.unicode.encoding" value="UnicodeLittle"/>
-    <property name="java.class.version" value="55.0"/>
-  </properties>
-  <testcase name="dslMapValuesAreNotMutable" classname="com.google.protobuf.kotlin.DslMapTest" time="0.001"/>
-  <testcase name="dslMapEntriesAreNotEvenSecretlyMutable" classname="com.google.protobuf.kotlin.DslMapTest" time="0.007"/>
-  <testcase name="dslMapEntriesAreNotMutable" classname="com.google.protobuf.kotlin.DslMapTest" time="0.001"/>
-  <testcase name="dslMapIsNotMutable" classname="com.google.protobuf.kotlin.DslMapTest" time="0"/>
-  <testcase name="dslMapKeysIteratorIsNotEvenSecretlyMutable" classname="com.google.protobuf.kotlin.DslMapTest" time="0.001"/>
-  <testcase name="dslMapEntriesIteratorIsNotEvenSecretlyMutable" classname="com.google.protobuf.kotlin.DslMapTest" time="0"/>
-  <testcase name="dslMapKeysAreNotEvenSecretlyMutable" classname="com.google.protobuf.kotlin.DslMapTest" time="0"/>
-  <testcase name="reflectsChangesInMap" classname="com.google.protobuf.kotlin.DslMapTest" time="0.016"/>
-  <testcase name="dslMapValuesAreNotEvenSecretlyMutable" classname="com.google.protobuf.kotlin.DslMapTest" time="0.001"/>
-  <testcase name="dslMapKeysAreNotMutable" classname="com.google.protobuf.kotlin.DslMapTest" time="0"/>
-  <testcase name="equality" classname="com.google.protobuf.kotlin.DslMapTest" time="0.002"/>
-  <testcase name="dslMapEntryObjectsAreNotEvenSecretlyMutable" classname="com.google.protobuf.kotlin.DslMapTest" time="0.001"/>
-  <testcase name="dslMapValuesIteratorIsNotEvenSecretlyMutable" classname="com.google.protobuf.kotlin.DslMapTest" time="0"/>
-  <testcase name="dslMapIsNotEvenSecretlyMutable" classname="com.google.protobuf.kotlin.DslMapTest" time="0"/>
-  <testcase name="dslMapEntryObjectsAreNotMutable" classname="com.google.protobuf.kotlin.DslMapTest" time="0.001"/>
-  <testcase name="expectedToString" classname="com.google.protobuf.kotlin.DslMapTest" time="0.001"/>
-  <testcase name="matchesMap" classname="com.google.protobuf.kotlin.DslMapTest" time="0"/>
-</testsuite>
\ No newline at end of file
diff --git a/java/kotlin-lite/target/surefire-reports/TEST-com.google.protobuf.kotlin.ExtendableMessageLiteExtensionsTest.xml b/java/kotlin-lite/target/surefire-reports/TEST-com.google.protobuf.kotlin.ExtendableMessageLiteExtensionsTest.xml
deleted file mode 100644
index 4d5a460..0000000
--- a/java/kotlin-lite/target/surefire-reports/TEST-com.google.protobuf.kotlin.ExtendableMessageLiteExtensionsTest.xml
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<testsuite xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://maven.apache.org/surefire/maven-surefire-plugin/xsd/surefire-test-report-3.0.xsd" version="3.0" name="com.google.protobuf.kotlin.ExtendableMessageLiteExtensionsTest" time="0.058" tests="7" errors="0" skipped="0" failures="0">
-  <properties>
-    <property name="sun.desktop" value="gnome"/>
-    <property name="awt.toolkit" value="sun.awt.X11.XToolkit"/>
-    <property name="java.specification.version" value="11"/>
-    <property name="sun.cpu.isalist" value=""/>
-    <property name="sun.jnu.encoding" value="UTF-8"/>
-    <property name="java.class.path" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/test-classes:/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/classes:/usr/local/google/home/deannagarcia/.m2/repository/junit/junit/4.13.2/junit-4.13.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymock/2.2/easymock-2.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymockclassextension/2.2.1/easymockclassextension-2.2.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava/30.1-android/guava-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/errorprone/error_prone_annotations/2.3.4/error_prone_annotations-2.3.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava-testlib/30.1-android/guava-testlib-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/truth/truth/1.1.2/truth-1.1.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-qual/3.9.1/checker-qual-3.9.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/auto/value/auto-value-annotations/1.7.4/auto-value-annotations-1.7.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/ow2/asm/asm/9.0/asm-9.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.4.31/kotlin-stdlib-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-common/1.4.31/kotlin-stdlib-common-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/annotations/13.0/annotations-13.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test/1.4.31/kotlin-test-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test-common/1.4.31/kotlin-test-common-1.4.31.jar:"/>
-    <property name="java.vm.vendor" value="Google Inc."/>
-    <property name="sun.arch.data.model" value="64"/>
-    <property name="java.vendor.url" value="https://goto.google.com/java-platform"/>
-    <property name="user.timezone" value=""/>
-    <property name="java.vm.specification.version" value="11"/>
-    <property name="os.name" value="Linux"/>
-    <property name="sun.java.launcher" value="SUN_STANDARD"/>
-    <property name="user.country" value="US"/>
-    <property name="sun.boot.library.path" value="/usr/local/buildtools/java/jdk11/lib"/>
-    <property name="sun.java.command" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/surefire/surefirebooter15572213431693199165.jar /usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/surefire 2021-03-30T17-04-20_597-jvmRun1 surefire6258591630934235673tmp surefire_010158085988164019591tmp"/>
-    <property name="jdk.debug" value="release"/>
-    <property name="surefire.test.class.path" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/test-classes:/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/classes:/usr/local/google/home/deannagarcia/.m2/repository/junit/junit/4.13.2/junit-4.13.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymock/2.2/easymock-2.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymockclassextension/2.2.1/easymockclassextension-2.2.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava/30.1-android/guava-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/errorprone/error_prone_annotations/2.3.4/error_prone_annotations-2.3.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava-testlib/30.1-android/guava-testlib-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/truth/truth/1.1.2/truth-1.1.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-qual/3.9.1/checker-qual-3.9.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/auto/value/auto-value-annotations/1.7.4/auto-value-annotations-1.7.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/ow2/asm/asm/9.0/asm-9.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.4.31/kotlin-stdlib-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-common/1.4.31/kotlin-stdlib-common-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/annotations/13.0/annotations-13.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test/1.4.31/kotlin-test-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test-common/1.4.31/kotlin-test-common-1.4.31.jar:"/>
-    <property name="sun.cpu.endian" value="little"/>
-    <property name="user.home" value="/usr/local/google/home/deannagarcia"/>
-    <property name="user.language" value="en"/>
-    <property name="java.specification.vendor" value="Oracle Corporation"/>
-    <property name="java.version.date" value="2021-03-16"/>
-    <property name="java.home" value="/usr/local/buildtools/java/jdk11"/>
-    <property name="file.separator" value="/"/>
-    <property name="basedir" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite"/>
-    <property name="java.vm.compressedOopsMode" value="Zero based"/>
-    <property name="line.separator" value="&#10;"/>
-    <property name="java.specification.name" value="Java Platform API Specification"/>
-    <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
-    <property name="java.awt.graphicsenv" value="sun.awt.X11GraphicsEnvironment"/>
-    <property name="surefire.real.class.path" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/surefire/surefirebooter15572213431693199165.jar"/>
-    <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
-    <property name="java.runtime.version" value="11.0.10+9-google-release-363282249"/>
-    <property name="user.name" value="deannagarcia"/>
-    <property name="path.separator" value=":"/>
-    <property name="os.version" value="5.7.17-1rodete5-amd64"/>
-    <property name="java.runtime.name" value="OpenJDK Runtime Environment"/>
-    <property name="file.encoding" value="UTF-8"/>
-    <property name="java.vm.name" value="OpenJDK 64-Bit Server VM"/>
-    <property name="localRepository" value="/usr/local/google/home/deannagarcia/.m2/repository"/>
-    <property name="java.vendor.url.bug" value="http://b.corp.google.com/createIssue?component=32554"/>
-    <property name="java.io.tmpdir" value="/tmp"/>
-    <property name="java.version" value="11.0.10"/>
-    <property name="user.dir" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite"/>
-    <property name="os.arch" value="amd64"/>
-    <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
-    <property name="java.awt.printerjob" value="sun.print.PSPrinterJob"/>
-    <property name="sun.os.patch.level" value="unknown"/>
-    <property name="java.library.path" value="/usr/lib/mesa-diverted/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu/mesa:/usr/lib/x86_64-linux-gnu/dri:/usr/lib/x86_64-linux-gnu/gallium-pipe:/usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib"/>
-    <property name="java.vm.info" value="mixed mode, sharing"/>
-    <property name="java.vendor" value="Google Inc."/>
-    <property name="java.vm.version" value="11.0.10+9-google-release-363282249"/>
-    <property name="sun.io.unicode.encoding" value="UnicodeLittle"/>
-    <property name="java.class.version" value="55.0"/>
-  </properties>
-  <testcase name="getOnMessage" classname="com.google.protobuf.kotlin.ExtendableMessageLiteExtensionsTest" time="0.05"/>
-  <testcase name="setOnBuilder" classname="com.google.protobuf.kotlin.ExtendableMessageLiteExtensionsTest" time="0.001"/>
-  <testcase name="containsPositiveOnBuilder" classname="com.google.protobuf.kotlin.ExtendableMessageLiteExtensionsTest" time="0"/>
-  <testcase name="containsPositiveOnMessage" classname="com.google.protobuf.kotlin.ExtendableMessageLiteExtensionsTest" time="0"/>
-  <testcase name="containsNegativeOnBuilder" classname="com.google.protobuf.kotlin.ExtendableMessageLiteExtensionsTest" time="0"/>
-  <testcase name="containsNegativeOnMessage" classname="com.google.protobuf.kotlin.ExtendableMessageLiteExtensionsTest" time="0"/>
-  <testcase name="getOnBuilder" classname="com.google.protobuf.kotlin.ExtendableMessageLiteExtensionsTest" time="0"/>
-</testsuite>
\ No newline at end of file
diff --git a/java/kotlin-lite/target/surefire-reports/TEST-com.google.protobuf.kotlin.ExtensionListTest.xml b/java/kotlin-lite/target/surefire-reports/TEST-com.google.protobuf.kotlin.ExtensionListTest.xml
deleted file mode 100644
index 688d323..0000000
--- a/java/kotlin-lite/target/surefire-reports/TEST-com.google.protobuf.kotlin.ExtensionListTest.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<testsuite xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://maven.apache.org/surefire/maven-surefire-plugin/xsd/surefire-test-report-3.0.xsd" version="3.0" name="com.google.protobuf.kotlin.ExtensionListTest" time="0.009" tests="9" errors="0" skipped="0" failures="0">
-  <properties>
-    <property name="sun.desktop" value="gnome"/>
-    <property name="awt.toolkit" value="sun.awt.X11.XToolkit"/>
-    <property name="java.specification.version" value="11"/>
-    <property name="sun.cpu.isalist" value=""/>
-    <property name="sun.jnu.encoding" value="UTF-8"/>
-    <property name="java.class.path" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/test-classes:/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/classes:/usr/local/google/home/deannagarcia/.m2/repository/junit/junit/4.13.2/junit-4.13.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymock/2.2/easymock-2.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymockclassextension/2.2.1/easymockclassextension-2.2.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava/30.1-android/guava-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/errorprone/error_prone_annotations/2.3.4/error_prone_annotations-2.3.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava-testlib/30.1-android/guava-testlib-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/truth/truth/1.1.2/truth-1.1.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-qual/3.9.1/checker-qual-3.9.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/auto/value/auto-value-annotations/1.7.4/auto-value-annotations-1.7.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/ow2/asm/asm/9.0/asm-9.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.4.31/kotlin-stdlib-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-common/1.4.31/kotlin-stdlib-common-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/annotations/13.0/annotations-13.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test/1.4.31/kotlin-test-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test-common/1.4.31/kotlin-test-common-1.4.31.jar:"/>
-    <property name="java.vm.vendor" value="Google Inc."/>
-    <property name="sun.arch.data.model" value="64"/>
-    <property name="java.vendor.url" value="https://goto.google.com/java-platform"/>
-    <property name="user.timezone" value=""/>
-    <property name="java.vm.specification.version" value="11"/>
-    <property name="os.name" value="Linux"/>
-    <property name="sun.java.launcher" value="SUN_STANDARD"/>
-    <property name="user.country" value="US"/>
-    <property name="sun.boot.library.path" value="/usr/local/buildtools/java/jdk11/lib"/>
-    <property name="sun.java.command" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/surefire/surefirebooter15572213431693199165.jar /usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/surefire 2021-03-30T17-04-20_597-jvmRun1 surefire6258591630934235673tmp surefire_010158085988164019591tmp"/>
-    <property name="jdk.debug" value="release"/>
-    <property name="surefire.test.class.path" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/test-classes:/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/classes:/usr/local/google/home/deannagarcia/.m2/repository/junit/junit/4.13.2/junit-4.13.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymock/2.2/easymock-2.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymockclassextension/2.2.1/easymockclassextension-2.2.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava/30.1-android/guava-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/errorprone/error_prone_annotations/2.3.4/error_prone_annotations-2.3.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava-testlib/30.1-android/guava-testlib-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/truth/truth/1.1.2/truth-1.1.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-qual/3.9.1/checker-qual-3.9.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/auto/value/auto-value-annotations/1.7.4/auto-value-annotations-1.7.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/ow2/asm/asm/9.0/asm-9.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.4.31/kotlin-stdlib-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-common/1.4.31/kotlin-stdlib-common-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/annotations/13.0/annotations-13.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test/1.4.31/kotlin-test-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test-common/1.4.31/kotlin-test-common-1.4.31.jar:"/>
-    <property name="sun.cpu.endian" value="little"/>
-    <property name="user.home" value="/usr/local/google/home/deannagarcia"/>
-    <property name="user.language" value="en"/>
-    <property name="java.specification.vendor" value="Oracle Corporation"/>
-    <property name="java.version.date" value="2021-03-16"/>
-    <property name="java.home" value="/usr/local/buildtools/java/jdk11"/>
-    <property name="file.separator" value="/"/>
-    <property name="basedir" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite"/>
-    <property name="java.vm.compressedOopsMode" value="Zero based"/>
-    <property name="line.separator" value="&#10;"/>
-    <property name="java.specification.name" value="Java Platform API Specification"/>
-    <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
-    <property name="java.awt.graphicsenv" value="sun.awt.X11GraphicsEnvironment"/>
-    <property name="surefire.real.class.path" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/surefire/surefirebooter15572213431693199165.jar"/>
-    <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
-    <property name="java.runtime.version" value="11.0.10+9-google-release-363282249"/>
-    <property name="user.name" value="deannagarcia"/>
-    <property name="path.separator" value=":"/>
-    <property name="os.version" value="5.7.17-1rodete5-amd64"/>
-    <property name="java.runtime.name" value="OpenJDK Runtime Environment"/>
-    <property name="file.encoding" value="UTF-8"/>
-    <property name="java.vm.name" value="OpenJDK 64-Bit Server VM"/>
-    <property name="localRepository" value="/usr/local/google/home/deannagarcia/.m2/repository"/>
-    <property name="java.vendor.url.bug" value="http://b.corp.google.com/createIssue?component=32554"/>
-    <property name="java.io.tmpdir" value="/tmp"/>
-    <property name="java.version" value="11.0.10"/>
-    <property name="user.dir" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite"/>
-    <property name="os.arch" value="amd64"/>
-    <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
-    <property name="java.awt.printerjob" value="sun.print.PSPrinterJob"/>
-    <property name="sun.os.patch.level" value="unknown"/>
-    <property name="java.library.path" value="/usr/lib/mesa-diverted/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu/mesa:/usr/lib/x86_64-linux-gnu/dri:/usr/lib/x86_64-linux-gnu/gallium-pipe:/usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib"/>
-    <property name="java.vm.info" value="mixed mode, sharing"/>
-    <property name="java.vendor" value="Google Inc."/>
-    <property name="java.vm.version" value="11.0.10+9-google-release-363282249"/>
-    <property name="sun.io.unicode.encoding" value="UnicodeLittle"/>
-    <property name="java.class.version" value="55.0"/>
-  </properties>
-  <testcase name="matchesList" classname="com.google.protobuf.kotlin.ExtensionListTest" time="0"/>
-  <testcase name="extensionList_IteratorIsNotEvenSecretlyMutable" classname="com.google.protobuf.kotlin.ExtensionListTest" time="0"/>
-  <testcase name="extensionListIsNotMutable" classname="com.google.protobuf.kotlin.ExtensionListTest" time="0"/>
-  <testcase name="extensionList_ListIteratorIsNotEvenSecretlyMutable" classname="com.google.protobuf.kotlin.ExtensionListTest" time="0"/>
-  <testcase name="extensionListIsNotEvenSecretlyMutable" classname="com.google.protobuf.kotlin.ExtensionListTest" time="0"/>
-  <testcase name="reflectsChangesInList" classname="com.google.protobuf.kotlin.ExtensionListTest" time="0"/>
-  <testcase name="equality" classname="com.google.protobuf.kotlin.ExtensionListTest" time="0"/>
-  <testcase name="extensionList_ListIteratorIndexIsNotEvenSecretlyMutable" classname="com.google.protobuf.kotlin.ExtensionListTest" time="0"/>
-  <testcase name="expectedToString" classname="com.google.protobuf.kotlin.ExtensionListTest" time="0"/>
-</testsuite>
\ No newline at end of file
diff --git a/java/kotlin-lite/target/surefire-reports/TEST-com.google.protobuf.kotlin.Proto2LiteTest.xml b/java/kotlin-lite/target/surefire-reports/TEST-com.google.protobuf.kotlin.Proto2LiteTest.xml
deleted file mode 100644
index 2609f64..0000000
--- a/java/kotlin-lite/target/surefire-reports/TEST-com.google.protobuf.kotlin.Proto2LiteTest.xml
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<testsuite xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://maven.apache.org/surefire/maven-surefire-plugin/xsd/surefire-test-report-3.0.xsd" version="3.0" name="com.google.protobuf.kotlin.Proto2LiteTest" time="0.113" tests="22" errors="0" skipped="0" failures="0">
-  <properties>
-    <property name="sun.desktop" value="gnome"/>
-    <property name="awt.toolkit" value="sun.awt.X11.XToolkit"/>
-    <property name="java.specification.version" value="11"/>
-    <property name="sun.cpu.isalist" value=""/>
-    <property name="sun.jnu.encoding" value="UTF-8"/>
-    <property name="java.class.path" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/test-classes:/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/classes:/usr/local/google/home/deannagarcia/.m2/repository/junit/junit/4.13.2/junit-4.13.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymock/2.2/easymock-2.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymockclassextension/2.2.1/easymockclassextension-2.2.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava/30.1-android/guava-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/errorprone/error_prone_annotations/2.3.4/error_prone_annotations-2.3.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava-testlib/30.1-android/guava-testlib-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/truth/truth/1.1.2/truth-1.1.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-qual/3.9.1/checker-qual-3.9.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/auto/value/auto-value-annotations/1.7.4/auto-value-annotations-1.7.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/ow2/asm/asm/9.0/asm-9.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.4.31/kotlin-stdlib-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-common/1.4.31/kotlin-stdlib-common-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/annotations/13.0/annotations-13.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test/1.4.31/kotlin-test-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test-common/1.4.31/kotlin-test-common-1.4.31.jar:"/>
-    <property name="java.vm.vendor" value="Google Inc."/>
-    <property name="sun.arch.data.model" value="64"/>
-    <property name="java.vendor.url" value="https://goto.google.com/java-platform"/>
-    <property name="user.timezone" value=""/>
-    <property name="java.vm.specification.version" value="11"/>
-    <property name="os.name" value="Linux"/>
-    <property name="sun.java.launcher" value="SUN_STANDARD"/>
-    <property name="user.country" value="US"/>
-    <property name="sun.boot.library.path" value="/usr/local/buildtools/java/jdk11/lib"/>
-    <property name="sun.java.command" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/surefire/surefirebooter15572213431693199165.jar /usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/surefire 2021-03-30T17-04-20_597-jvmRun1 surefire6258591630934235673tmp surefire_010158085988164019591tmp"/>
-    <property name="jdk.debug" value="release"/>
-    <property name="surefire.test.class.path" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/test-classes:/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/classes:/usr/local/google/home/deannagarcia/.m2/repository/junit/junit/4.13.2/junit-4.13.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymock/2.2/easymock-2.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymockclassextension/2.2.1/easymockclassextension-2.2.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava/30.1-android/guava-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/errorprone/error_prone_annotations/2.3.4/error_prone_annotations-2.3.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava-testlib/30.1-android/guava-testlib-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/truth/truth/1.1.2/truth-1.1.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-qual/3.9.1/checker-qual-3.9.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/auto/value/auto-value-annotations/1.7.4/auto-value-annotations-1.7.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/ow2/asm/asm/9.0/asm-9.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.4.31/kotlin-stdlib-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-common/1.4.31/kotlin-stdlib-common-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/annotations/13.0/annotations-13.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test/1.4.31/kotlin-test-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test-common/1.4.31/kotlin-test-common-1.4.31.jar:"/>
-    <property name="sun.cpu.endian" value="little"/>
-    <property name="user.home" value="/usr/local/google/home/deannagarcia"/>
-    <property name="user.language" value="en"/>
-    <property name="java.specification.vendor" value="Oracle Corporation"/>
-    <property name="java.version.date" value="2021-03-16"/>
-    <property name="java.home" value="/usr/local/buildtools/java/jdk11"/>
-    <property name="file.separator" value="/"/>
-    <property name="basedir" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite"/>
-    <property name="java.vm.compressedOopsMode" value="Zero based"/>
-    <property name="line.separator" value="&#10;"/>
-    <property name="java.specification.name" value="Java Platform API Specification"/>
-    <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
-    <property name="java.awt.graphicsenv" value="sun.awt.X11GraphicsEnvironment"/>
-    <property name="surefire.real.class.path" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/surefire/surefirebooter15572213431693199165.jar"/>
-    <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
-    <property name="java.runtime.version" value="11.0.10+9-google-release-363282249"/>
-    <property name="user.name" value="deannagarcia"/>
-    <property name="path.separator" value=":"/>
-    <property name="os.version" value="5.7.17-1rodete5-amd64"/>
-    <property name="java.runtime.name" value="OpenJDK Runtime Environment"/>
-    <property name="file.encoding" value="UTF-8"/>
-    <property name="java.vm.name" value="OpenJDK 64-Bit Server VM"/>
-    <property name="localRepository" value="/usr/local/google/home/deannagarcia/.m2/repository"/>
-    <property name="java.vendor.url.bug" value="http://b.corp.google.com/createIssue?component=32554"/>
-    <property name="java.io.tmpdir" value="/tmp"/>
-    <property name="java.version" value="11.0.10"/>
-    <property name="user.dir" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite"/>
-    <property name="os.arch" value="amd64"/>
-    <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
-    <property name="java.awt.printerjob" value="sun.print.PSPrinterJob"/>
-    <property name="sun.os.patch.level" value="unknown"/>
-    <property name="java.library.path" value="/usr/lib/mesa-diverted/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu/mesa:/usr/lib/x86_64-linux-gnu/dri:/usr/lib/x86_64-linux-gnu/gallium-pipe:/usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib"/>
-    <property name="java.vm.info" value="mixed mode, sharing"/>
-    <property name="java.vendor" value="Google Inc."/>
-    <property name="java.vm.version" value="11.0.10+9-google-release-363282249"/>
-    <property name="sun.io.unicode.encoding" value="UnicodeLittle"/>
-    <property name="java.class.version" value="55.0"/>
-  </properties>
-  <testcase name="testEmptyMessages" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0.009"/>
-  <testcase name="testOneof" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0.023"/>
-  <testcase name="testCopy" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0.001"/>
-  <testcase name="testHardKeywordHazzers" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0.016"/>
-  <testcase name="testExtensionsSet" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0.015"/>
-  <testcase name="testGetters" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0.001"/>
-  <testcase name="testEvilNames" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0.009"/>
-  <testcase name="testExtensionGetters" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0"/>
-  <testcase name="testHazzers" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0"/>
-  <testcase name="testRepeatedExtensionGettersAndSetters" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0.001"/>
-  <testcase name="testDefaultGetters" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0"/>
-  <testcase name="testExtensionClears" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0"/>
-  <testcase name="testMapGettersAndSetters" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0.015"/>
-  <testcase name="testMapClear" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0"/>
-  <testcase name="testHardKeywordGettersAndSetters" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0.001"/>
-  <testcase name="testRepeatedGettersAndSetters" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0.01"/>
-  <testcase name="testClears" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0.001"/>
-  <testcase name="testMapSetters" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0"/>
-  <testcase name="testMapRemove" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0"/>
-  <testcase name="testSetters" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0.002"/>
-  <testcase name="testExtensionContains" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0"/>
-  <testcase name="testHardKeywordClears" classname="com.google.protobuf.kotlin.Proto2LiteTest" time="0"/>
-</testsuite>
\ No newline at end of file
diff --git a/java/kotlin-lite/target/surefire-reports/TEST-com.google.protobuf.kotlin.Proto3Test.xml b/java/kotlin-lite/target/surefire-reports/TEST-com.google.protobuf.kotlin.Proto3Test.xml
deleted file mode 100644
index 0c38286..0000000
--- a/java/kotlin-lite/target/surefire-reports/TEST-com.google.protobuf.kotlin.Proto3Test.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<testsuite xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://maven.apache.org/surefire/maven-surefire-plugin/xsd/surefire-test-report-3.0.xsd" version="3.0" name="com.google.protobuf.kotlin.Proto3Test" time="0.053" tests="11" errors="0" skipped="0" failures="0">
-  <properties>
-    <property name="sun.desktop" value="gnome"/>
-    <property name="awt.toolkit" value="sun.awt.X11.XToolkit"/>
-    <property name="java.specification.version" value="11"/>
-    <property name="sun.cpu.isalist" value=""/>
-    <property name="sun.jnu.encoding" value="UTF-8"/>
-    <property name="java.class.path" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/test-classes:/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/classes:/usr/local/google/home/deannagarcia/.m2/repository/junit/junit/4.13.2/junit-4.13.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymock/2.2/easymock-2.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymockclassextension/2.2.1/easymockclassextension-2.2.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava/30.1-android/guava-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/errorprone/error_prone_annotations/2.3.4/error_prone_annotations-2.3.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava-testlib/30.1-android/guava-testlib-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/truth/truth/1.1.2/truth-1.1.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-qual/3.9.1/checker-qual-3.9.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/auto/value/auto-value-annotations/1.7.4/auto-value-annotations-1.7.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/ow2/asm/asm/9.0/asm-9.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.4.31/kotlin-stdlib-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-common/1.4.31/kotlin-stdlib-common-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/annotations/13.0/annotations-13.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test/1.4.31/kotlin-test-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test-common/1.4.31/kotlin-test-common-1.4.31.jar:"/>
-    <property name="java.vm.vendor" value="Google Inc."/>
-    <property name="sun.arch.data.model" value="64"/>
-    <property name="java.vendor.url" value="https://goto.google.com/java-platform"/>
-    <property name="user.timezone" value=""/>
-    <property name="java.vm.specification.version" value="11"/>
-    <property name="os.name" value="Linux"/>
-    <property name="sun.java.launcher" value="SUN_STANDARD"/>
-    <property name="user.country" value="US"/>
-    <property name="sun.boot.library.path" value="/usr/local/buildtools/java/jdk11/lib"/>
-    <property name="sun.java.command" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/surefire/surefirebooter15572213431693199165.jar /usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/surefire 2021-03-30T17-04-20_597-jvmRun1 surefire6258591630934235673tmp surefire_010158085988164019591tmp"/>
-    <property name="jdk.debug" value="release"/>
-    <property name="surefire.test.class.path" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/test-classes:/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/classes:/usr/local/google/home/deannagarcia/.m2/repository/junit/junit/4.13.2/junit-4.13.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymock/2.2/easymock-2.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/easymock/easymockclassextension/2.2.1/easymockclassextension-2.2.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava/30.1-android/guava-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/errorprone/error_prone_annotations/2.3.4/error_prone_annotations-2.3.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/guava/guava-testlib/30.1-android/guava-testlib-30.1-android.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/truth/truth/1.1.2/truth-1.1.2.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/checkerframework/checker-qual/3.9.1/checker-qual-3.9.1.jar:/usr/local/google/home/deannagarcia/.m2/repository/com/google/auto/value/auto-value-annotations/1.7.4/auto-value-annotations-1.7.4.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/ow2/asm/asm/9.0/asm-9.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.4.31/kotlin-stdlib-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-common/1.4.31/kotlin-stdlib-common-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/annotations/13.0/annotations-13.0.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test/1.4.31/kotlin-test-1.4.31.jar:/usr/local/google/home/deannagarcia/.m2/repository/org/jetbrains/kotlin/kotlin-test-common/1.4.31/kotlin-test-common-1.4.31.jar:"/>
-    <property name="sun.cpu.endian" value="little"/>
-    <property name="user.home" value="/usr/local/google/home/deannagarcia"/>
-    <property name="user.language" value="en"/>
-    <property name="java.specification.vendor" value="Oracle Corporation"/>
-    <property name="java.version.date" value="2021-03-16"/>
-    <property name="java.home" value="/usr/local/buildtools/java/jdk11"/>
-    <property name="file.separator" value="/"/>
-    <property name="basedir" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite"/>
-    <property name="java.vm.compressedOopsMode" value="Zero based"/>
-    <property name="line.separator" value="&#10;"/>
-    <property name="java.specification.name" value="Java Platform API Specification"/>
-    <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
-    <property name="java.awt.graphicsenv" value="sun.awt.X11GraphicsEnvironment"/>
-    <property name="surefire.real.class.path" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite/target/surefire/surefirebooter15572213431693199165.jar"/>
-    <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
-    <property name="java.runtime.version" value="11.0.10+9-google-release-363282249"/>
-    <property name="user.name" value="deannagarcia"/>
-    <property name="path.separator" value=":"/>
-    <property name="os.version" value="5.7.17-1rodete5-amd64"/>
-    <property name="java.runtime.name" value="OpenJDK Runtime Environment"/>
-    <property name="file.encoding" value="UTF-8"/>
-    <property name="java.vm.name" value="OpenJDK 64-Bit Server VM"/>
-    <property name="localRepository" value="/usr/local/google/home/deannagarcia/.m2/repository"/>
-    <property name="java.vendor.url.bug" value="http://b.corp.google.com/createIssue?component=32554"/>
-    <property name="java.io.tmpdir" value="/tmp"/>
-    <property name="java.version" value="11.0.10"/>
-    <property name="user.dir" value="/usr/local/google/home/deannagarcia/protobuf/java/kotlin-lite"/>
-    <property name="os.arch" value="amd64"/>
-    <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
-    <property name="java.awt.printerjob" value="sun.print.PSPrinterJob"/>
-    <property name="sun.os.patch.level" value="unknown"/>
-    <property name="java.library.path" value="/usr/lib/mesa-diverted/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu/mesa:/usr/lib/x86_64-linux-gnu/dri:/usr/lib/x86_64-linux-gnu/gallium-pipe:/usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib"/>
-    <property name="java.vm.info" value="mixed mode, sharing"/>
-    <property name="java.vendor" value="Google Inc."/>
-    <property name="java.vm.version" value="11.0.10+9-google-release-363282249"/>
-    <property name="sun.io.unicode.encoding" value="UnicodeLittle"/>
-    <property name="java.class.version" value="55.0"/>
-  </properties>
-  <testcase name="testGettersAndSetters" classname="com.google.protobuf.kotlin.Proto3Test" time="0.011"/>
-  <testcase name="testEmptyMessages" classname="com.google.protobuf.kotlin.Proto3Test" time="0.002"/>
-  <testcase name="testOneof" classname="com.google.protobuf.kotlin.Proto3Test" time="0"/>
-  <testcase name="testCopy" classname="com.google.protobuf.kotlin.Proto3Test" time="0.001"/>
-  <testcase name="testHardKeywordHazzers" classname="com.google.protobuf.kotlin.Proto3Test" time="0.016"/>
-  <testcase name="testEvilNames" classname="com.google.protobuf.kotlin.Proto3Test" time="0.014"/>
-  <testcase name="testHardKeywordGettersAndSetters" classname="com.google.protobuf.kotlin.Proto3Test" time="0"/>
-  <testcase name="testRepeatedGettersAndSetters" classname="com.google.protobuf.kotlin.Proto3Test" time="0.001"/>
-  <testcase name="testMultipleFiles" classname="com.google.protobuf.kotlin.Proto3Test" time="0.004"/>
-  <testcase name="testClears" classname="com.google.protobuf.kotlin.Proto3Test" time="0"/>
-  <testcase name="testHardKeywordClears" classname="com.google.protobuf.kotlin.Proto3Test" time="0"/>
-</testsuite>
\ No newline at end of file
diff --git a/java/kotlin-lite/target/surefire-reports/com.google.protobuf.kotlin.DslListTest.txt b/java/kotlin-lite/target/surefire-reports/com.google.protobuf.kotlin.DslListTest.txt
deleted file mode 100644
index 4f83e00..0000000
--- a/java/kotlin-lite/target/surefire-reports/com.google.protobuf.kotlin.DslListTest.txt
+++ /dev/null
@@ -1,4 +0,0 @@
--------------------------------------------------------------------------------
-Test set: com.google.protobuf.kotlin.DslListTest
--------------------------------------------------------------------------------
-Tests run: 9, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.209 s - in com.google.protobuf.kotlin.DslListTest
diff --git a/java/kotlin-lite/target/surefire-reports/com.google.protobuf.kotlin.DslMapTest.txt b/java/kotlin-lite/target/surefire-reports/com.google.protobuf.kotlin.DslMapTest.txt
deleted file mode 100644
index bf712a8..0000000
--- a/java/kotlin-lite/target/surefire-reports/com.google.protobuf.kotlin.DslMapTest.txt
+++ /dev/null
@@ -1,4 +0,0 @@
--------------------------------------------------------------------------------
-Test set: com.google.protobuf.kotlin.DslMapTest
--------------------------------------------------------------------------------
-Tests run: 17, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.051 s - in com.google.protobuf.kotlin.DslMapTest
diff --git a/java/kotlin-lite/target/surefire-reports/com.google.protobuf.kotlin.ExtendableMessageLiteExtensionsTest.txt b/java/kotlin-lite/target/surefire-reports/com.google.protobuf.kotlin.ExtendableMessageLiteExtensionsTest.txt
deleted file mode 100644
index 972d3d8..0000000
--- a/java/kotlin-lite/target/surefire-reports/com.google.protobuf.kotlin.ExtendableMessageLiteExtensionsTest.txt
+++ /dev/null
@@ -1,4 +0,0 @@
--------------------------------------------------------------------------------
-Test set: com.google.protobuf.kotlin.ExtendableMessageLiteExtensionsTest
--------------------------------------------------------------------------------
-Tests run: 7, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.058 s - in com.google.protobuf.kotlin.ExtendableMessageLiteExtensionsTest
diff --git a/java/kotlin-lite/target/surefire-reports/com.google.protobuf.kotlin.ExtensionListTest.txt b/java/kotlin-lite/target/surefire-reports/com.google.protobuf.kotlin.ExtensionListTest.txt
deleted file mode 100644
index 4a9f703..0000000
--- a/java/kotlin-lite/target/surefire-reports/com.google.protobuf.kotlin.ExtensionListTest.txt
+++ /dev/null
@@ -1,4 +0,0 @@
--------------------------------------------------------------------------------
-Test set: com.google.protobuf.kotlin.ExtensionListTest
--------------------------------------------------------------------------------
-Tests run: 9, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.009 s - in com.google.protobuf.kotlin.ExtensionListTest
diff --git a/java/kotlin-lite/target/surefire-reports/com.google.protobuf.kotlin.Proto2LiteTest.txt b/java/kotlin-lite/target/surefire-reports/com.google.protobuf.kotlin.Proto2LiteTest.txt
deleted file mode 100644
index 3c70da7..0000000
--- a/java/kotlin-lite/target/surefire-reports/com.google.protobuf.kotlin.Proto2LiteTest.txt
+++ /dev/null
@@ -1,4 +0,0 @@
--------------------------------------------------------------------------------
-Test set: com.google.protobuf.kotlin.Proto2LiteTest
--------------------------------------------------------------------------------
-Tests run: 22, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.113 s - in com.google.protobuf.kotlin.Proto2LiteTest
diff --git a/java/kotlin-lite/target/surefire-reports/com.google.protobuf.kotlin.Proto3Test.txt b/java/kotlin-lite/target/surefire-reports/com.google.protobuf.kotlin.Proto3Test.txt
deleted file mode 100644
index 838ee70..0000000
--- a/java/kotlin-lite/target/surefire-reports/com.google.protobuf.kotlin.Proto3Test.txt
+++ /dev/null
@@ -1,4 +0,0 @@
--------------------------------------------------------------------------------
-Test set: com.google.protobuf.kotlin.Proto3Test
--------------------------------------------------------------------------------
-Tests run: 11, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.053 s - in com.google.protobuf.kotlin.Proto3Test
diff --git a/java/kotlin-lite/target/test-classes/META-INF/protobuf-javalite.kotlin_module b/java/kotlin-lite/target/test-classes/META-INF/protobuf-javalite.kotlin_module
deleted file mode 100644
index 5be5d4d..0000000
--- a/java/kotlin-lite/target/test-classes/META-INF/protobuf-javalite.kotlin_module
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/DupEnumKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/DupEnumKt$Dsl$Companion.class
deleted file mode 100644
index e830593..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/DupEnumKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/DupEnumKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/DupEnumKt$Dsl.class
deleted file mode 100644
index a875929..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/DupEnumKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/DupEnumKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/DupEnumKt.class
deleted file mode 100644
index 0830121..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/DupEnumKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/DupEnumKtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/DupEnumKtKt.class
deleted file mode 100644
index 06e4f5a..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/DupEnumKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/ForeignMessageLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/ForeignMessageLiteKt$Dsl$Companion.class
deleted file mode 100644
index 983b1ce..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/ForeignMessageLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/ForeignMessageLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/ForeignMessageLiteKt$Dsl.class
deleted file mode 100644
index 1a04586..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/ForeignMessageLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/ForeignMessageLiteKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/ForeignMessageLiteKt.class
deleted file mode 100644
index 7d767e0..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/ForeignMessageLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/ForeignMessageLiteKtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/ForeignMessageLiteKtKt.class
deleted file mode 100644
index c55337e..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/ForeignMessageLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedFixed32Kt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedFixed32Kt$Dsl$Companion.class
deleted file mode 100644
index f6d38ea..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedFixed32Kt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedFixed32Kt$Dsl$RepeatedFixed32Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedFixed32Kt$Dsl$RepeatedFixed32Proxy.class
deleted file mode 100644
index 86b0809..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedFixed32Kt$Dsl$RepeatedFixed32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedFixed32Kt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedFixed32Kt$Dsl.class
deleted file mode 100644
index e31ec7f..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedFixed32Kt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedFixed32Kt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedFixed32Kt.class
deleted file mode 100644
index d8846f4..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedFixed32Kt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedFixed32KtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedFixed32KtKt.class
deleted file mode 100644
index ba94fa1..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedFixed32KtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedInt32Kt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedInt32Kt$Dsl$Companion.class
deleted file mode 100644
index 399f7bd..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedInt32Kt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedInt32Kt$Dsl$RepeatedInt32Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedInt32Kt$Dsl$RepeatedInt32Proxy.class
deleted file mode 100644
index db1ec52..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedInt32Kt$Dsl$RepeatedInt32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedInt32Kt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedInt32Kt$Dsl.class
deleted file mode 100644
index 488ecc2..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedInt32Kt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedInt32Kt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedInt32Kt.class
deleted file mode 100644
index e0525fb..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedInt32Kt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedInt32KtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedInt32KtKt.class
deleted file mode 100644
index 3a9b02a..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/NonPackedInt32KtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/OptionalGroup_extension_liteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/OptionalGroup_extension_liteKt$Dsl$Companion.class
deleted file mode 100644
index ec1eed3..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/OptionalGroup_extension_liteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/OptionalGroup_extension_liteKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/OptionalGroup_extension_liteKt$Dsl.class
deleted file mode 100644
index c43cb30..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/OptionalGroup_extension_liteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/OptionalGroup_extension_liteKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/OptionalGroup_extension_liteKt.class
deleted file mode 100644
index 430090a..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/OptionalGroup_extension_liteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/OptionalGroup_extension_liteKtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/OptionalGroup_extension_liteKtKt.class
deleted file mode 100644
index 0881639..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/OptionalGroup_extension_liteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedFixed32Kt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedFixed32Kt$Dsl$Companion.class
deleted file mode 100644
index 0bbfa2a..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedFixed32Kt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedFixed32Kt$Dsl$RepeatedFixed32Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedFixed32Kt$Dsl$RepeatedFixed32Proxy.class
deleted file mode 100644
index 5318d80..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedFixed32Kt$Dsl$RepeatedFixed32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedFixed32Kt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedFixed32Kt$Dsl.class
deleted file mode 100644
index 7bba53b..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedFixed32Kt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedFixed32Kt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedFixed32Kt.class
deleted file mode 100644
index 5717161..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedFixed32Kt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedFixed32KtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedFixed32KtKt.class
deleted file mode 100644
index 1df1d36..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedFixed32KtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedInt32Kt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedInt32Kt$Dsl$Companion.class
deleted file mode 100644
index ea0a892..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedInt32Kt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedInt32Kt$Dsl$RepeatedInt32Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedInt32Kt$Dsl$RepeatedInt32Proxy.class
deleted file mode 100644
index 2a8e1b9..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedInt32Kt$Dsl$RepeatedInt32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedInt32Kt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedInt32Kt$Dsl.class
deleted file mode 100644
index aa0667f..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedInt32Kt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedInt32Kt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedInt32Kt.class
deleted file mode 100644
index 897c26f..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedInt32Kt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedInt32KtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedInt32KtKt.class
deleted file mode 100644
index d218c96..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/PackedInt32KtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/RecursiveMessageKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/RecursiveMessageKt$Dsl$Companion.class
deleted file mode 100644
index c2d39a2..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/RecursiveMessageKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/RecursiveMessageKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/RecursiveMessageKt$Dsl.class
deleted file mode 100644
index 5ef761f..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/RecursiveMessageKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/RecursiveMessageKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/RecursiveMessageKt.class
deleted file mode 100644
index 1559da6..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/RecursiveMessageKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/RecursiveMessageKtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/RecursiveMessageKtKt.class
deleted file mode 100644
index db36346..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/RecursiveMessageKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/RepeatedGroup_extension_liteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/RepeatedGroup_extension_liteKt$Dsl$Companion.class
deleted file mode 100644
index 393a779..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/RepeatedGroup_extension_liteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/RepeatedGroup_extension_liteKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/RepeatedGroup_extension_liteKt$Dsl.class
deleted file mode 100644
index 9276172..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/RepeatedGroup_extension_liteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/RepeatedGroup_extension_liteKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/RepeatedGroup_extension_liteKt.class
deleted file mode 100644
index 8feee33..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/RepeatedGroup_extension_liteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/RepeatedGroup_extension_liteKtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/RepeatedGroup_extension_liteKtKt.class
deleted file mode 100644
index 0935a1c..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/RepeatedGroup_extension_liteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllExtensionsLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllExtensionsLiteKt$Dsl$Companion.class
deleted file mode 100644
index dd2cf8e..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllExtensionsLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllExtensionsLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllExtensionsLiteKt$Dsl.class
deleted file mode 100644
index 176dc69..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllExtensionsLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllExtensionsLiteKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllExtensionsLiteKt.class
deleted file mode 100644
index 9d98679..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllExtensionsLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllExtensionsLiteKtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllExtensionsLiteKtKt.class
deleted file mode 100644
index 0218608..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllExtensionsLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$Companion.class
deleted file mode 100644
index 330fb65..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedBoolProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedBoolProxy.class
deleted file mode 100644
index bef7af0..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedBoolProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedBytesProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedBytesProxy.class
deleted file mode 100644
index b010e88..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedBytesProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedCordProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedCordProxy.class
deleted file mode 100644
index 47aadd3..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedCordProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedDoubleProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedDoubleProxy.class
deleted file mode 100644
index e06a32d..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedDoubleProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedFixed32Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedFixed32Proxy.class
deleted file mode 100644
index 14f1781..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedFixed32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedFixed64Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedFixed64Proxy.class
deleted file mode 100644
index 6daf65a..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedFixed64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedFloatProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedFloatProxy.class
deleted file mode 100644
index 6fff1cb..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedFloatProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedForeignEnumProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedForeignEnumProxy.class
deleted file mode 100644
index 261e722..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedForeignEnumProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedForeignMessageProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedForeignMessageProxy.class
deleted file mode 100644
index ec1f5c9..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedForeignMessageProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedGroupProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedGroupProxy.class
deleted file mode 100644
index e87b488..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedGroupProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedImportEnumProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedImportEnumProxy.class
deleted file mode 100644
index 2844822..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedImportEnumProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedImportMessageProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedImportMessageProxy.class
deleted file mode 100644
index 969422c..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedImportMessageProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedInt32Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedInt32Proxy.class
deleted file mode 100644
index 4850716..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedInt32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedInt64Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedInt64Proxy.class
deleted file mode 100644
index d1fbd53..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedInt64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedLazyMessageProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedLazyMessageProxy.class
deleted file mode 100644
index bb70d75..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedLazyMessageProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedNestedEnumProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedNestedEnumProxy.class
deleted file mode 100644
index abb681f..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedNestedEnumProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedNestedMessageProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedNestedMessageProxy.class
deleted file mode 100644
index 7b4e17a..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedNestedMessageProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedSfixed32Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedSfixed32Proxy.class
deleted file mode 100644
index a4fd748..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedSfixed32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedSfixed64Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedSfixed64Proxy.class
deleted file mode 100644
index eeab713..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedSfixed64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedSint32Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedSint32Proxy.class
deleted file mode 100644
index 1fd410f..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedSint32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedSint64Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedSint64Proxy.class
deleted file mode 100644
index 981c947..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedSint64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedStringPieceProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedStringPieceProxy.class
deleted file mode 100644
index 537bea1..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedStringPieceProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedStringProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedStringProxy.class
deleted file mode 100644
index a7982de..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedStringProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedUint32Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedUint32Proxy.class
deleted file mode 100644
index 9bd8a27..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedUint32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedUint64Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedUint64Proxy.class
deleted file mode 100644
index 9d19f73..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl$RepeatedUint64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl.class
deleted file mode 100644
index 561ca94..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$NestedMessage2Kt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$NestedMessage2Kt$Dsl$Companion.class
deleted file mode 100644
index 8aa49e1..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$NestedMessage2Kt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$NestedMessage2Kt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$NestedMessage2Kt$Dsl.class
deleted file mode 100644
index e22310f..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$NestedMessage2Kt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$NestedMessage2Kt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$NestedMessage2Kt.class
deleted file mode 100644
index 60694e6..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$NestedMessage2Kt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$NestedMessageKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$NestedMessageKt$Dsl$Companion.class
deleted file mode 100644
index 08153b7..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$NestedMessageKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$NestedMessageKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$NestedMessageKt$Dsl.class
deleted file mode 100644
index 3406347..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$NestedMessageKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$NestedMessageKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$NestedMessageKt.class
deleted file mode 100644
index 75e05a9..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$NestedMessageKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$OptionalGroupKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$OptionalGroupKt$Dsl$Companion.class
deleted file mode 100644
index 6d2acbf..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$OptionalGroupKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$OptionalGroupKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$OptionalGroupKt$Dsl.class
deleted file mode 100644
index 5253edc..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$OptionalGroupKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$OptionalGroupKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$OptionalGroupKt.class
deleted file mode 100644
index c8839c0..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$OptionalGroupKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$RepeatedGroupKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$RepeatedGroupKt$Dsl$Companion.class
deleted file mode 100644
index 9c67b36..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$RepeatedGroupKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$RepeatedGroupKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$RepeatedGroupKt$Dsl.class
deleted file mode 100644
index 58b128c..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$RepeatedGroupKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$RepeatedGroupKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$RepeatedGroupKt.class
deleted file mode 100644
index aae15a4..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt$RepeatedGroupKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt.class
deleted file mode 100644
index 3db5689..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKtKt.class
deleted file mode 100644
index 6a1dfa6..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestAllTypesLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestDeprecatedLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestDeprecatedLiteKt$Dsl$Companion.class
deleted file mode 100644
index a23f75d..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestDeprecatedLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestDeprecatedLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestDeprecatedLiteKt$Dsl.class
deleted file mode 100644
index a021e9b..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestDeprecatedLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestDeprecatedLiteKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestDeprecatedLiteKt.class
deleted file mode 100644
index 90896b8..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestDeprecatedLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestDeprecatedLiteKtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestDeprecatedLiteKtKt.class
deleted file mode 100644
index 948289f..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestDeprecatedLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageLiteKt$Dsl$Companion.class
deleted file mode 100644
index 8101240..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageLiteKt$Dsl.class
deleted file mode 100644
index cb13203..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageLiteKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageLiteKt.class
deleted file mode 100644
index bdb6bdd..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageLiteKtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageLiteKtKt.class
deleted file mode 100644
index 8c62608..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageWithExtensionsLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageWithExtensionsLiteKt$Dsl$Companion.class
deleted file mode 100644
index 84935e5..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageWithExtensionsLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageWithExtensionsLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageWithExtensionsLiteKt$Dsl.class
deleted file mode 100644
index 6154900..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageWithExtensionsLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageWithExtensionsLiteKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageWithExtensionsLiteKt.class
deleted file mode 100644
index e0d3904..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageWithExtensionsLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageWithExtensionsLiteKtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageWithExtensionsLiteKtKt.class
deleted file mode 100644
index 87a86aa..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestEmptyMessageWithExtensionsLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$Dsl$Companion.class
deleted file mode 100644
index 34904d5..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$Dsl$PackedInt32Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$Dsl$PackedInt32Proxy.class
deleted file mode 100644
index 0d95245..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$Dsl$PackedInt32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$Dsl$RepeatedInt32Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$Dsl$RepeatedInt32Proxy.class
deleted file mode 100644
index 6f9d746..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$Dsl$RepeatedInt32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$Dsl$StringStringMapProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$Dsl$StringStringMapProxy.class
deleted file mode 100644
index bf77fdb..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$Dsl$StringStringMapProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$Dsl.class
deleted file mode 100644
index 3859f0b..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$OptionalGroupKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$OptionalGroupKt$Dsl$Companion.class
deleted file mode 100644
index 24fc6af..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$OptionalGroupKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$OptionalGroupKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$OptionalGroupKt$Dsl.class
deleted file mode 100644
index a162180..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$OptionalGroupKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$OptionalGroupKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$OptionalGroupKt.class
deleted file mode 100644
index 220a2e5..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt$OptionalGroupKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt.class
deleted file mode 100644
index b214164..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKtKt.class
deleted file mode 100644
index 8d7746a..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestHugeFieldNumbersLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestNestedExtensionLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestNestedExtensionLiteKt$Dsl$Companion.class
deleted file mode 100644
index e76a266..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestNestedExtensionLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestNestedExtensionLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestNestedExtensionLiteKt$Dsl.class
deleted file mode 100644
index 2a934c0..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestNestedExtensionLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestNestedExtensionLiteKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestNestedExtensionLiteKt.class
deleted file mode 100644
index 8c14f9f..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestNestedExtensionLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestNestedExtensionLiteKtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestNestedExtensionLiteKtKt.class
deleted file mode 100644
index 906e455..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestNestedExtensionLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestOneofParsingLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestOneofParsingLiteKt$Dsl$Companion.class
deleted file mode 100644
index f7a3968..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestOneofParsingLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestOneofParsingLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestOneofParsingLiteKt$Dsl.class
deleted file mode 100644
index 366f7fc..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestOneofParsingLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestOneofParsingLiteKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestOneofParsingLiteKt.class
deleted file mode 100644
index 3355d14..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestOneofParsingLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestOneofParsingLiteKtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestOneofParsingLiteKtKt.class
deleted file mode 100644
index 120eac4..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestOneofParsingLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedExtensionsLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedExtensionsLiteKt$Dsl$Companion.class
deleted file mode 100644
index ea3be09..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedExtensionsLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedExtensionsLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedExtensionsLiteKt$Dsl.class
deleted file mode 100644
index cc372d2..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedExtensionsLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedExtensionsLiteKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedExtensionsLiteKt.class
deleted file mode 100644
index f3fb579..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedExtensionsLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedExtensionsLiteKtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedExtensionsLiteKtKt.class
deleted file mode 100644
index 566feee..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedExtensionsLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$Companion.class
deleted file mode 100644
index 435f198..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedBoolProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedBoolProxy.class
deleted file mode 100644
index 0742243..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedBoolProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedDoubleProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedDoubleProxy.class
deleted file mode 100644
index 0d194e1..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedDoubleProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedEnumProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedEnumProxy.class
deleted file mode 100644
index bcc62b0..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedEnumProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedFixed32Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedFixed32Proxy.class
deleted file mode 100644
index 44f0c32..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedFixed32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedFixed64Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedFixed64Proxy.class
deleted file mode 100644
index e89a238..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedFixed64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedFloatProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedFloatProxy.class
deleted file mode 100644
index 39b7e03..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedFloatProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedInt32Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedInt32Proxy.class
deleted file mode 100644
index fb03041..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedInt32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedInt64Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedInt64Proxy.class
deleted file mode 100644
index d2742e6..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedInt64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedSfixed32Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedSfixed32Proxy.class
deleted file mode 100644
index e145bd9..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedSfixed32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedSfixed64Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedSfixed64Proxy.class
deleted file mode 100644
index ac6935b..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedSfixed64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedSint32Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedSint32Proxy.class
deleted file mode 100644
index 4e239f7..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedSint32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedSint64Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedSint64Proxy.class
deleted file mode 100644
index 13f8766..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedSint64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedUint32Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedUint32Proxy.class
deleted file mode 100644
index 97ffeef..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedUint32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedUint64Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedUint64Proxy.class
deleted file mode 100644
index cde8db3..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl$PackedUint64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl.class
deleted file mode 100644
index 7f39a3d..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt.class
deleted file mode 100644
index c2c75d4..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKtKt.class
deleted file mode 100644
index d22df78..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestPackedTypesLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$Dsl$Companion.class
deleted file mode 100644
index d5fe70d..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$Dsl$RepeatedAllTypesProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$Dsl$RepeatedAllTypesProxy.class
deleted file mode 100644
index 80d018e..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$Dsl$RepeatedAllTypesProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$Dsl$RepeatedGroupProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$Dsl$RepeatedGroupProxy.class
deleted file mode 100644
index eb4beb1..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$Dsl$RepeatedGroupProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$Dsl.class
deleted file mode 100644
index 81ed089..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$OptionalGroupKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$OptionalGroupKt$Dsl$Companion.class
deleted file mode 100644
index 5bdbcfd..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$OptionalGroupKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$OptionalGroupKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$OptionalGroupKt$Dsl.class
deleted file mode 100644
index 3f9bbcc..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$OptionalGroupKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$OptionalGroupKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$OptionalGroupKt.class
deleted file mode 100644
index 1e207c1..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$OptionalGroupKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Companion.class
deleted file mode 100644
index 4255adb..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Ext1Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Ext1Proxy.class
deleted file mode 100644
index 3eb7ee3..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Ext1Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Ext2Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Ext2Proxy.class
deleted file mode 100644
index 693965a..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Ext2Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Field1Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Field1Proxy.class
deleted file mode 100644
index 842490c..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Field1Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Field2Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Field2Proxy.class
deleted file mode 100644
index d958af4..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Field2Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Field3Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Field3Proxy.class
deleted file mode 100644
index 08b68ac..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Field3Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Group1Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Group1Proxy.class
deleted file mode 100644
index 31ff2a3..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Group1Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Group2Proxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Group2Proxy.class
deleted file mode 100644
index 9a871db..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl$Group2Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl.class
deleted file mode 100644
index 67fa84f..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Group1Kt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Group1Kt$Dsl$Companion.class
deleted file mode 100644
index 9520a9e..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Group1Kt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Group1Kt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Group1Kt$Dsl.class
deleted file mode 100644
index 53785a1..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Group1Kt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Group1Kt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Group1Kt.class
deleted file mode 100644
index f9ad96e..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Group1Kt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Group2Kt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Group2Kt$Dsl$Companion.class
deleted file mode 100644
index cdf0dbf..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Group2Kt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Group2Kt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Group2Kt$Dsl.class
deleted file mode 100644
index d07e7c6..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Group2Kt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Group2Kt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Group2Kt.class
deleted file mode 100644
index 7eb8b03..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt$Group2Kt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt.class
deleted file mode 100644
index de01dba..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedFieldsGeneratorKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedGroupKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedGroupKt$Dsl$Companion.class
deleted file mode 100644
index b085e14..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedGroupKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedGroupKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedGroupKt$Dsl.class
deleted file mode 100644
index 0f6ed0d..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedGroupKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedGroupKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedGroupKt.class
deleted file mode 100644
index 9b7d52e..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt$RepeatedGroupKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt.class
deleted file mode 100644
index e8d0550..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKtKt.class
deleted file mode 100644
index 308039d..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestParsingMergeLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestUtil$1.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestUtil$1.class
deleted file mode 100644
index a8c17c7..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestUtil$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestUtil$TestLogHandler.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestUtil$TestLogHandler.class
deleted file mode 100644
index 8e2d614..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestUtil$TestLogHandler.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestUtil.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestUtil.class
deleted file mode 100644
index 00c37f2..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestUtil.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestUtilLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/TestUtilLite.class
deleted file mode 100644
index 46fc4cb..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/TestUtilLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$1.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$1.class
deleted file mode 100644
index 7b09ec4..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$ImportEnumLite$1.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$ImportEnumLite$1.class
deleted file mode 100644
index e48b963..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$ImportEnumLite$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$ImportEnumLite$ImportEnumLiteVerifier.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$ImportEnumLite$ImportEnumLiteVerifier.class
deleted file mode 100644
index e5146c9..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$ImportEnumLite$ImportEnumLiteVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$ImportEnumLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$ImportEnumLite.class
deleted file mode 100644
index 2076ea7..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$ImportEnumLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$ImportMessageLite$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$ImportMessageLite$Builder.class
deleted file mode 100644
index da59198..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$ImportMessageLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$ImportMessageLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$ImportMessageLite.class
deleted file mode 100644
index 4bb8c6f..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$ImportMessageLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$ImportMessageLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$ImportMessageLiteOrBuilder.class
deleted file mode 100644
index 2632ae7..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite$ImportMessageLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite.class
deleted file mode 100644
index 617159f..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportPublicLite$1.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportPublicLite$1.class
deleted file mode 100644
index a90767c..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportPublicLite$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportPublicLite$PublicImportMessageLite$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportPublicLite$PublicImportMessageLite$Builder.class
deleted file mode 100644
index a4bcfe2..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportPublicLite$PublicImportMessageLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportPublicLite$PublicImportMessageLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportPublicLite$PublicImportMessageLite.class
deleted file mode 100644
index 4814004..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportPublicLite$PublicImportMessageLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportPublicLite$PublicImportMessageLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportPublicLite$PublicImportMessageLiteOrBuilder.class
deleted file mode 100644
index 3963828..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportPublicLite$PublicImportMessageLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportPublicLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportPublicLite.class
deleted file mode 100644
index f4c3919..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestImportPublicLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$1.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$1.class
deleted file mode 100644
index bca6104..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$DupEnum$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$DupEnum$Builder.class
deleted file mode 100644
index d2557d6..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$DupEnum$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$DupEnum$TestEnumWithDupValueLite$1.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$DupEnum$TestEnumWithDupValueLite$1.class
deleted file mode 100644
index 6a5bded..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$DupEnum$TestEnumWithDupValueLite$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$DupEnum$TestEnumWithDupValueLite$TestEnumWithDupValueLiteVerifier.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$DupEnum$TestEnumWithDupValueLite$TestEnumWithDupValueLiteVerifier.class
deleted file mode 100644
index bfd28ad..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$DupEnum$TestEnumWithDupValueLite$TestEnumWithDupValueLiteVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$DupEnum$TestEnumWithDupValueLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$DupEnum$TestEnumWithDupValueLite.class
deleted file mode 100644
index c01a24b..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$DupEnum$TestEnumWithDupValueLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$DupEnum.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$DupEnum.class
deleted file mode 100644
index bbdf4f9..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$DupEnum.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$DupEnumOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$DupEnumOrBuilder.class
deleted file mode 100644
index d963a3f..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$DupEnumOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$ForeignEnumLite$1.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$ForeignEnumLite$1.class
deleted file mode 100644
index c3bda3b..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$ForeignEnumLite$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$ForeignEnumLite$ForeignEnumLiteVerifier.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$ForeignEnumLite$ForeignEnumLiteVerifier.class
deleted file mode 100644
index 8ac38ec..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$ForeignEnumLite$ForeignEnumLiteVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$ForeignEnumLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$ForeignEnumLite.class
deleted file mode 100644
index 78861d0..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$ForeignEnumLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$ForeignMessageLite$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$ForeignMessageLite$Builder.class
deleted file mode 100644
index 5af3106..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$ForeignMessageLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$ForeignMessageLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$ForeignMessageLite.class
deleted file mode 100644
index c5babd8..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$ForeignMessageLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$ForeignMessageLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$ForeignMessageLiteOrBuilder.class
deleted file mode 100644
index 0f10850..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$ForeignMessageLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$NonPackedFixed32$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$NonPackedFixed32$Builder.class
deleted file mode 100644
index 3252cca..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$NonPackedFixed32$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$NonPackedFixed32.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$NonPackedFixed32.class
deleted file mode 100644
index a810013..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$NonPackedFixed32.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$NonPackedFixed32OrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$NonPackedFixed32OrBuilder.class
deleted file mode 100644
index 07b3c66..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$NonPackedFixed32OrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$NonPackedInt32$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$NonPackedInt32$Builder.class
deleted file mode 100644
index 7e77b04..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$NonPackedInt32$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$NonPackedInt32.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$NonPackedInt32.class
deleted file mode 100644
index 6d572ae..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$NonPackedInt32.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$NonPackedInt32OrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$NonPackedInt32OrBuilder.class
deleted file mode 100644
index 4a09048..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$NonPackedInt32OrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$OptionalGroup_extension_lite$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$OptionalGroup_extension_lite$Builder.class
deleted file mode 100644
index 0a2681f..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$OptionalGroup_extension_lite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$OptionalGroup_extension_lite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$OptionalGroup_extension_lite.class
deleted file mode 100644
index 364e773..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$OptionalGroup_extension_lite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$OptionalGroup_extension_liteOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$OptionalGroup_extension_liteOrBuilder.class
deleted file mode 100644
index a71dde5..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$OptionalGroup_extension_liteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$PackedFixed32$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$PackedFixed32$Builder.class
deleted file mode 100644
index 70056b0..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$PackedFixed32$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$PackedFixed32.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$PackedFixed32.class
deleted file mode 100644
index be2564e..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$PackedFixed32.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$PackedFixed32OrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$PackedFixed32OrBuilder.class
deleted file mode 100644
index 5987a3c..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$PackedFixed32OrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$PackedInt32$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$PackedInt32$Builder.class
deleted file mode 100644
index 2fd9bcd..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$PackedInt32$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$PackedInt32.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$PackedInt32.class
deleted file mode 100644
index 481b329..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$PackedInt32.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$PackedInt32OrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$PackedInt32OrBuilder.class
deleted file mode 100644
index 5b71c4e..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$PackedInt32OrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$RecursiveMessage$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$RecursiveMessage$Builder.class
deleted file mode 100644
index 46ac3cd..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$RecursiveMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$RecursiveMessage.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$RecursiveMessage.class
deleted file mode 100644
index 5d0990f..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$RecursiveMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$RecursiveMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$RecursiveMessageOrBuilder.class
deleted file mode 100644
index 5f7b6be..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$RecursiveMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$RepeatedGroup_extension_lite$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$RepeatedGroup_extension_lite$Builder.class
deleted file mode 100644
index b56e1c9..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$RepeatedGroup_extension_lite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$RepeatedGroup_extension_lite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$RepeatedGroup_extension_lite.class
deleted file mode 100644
index 959c018..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$RepeatedGroup_extension_lite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$RepeatedGroup_extension_liteOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$RepeatedGroup_extension_liteOrBuilder.class
deleted file mode 100644
index 25dfed0..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$RepeatedGroup_extension_liteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllExtensionsLite$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllExtensionsLite$Builder.class
deleted file mode 100644
index 8f79c2d..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllExtensionsLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllExtensionsLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllExtensionsLite.class
deleted file mode 100644
index 915f045..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllExtensionsLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllExtensionsLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllExtensionsLiteOrBuilder.class
deleted file mode 100644
index bfe6401..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllExtensionsLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$1.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$1.class
deleted file mode 100644
index 0e69bf2..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$2.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$2.class
deleted file mode 100644
index 5511af3..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$2.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$3.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$3.class
deleted file mode 100644
index 23cec54..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$3.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$Builder.class
deleted file mode 100644
index 6197658..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedEnum$1.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedEnum$1.class
deleted file mode 100644
index 843210e..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedEnum$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedEnum$NestedEnumVerifier.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedEnum$NestedEnumVerifier.class
deleted file mode 100644
index 7e7dc15..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedEnum$NestedEnumVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedEnum.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedEnum.class
deleted file mode 100644
index a94008b..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedEnum.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage$Builder.class
deleted file mode 100644
index c40a86c..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage.class
deleted file mode 100644
index 23b778d..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage2$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage2$Builder.class
deleted file mode 100644
index 60320ba..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage2$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage2.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage2.class
deleted file mode 100644
index c8f3f58..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage2.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage2OrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage2OrBuilder.class
deleted file mode 100644
index 67d9d51..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessage2OrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessageOrBuilder.class
deleted file mode 100644
index 716c4dc..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$NestedMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$OneofFieldCase.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$OneofFieldCase.class
deleted file mode 100644
index dd286ce..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$OneofFieldCase.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$OptionalGroup$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$OptionalGroup$Builder.class
deleted file mode 100644
index 7d7b4a3..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$OptionalGroup$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$OptionalGroup.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$OptionalGroup.class
deleted file mode 100644
index 4f05de5..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$OptionalGroup.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$OptionalGroupOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$OptionalGroupOrBuilder.class
deleted file mode 100644
index f31c90e..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$OptionalGroupOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$RepeatedGroup$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$RepeatedGroup$Builder.class
deleted file mode 100644
index 3fd13fe..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$RepeatedGroup$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$RepeatedGroup.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$RepeatedGroup.class
deleted file mode 100644
index 2b0f9c9..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$RepeatedGroup.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$RepeatedGroupOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$RepeatedGroupOrBuilder.class
deleted file mode 100644
index b8f31c7..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite$RepeatedGroupOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite.class
deleted file mode 100644
index 2583da6..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLiteOrBuilder.class
deleted file mode 100644
index fe2fe36..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestAllTypesLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestDeprecatedLite$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestDeprecatedLite$Builder.class
deleted file mode 100644
index 07e8819..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestDeprecatedLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestDeprecatedLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestDeprecatedLite.class
deleted file mode 100644
index fbd0c64..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestDeprecatedLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestDeprecatedLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestDeprecatedLiteOrBuilder.class
deleted file mode 100644
index dec385a..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestDeprecatedLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestEmptyMessageLite$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestEmptyMessageLite$Builder.class
deleted file mode 100644
index 7883e9d..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestEmptyMessageLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestEmptyMessageLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestEmptyMessageLite.class
deleted file mode 100644
index bb57c02..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestEmptyMessageLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestEmptyMessageLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestEmptyMessageLiteOrBuilder.class
deleted file mode 100644
index 547da99..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestEmptyMessageLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestEmptyMessageWithExtensionsLite$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestEmptyMessageWithExtensionsLite$Builder.class
deleted file mode 100644
index 6ef1a5b..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestEmptyMessageWithExtensionsLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestEmptyMessageWithExtensionsLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestEmptyMessageWithExtensionsLite.class
deleted file mode 100644
index 77ef3f8..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestEmptyMessageWithExtensionsLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestEmptyMessageWithExtensionsLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestEmptyMessageWithExtensionsLiteOrBuilder.class
deleted file mode 100644
index 247c202..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestEmptyMessageWithExtensionsLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$Builder.class
deleted file mode 100644
index 1f4272d..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$OneofFieldCase.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$OneofFieldCase.class
deleted file mode 100644
index b02610e..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$OneofFieldCase.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$OptionalGroup$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$OptionalGroup$Builder.class
deleted file mode 100644
index 32d16be..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$OptionalGroup$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$OptionalGroup.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$OptionalGroup.class
deleted file mode 100644
index 5605bc0..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$OptionalGroup.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$OptionalGroupOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$OptionalGroupOrBuilder.class
deleted file mode 100644
index d062afa..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$OptionalGroupOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$StringStringMapDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$StringStringMapDefaultEntryHolder.class
deleted file mode 100644
index 792b33b..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite$StringStringMapDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite.class
deleted file mode 100644
index b9393df..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLiteOrBuilder.class
deleted file mode 100644
index a1344a0..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestHugeFieldNumbersLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestNestedExtensionLite$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestNestedExtensionLite$Builder.class
deleted file mode 100644
index aa3fd2d..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestNestedExtensionLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestNestedExtensionLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestNestedExtensionLite.class
deleted file mode 100644
index 3803303..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestNestedExtensionLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestNestedExtensionLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestNestedExtensionLiteOrBuilder.class
deleted file mode 100644
index 4e54874..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestNestedExtensionLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestOneofParsingLite$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestOneofParsingLite$Builder.class
deleted file mode 100644
index 1413799..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestOneofParsingLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestOneofParsingLite$OneofFieldCase.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestOneofParsingLite$OneofFieldCase.class
deleted file mode 100644
index 3e58970..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestOneofParsingLite$OneofFieldCase.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestOneofParsingLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestOneofParsingLite.class
deleted file mode 100644
index a9bd89e..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestOneofParsingLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestOneofParsingLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestOneofParsingLiteOrBuilder.class
deleted file mode 100644
index 20cc644..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestOneofParsingLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedExtensionsLite$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedExtensionsLite$Builder.class
deleted file mode 100644
index e7f87d1..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedExtensionsLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedExtensionsLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedExtensionsLite.class
deleted file mode 100644
index 5241657..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedExtensionsLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedExtensionsLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedExtensionsLiteOrBuilder.class
deleted file mode 100644
index 3f78158..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedExtensionsLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedTypesLite$1.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedTypesLite$1.class
deleted file mode 100644
index 1f3a7fe..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedTypesLite$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedTypesLite$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedTypesLite$Builder.class
deleted file mode 100644
index a7d04a8..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedTypesLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedTypesLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedTypesLite.class
deleted file mode 100644
index e77cf90..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedTypesLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedTypesLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedTypesLiteOrBuilder.class
deleted file mode 100644
index e728d74..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestPackedTypesLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$Builder.class
deleted file mode 100644
index 3774efc..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$OptionalGroup$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$OptionalGroup$Builder.class
deleted file mode 100644
index b0bfeee..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$OptionalGroup$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$OptionalGroup.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$OptionalGroup.class
deleted file mode 100644
index 89aad48..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$OptionalGroup.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$OptionalGroupOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$OptionalGroupOrBuilder.class
deleted file mode 100644
index 2034057..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$OptionalGroupOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Builder.class
deleted file mode 100644
index 47e740b..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group1$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group1$Builder.class
deleted file mode 100644
index ee4adbb..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group1$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group1.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group1.class
deleted file mode 100644
index 80ad75e..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group1OrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group1OrBuilder.class
deleted file mode 100644
index 65674cf..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group1OrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group2$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group2$Builder.class
deleted file mode 100644
index 26bde96..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group2$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group2.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group2.class
deleted file mode 100644
index 3bac1dd..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group2.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group2OrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group2OrBuilder.class
deleted file mode 100644
index a987979..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator$Group2OrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator.class
deleted file mode 100644
index 2b90949..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGenerator.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGeneratorOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGeneratorOrBuilder.class
deleted file mode 100644
index 8a06125..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedFieldsGeneratorOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedGroup$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedGroup$Builder.class
deleted file mode 100644
index 5a3fa3b..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedGroup$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedGroup.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedGroup.class
deleted file mode 100644
index 9a1eb55..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedGroup.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedGroupOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedGroupOrBuilder.class
deleted file mode 100644
index cccb77b..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite$RepeatedGroupOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite.class
deleted file mode 100644
index 113d90a..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLiteOrBuilder.class
deleted file mode 100644
index ac5b194..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$TestParsingMergeLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V1EnumLite$1.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V1EnumLite$1.class
deleted file mode 100644
index 5c463cc..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V1EnumLite$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V1EnumLite$V1EnumLiteVerifier.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V1EnumLite$V1EnumLiteVerifier.class
deleted file mode 100644
index f0f3b4b..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V1EnumLite$V1EnumLiteVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V1EnumLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V1EnumLite.class
deleted file mode 100644
index ee5182b..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V1EnumLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V1MessageLite$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V1MessageLite$Builder.class
deleted file mode 100644
index 6335da5..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V1MessageLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V1MessageLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V1MessageLite.class
deleted file mode 100644
index dbf9224..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V1MessageLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V1MessageLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V1MessageLiteOrBuilder.class
deleted file mode 100644
index 4117d7a..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V1MessageLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V2EnumLite$1.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V2EnumLite$1.class
deleted file mode 100644
index 3998c6f..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V2EnumLite$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V2EnumLite$V2EnumLiteVerifier.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V2EnumLite$V2EnumLiteVerifier.class
deleted file mode 100644
index b650f27..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V2EnumLite$V2EnumLiteVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V2EnumLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V2EnumLite.class
deleted file mode 100644
index ad83179..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V2EnumLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V2MessageLite$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V2MessageLite$Builder.class
deleted file mode 100644
index dac9ec6..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V2MessageLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V2MessageLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V2MessageLite.class
deleted file mode 100644
index 17542fa..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V2MessageLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V2MessageLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V2MessageLiteOrBuilder.class
deleted file mode 100644
index 3401693..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite$V2MessageLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite.class
deleted file mode 100644
index 7307e34..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/UnittestLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/V1MessageLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/V1MessageLiteKt$Dsl$Companion.class
deleted file mode 100644
index 63e75bd..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/V1MessageLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/V1MessageLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/V1MessageLiteKt$Dsl.class
deleted file mode 100644
index ac7651a..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/V1MessageLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/V1MessageLiteKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/V1MessageLiteKt.class
deleted file mode 100644
index 1cbe53a..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/V1MessageLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/V1MessageLiteKtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/V1MessageLiteKtKt.class
deleted file mode 100644
index 646bc70..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/V1MessageLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/V2MessageLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/V2MessageLiteKt$Dsl$Companion.class
deleted file mode 100644
index 31f8ead..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/V2MessageLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/V2MessageLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/V2MessageLiteKt$Dsl.class
deleted file mode 100644
index 2eef84e..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/V2MessageLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/V2MessageLiteKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/V2MessageLiteKt.class
deleted file mode 100644
index 23c40c1..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/V2MessageLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/V2MessageLiteKtKt.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/V2MessageLiteKtKt.class
deleted file mode 100644
index f1a21ff..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/V2MessageLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/DslListTest$DummyProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/DslListTest$DummyProxy.class
deleted file mode 100644
index 036a499..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/DslListTest$DummyProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/DslListTest.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/DslListTest.class
deleted file mode 100644
index 0eb49ff..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/DslListTest.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/DslMapTest$DummyProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/DslMapTest$DummyProxy.class
deleted file mode 100644
index 011c654..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/DslMapTest$DummyProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/DslMapTest.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/DslMapTest.class
deleted file mode 100644
index ca02f51..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/DslMapTest.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/ExtendableMessageLiteExtensionsTest.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/ExtendableMessageLiteExtensionsTest.class
deleted file mode 100644
index 5beec8a..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/ExtendableMessageLiteExtensionsTest.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/ExtensionListTest$DummyProxy.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/ExtensionListTest$DummyProxy.class
deleted file mode 100644
index 3618a3f..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/ExtensionListTest$DummyProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/ExtensionListTest.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/ExtensionListTest.class
deleted file mode 100644
index a42c8a7..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/ExtensionListTest.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/Proto2LiteTest.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/Proto2LiteTest.class
deleted file mode 100644
index 046c931..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/Proto2LiteTest.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/Proto3Test.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/Proto3Test.class
deleted file mode 100644
index b4c3f57..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/kotlin/Proto3Test.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$1.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$1.class
deleted file mode 100644
index 203f365..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportEnum$1.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportEnum$1.class
deleted file mode 100644
index c956c01..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportEnum$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportEnum$ImportEnumVerifier.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportEnum$ImportEnumVerifier.class
deleted file mode 100644
index 7e96daa..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportEnum$ImportEnumVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportEnum.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportEnum.class
deleted file mode 100644
index 9c78766..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportEnum.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportEnumForMap$1.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportEnumForMap$1.class
deleted file mode 100644
index 67c8058..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportEnumForMap$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportEnumForMap$ImportEnumForMapVerifier.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportEnumForMap$ImportEnumForMapVerifier.class
deleted file mode 100644
index b349bb5..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportEnumForMap$ImportEnumForMapVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportEnumForMap.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportEnumForMap.class
deleted file mode 100644
index 9226610..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportEnumForMap.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportMessage$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportMessage$Builder.class
deleted file mode 100644
index 8355ccd..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportMessage.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportMessage.class
deleted file mode 100644
index 26e41b1..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportMessageOrBuilder.class
deleted file mode 100644
index d84211d..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport$ImportMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport.class
deleted file mode 100644
index 06622b6..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImport.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImportPublic$1.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImportPublic$1.class
deleted file mode 100644
index 465ac37..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImportPublic$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImportPublic$PublicImportMessage$Builder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImportPublic$PublicImportMessage$Builder.class
deleted file mode 100644
index 40effb4..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImportPublic$PublicImportMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImportPublic$PublicImportMessage.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImportPublic$PublicImportMessage.class
deleted file mode 100644
index 7f0dbff..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImportPublic$PublicImportMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImportPublic$PublicImportMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImportPublic$PublicImportMessageOrBuilder.class
deleted file mode 100644
index 42dd72e..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImportPublic$PublicImportMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImportPublic.class b/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImportPublic.class
deleted file mode 100644
index dabfe6e..0000000
--- a/java/kotlin-lite/target/test-classes/com/google/protobuf/test/UnittestImportPublic.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt$Dsl$ALLCAPSMAPProxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt$Dsl$ALLCAPSMAPProxy.class
deleted file mode 100644
index ab8072a..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt$Dsl$ALLCAPSMAPProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt$Dsl$ALLCAPSProxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt$Dsl$ALLCAPSProxy.class
deleted file mode 100644
index 8542fe3..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt$Dsl$ALLCAPSProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt$Dsl$Class_Proxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt$Dsl$Class_Proxy.class
deleted file mode 100644
index 94dfdd2..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt$Dsl$Class_Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt$Dsl$Companion.class
deleted file mode 100644
index 9ab97f4..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt$Dsl$ExtensionProxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt$Dsl$ExtensionProxy.class
deleted file mode 100644
index 2172993..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt$Dsl$ExtensionProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt$Dsl.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt$Dsl.class
deleted file mode 100644
index 97825a4..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt.class
deleted file mode 100644
index 2373aed..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2Kt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2KtKt.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2KtKt.class
deleted file mode 100644
index 2f7e0e3..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2KtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$1.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$1.class
deleted file mode 100644
index a514fd0..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2$ALLCAPSMAPDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2$ALLCAPSMAPDefaultEntryHolder.class
deleted file mode 100644
index a9befd2..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2$ALLCAPSMAPDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2$Builder.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2$Builder.class
deleted file mode 100644
index 69ff58d..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2$CamelCaseCase.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2$CamelCaseCase.class
deleted file mode 100644
index 46147ae..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2$CamelCaseCase.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2.class
deleted file mode 100644
index d508dab..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2OrBuilder.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2OrBuilder.class
deleted file mode 100644
index 5655451..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$EvilNamesProto2OrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$1.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$1.class
deleted file mode 100644
index 3735b59..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$Builder.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$Builder.class
deleted file mode 100644
index b4e19ad..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$ContinueDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$ContinueDefaultEntryHolder.class
deleted file mode 100644
index ab7e304..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$ContinueDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedEnum$1.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedEnum$1.class
deleted file mode 100644
index d253688..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedEnum$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedEnum$NestedEnumVerifier.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedEnum$NestedEnumVerifier.class
deleted file mode 100644
index be123a6..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedEnum$NestedEnumVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedEnum.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedEnum.class
deleted file mode 100644
index b0c12e7..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedEnum.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedMessage$Builder.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedMessage$Builder.class
deleted file mode 100644
index 17ef510..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedMessage.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedMessage.class
deleted file mode 100644
index 150c016..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedMessageOrBuilder.class
deleted file mode 100644
index a76ba63..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes$NestedMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes.class
deleted file mode 100644
index 39af6e7..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypes.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypesOrBuilder.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypesOrBuilder.class
deleted file mode 100644
index dd1d8a8..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$HardKeywordsAllTypesOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$Interface$Builder.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$Interface$Builder.class
deleted file mode 100644
index a9c1b7a..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$Interface$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$Interface.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$Interface.class
deleted file mode 100644
index 7e833e6..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$Interface.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$InterfaceOrBuilder.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$InterfaceOrBuilder.class
deleted file mode 100644
index 593cf3a..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass$InterfaceOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass.class
deleted file mode 100644
index e723506..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/EvilNamesProto2OuterClass.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl$Companion.class
deleted file mode 100644
index 7f26e2c..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl$Continue_Proxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl$Continue_Proxy.class
deleted file mode 100644
index f31eecf..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl$Continue_Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl$Else_Proxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl$Else_Proxy.class
deleted file mode 100644
index f6187c3..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl$Else_Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl$For_Proxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl$For_Proxy.class
deleted file mode 100644
index a6f8c2a..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl$For_Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl$Fun_Proxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl$Fun_Proxy.class
deleted file mode 100644
index ae8a3dc..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl$Fun_Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl$If_Proxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl$If_Proxy.class
deleted file mode 100644
index 8defe8a..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl$If_Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl.class
deleted file mode 100644
index 96d19b7..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$NestedMessageKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$NestedMessageKt$Dsl$Companion.class
deleted file mode 100644
index 6060174..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$NestedMessageKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$NestedMessageKt$Dsl.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$NestedMessageKt$Dsl.class
deleted file mode 100644
index 5259bc7..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$NestedMessageKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$NestedMessageKt.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$NestedMessageKt.class
deleted file mode 100644
index 55c21fa..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt$NestedMessageKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt.class
deleted file mode 100644
index f9594bd..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKtKt.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKtKt.class
deleted file mode 100644
index 7f5b901..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/HardKeywordsAllTypesKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/InterfaceKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/InterfaceKt$Dsl$Companion.class
deleted file mode 100644
index 7803518..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/InterfaceKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/InterfaceKt$Dsl.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/InterfaceKt$Dsl.class
deleted file mode 100644
index 306bad3..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/InterfaceKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/InterfaceKt.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/InterfaceKt.class
deleted file mode 100644
index 1b73b10..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/InterfaceKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto2/InterfaceKtKt.class b/java/kotlin-lite/target/test-classes/evil_names_proto2/InterfaceKtKt.class
deleted file mode 100644
index bf49906..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto2/InterfaceKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/ClassKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/ClassKt$Dsl$Companion.class
deleted file mode 100644
index daab73f..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/ClassKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/ClassKt$Dsl.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/ClassKt$Dsl.class
deleted file mode 100644
index e0c940d..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/ClassKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/ClassKt.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/ClassKt.class
deleted file mode 100644
index 9d36b00..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/ClassKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/ClassKtKt.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/ClassKtKt.class
deleted file mode 100644
index 100137a..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/ClassKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$ALLCAPSMAPProxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$ALLCAPSMAPProxy.class
deleted file mode 100644
index 99bb842..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$ALLCAPSMAPProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$ALLCAPSProxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$ALLCAPSProxy.class
deleted file mode 100644
index cafbe0d..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$ALLCAPSProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$Companion.class
deleted file mode 100644
index cc4d774..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$ExtensionProxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$ExtensionProxy.class
deleted file mode 100644
index 0bae60b..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$ExtensionProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$KProxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$KProxy.class
deleted file mode 100644
index 73e9c99..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$KProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$KeyProxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$KeyProxy.class
deleted file mode 100644
index 90d9d59..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$KeyProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$MapProxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$MapProxy.class
deleted file mode 100644
index f45c014..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$MapProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$NewValuesProxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$NewValuesProxy.class
deleted file mode 100644
index eacc733..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$NewValuesProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$PairsProxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$PairsProxy.class
deleted file mode 100644
index 609674d..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$PairsProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$VProxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$VProxy.class
deleted file mode 100644
index 24d1f3d..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$VProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$ValuesProxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$ValuesProxy.class
deleted file mode 100644
index 0c095a8..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl$ValuesProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl.class
deleted file mode 100644
index 7720538..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt.class
deleted file mode 100644
index 4e50e6f..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3Kt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3KtKt.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3KtKt.class
deleted file mode 100644
index 39222e0..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3KtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$1.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$1.class
deleted file mode 100644
index d4093cb..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$Class$Builder.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$Class$Builder.class
deleted file mode 100644
index e7b1b03..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$Class$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$Class.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$Class.class
deleted file mode 100644
index f1c4c20..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$Class.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$ClassOrBuilder.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$ClassOrBuilder.class
deleted file mode 100644
index 3e3a59c..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$ClassOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$ALLCAPSMAPDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$ALLCAPSMAPDefaultEntryHolder.class
deleted file mode 100644
index f5deb27..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$ALLCAPSMAPDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$Builder.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$Builder.class
deleted file mode 100644
index ab52508..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$CamelCaseCase.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$CamelCaseCase.class
deleted file mode 100644
index 7654023..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$CamelCaseCase.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$KDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$KDefaultEntryHolder.class
deleted file mode 100644
index 466a566..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$KDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$KeyDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$KeyDefaultEntryHolder.class
deleted file mode 100644
index 40d5213..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$KeyDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$LeadingUnderscoreOneofCase.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$LeadingUnderscoreOneofCase.class
deleted file mode 100644
index a4daf7f..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$LeadingUnderscoreOneofCase.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$MapDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$MapDefaultEntryHolder.class
deleted file mode 100644
index 4771cf4..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$MapDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$PairsDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$PairsDefaultEntryHolder.class
deleted file mode 100644
index 02b5cc1..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$PairsDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$VDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$VDefaultEntryHolder.class
deleted file mode 100644
index aa8292a..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3$VDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3.class
deleted file mode 100644
index 3cb41b9..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3OrBuilder.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3OrBuilder.class
deleted file mode 100644
index 737eb9b..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$EvilNamesProto3OrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$1.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$1.class
deleted file mode 100644
index 51b4cd7..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$Builder.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$Builder.class
deleted file mode 100644
index 87143d3..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$ContinueDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$ContinueDefaultEntryHolder.class
deleted file mode 100644
index 2f43bb2..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$ContinueDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedEnum$1.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedEnum$1.class
deleted file mode 100644
index 137442f..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedEnum$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedEnum$NestedEnumVerifier.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedEnum$NestedEnumVerifier.class
deleted file mode 100644
index 296d51d..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedEnum$NestedEnumVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedEnum.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedEnum.class
deleted file mode 100644
index 9c23dce..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedEnum.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedMessage$Builder.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedMessage$Builder.class
deleted file mode 100644
index a94c59a..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedMessage.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedMessage.class
deleted file mode 100644
index c2968e8..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedMessageOrBuilder.class
deleted file mode 100644
index 578887d..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes$NestedMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes.class
deleted file mode 100644
index bb6f5a0..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypes.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypesOrBuilder.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypesOrBuilder.class
deleted file mode 100644
index 9b08f7d..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass$HardKeywordsAllTypesOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass.class
deleted file mode 100644
index 3a15578..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/EvilNamesProto3OuterClass.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl$Companion.class
deleted file mode 100644
index 4cf828d..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl$Continue_Proxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl$Continue_Proxy.class
deleted file mode 100644
index ea7fa31..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl$Continue_Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl$Else_Proxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl$Else_Proxy.class
deleted file mode 100644
index 1db90a0..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl$Else_Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl$For_Proxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl$For_Proxy.class
deleted file mode 100644
index f737a37..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl$For_Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl$Fun_Proxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl$Fun_Proxy.class
deleted file mode 100644
index f2ec195..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl$Fun_Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl$If_Proxy.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl$If_Proxy.class
deleted file mode 100644
index 48a4a88..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl$If_Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl.class
deleted file mode 100644
index 690fdf4..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$NestedMessageKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$NestedMessageKt$Dsl$Companion.class
deleted file mode 100644
index 2b4314f..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$NestedMessageKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$NestedMessageKt$Dsl.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$NestedMessageKt$Dsl.class
deleted file mode 100644
index f8d0697..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$NestedMessageKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$NestedMessageKt.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$NestedMessageKt.class
deleted file mode 100644
index cc2ede7..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt$NestedMessageKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt.class
deleted file mode 100644
index e33ffcb..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKtKt.class b/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKtKt.class
deleted file mode 100644
index 5be62e6..0000000
--- a/java/kotlin-lite/target/test-classes/evil_names_proto3/HardKeywordsAllTypesKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessage$1.class b/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessage$1.class
deleted file mode 100644
index 22cc8d7..0000000
--- a/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessage$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessage$Builder.class b/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessage$Builder.class
deleted file mode 100644
index 9fed5d9..0000000
--- a/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessage.class b/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessage.class
deleted file mode 100644
index b8b69e5..0000000
--- a/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessageKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessageKt$Dsl$Companion.class
deleted file mode 100644
index 859bef3..0000000
--- a/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessageKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessageKt$Dsl.class b/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessageKt$Dsl.class
deleted file mode 100644
index be3dba8..0000000
--- a/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessageKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessageKt.class b/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessageKt.class
deleted file mode 100644
index d4a3b9d..0000000
--- a/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessageKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessageKtKt.class b/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessageKtKt.class
deleted file mode 100644
index a398dc1..0000000
--- a/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessageKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessageOrBuilder.class
deleted file mode 100644
index 2710791..0000000
--- a/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessageOuterClass.class b/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessageOuterClass.class
deleted file mode 100644
index 33ee704..0000000
--- a/java/kotlin-lite/target/test-classes/example_extensible_message/ExampleExtensibleMessageOuterClass.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/google/protobuf/testdata/golden_message_oneof_implemented b/java/kotlin-lite/target/test-classes/google/protobuf/testdata/golden_message_oneof_implemented
deleted file mode 100644
index b48c898..0000000
--- a/java/kotlin-lite/target/test-classes/google/protobuf/testdata/golden_message_oneof_implemented
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/google/protobuf/testdata/golden_packed_fields_message b/java/kotlin-lite/target/test-classes/google/protobuf/testdata/golden_packed_fields_message
deleted file mode 100644
index ee28d38..0000000
--- a/java/kotlin-lite/target/test-classes/google/protobuf/testdata/golden_packed_fields_message
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageA$1.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageA$1.class
deleted file mode 100644
index a697374..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageA$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageA$Builder.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageA$Builder.class
deleted file mode 100644
index 05a1ff0..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageA$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageA.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageA.class
deleted file mode 100644
index 1684099..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageA.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageAKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageAKt$Dsl$Companion.class
deleted file mode 100644
index 4841e14..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageAKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageAKt$Dsl.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageAKt$Dsl.class
deleted file mode 100644
index 355da8c..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageAKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageAKt.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageAKt.class
deleted file mode 100644
index 639c69f..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageAKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageAKtKt.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageAKtKt.class
deleted file mode 100644
index 8038203..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageAKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageAOrBuilder.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageAOrBuilder.class
deleted file mode 100644
index d889de6..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageAOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageB$1.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageB$1.class
deleted file mode 100644
index f7eac5a..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageB$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageB$Builder.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageB$Builder.class
deleted file mode 100644
index 51ed35f..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageB$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageB.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageB.class
deleted file mode 100644
index 3c5d3cf..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageB.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageBKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageBKt$Dsl$Companion.class
deleted file mode 100644
index e8a91fa..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageBKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageBKt$Dsl.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageBKt$Dsl.class
deleted file mode 100644
index ca31d57..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageBKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageBKt.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageBKt.class
deleted file mode 100644
index 07c6ce7..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageBKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageBKtKt.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageBKtKt.class
deleted file mode 100644
index 80bd766..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageBKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageBOrBuilder.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageBOrBuilder.class
deleted file mode 100644
index 7198c50..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesMessageBOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesProto3.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesProto3.class
deleted file mode 100644
index d0583d2..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/MultipleFilesProto3.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/NestedEnum$1.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/NestedEnum$1.class
deleted file mode 100644
index f4b4341..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/NestedEnum$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/NestedEnum$NestedEnumVerifier.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/NestedEnum$NestedEnumVerifier.class
deleted file mode 100644
index 81b492d..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/NestedEnum$NestedEnumVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/multiple_files_proto3/NestedEnum.class b/java/kotlin-lite/target/test-classes/multiple_files_proto3/NestedEnum.class
deleted file mode 100644
index c00b516..0000000
--- a/java/kotlin-lite/target/test-classes/multiple_files_proto3/NestedEnum.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/ForeignMessageKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/proto3_unittest/ForeignMessageKt$Dsl$Companion.class
deleted file mode 100644
index 89513f1..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/ForeignMessageKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/ForeignMessageKt$Dsl.class b/java/kotlin-lite/target/test-classes/proto3_unittest/ForeignMessageKt$Dsl.class
deleted file mode 100644
index 190f076..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/ForeignMessageKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/ForeignMessageKt.class b/java/kotlin-lite/target/test-classes/proto3_unittest/ForeignMessageKt.class
deleted file mode 100644
index 3d56963..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/ForeignMessageKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/ForeignMessageKtKt.class b/java/kotlin-lite/target/test-classes/proto3_unittest/ForeignMessageKtKt.class
deleted file mode 100644
index e9f175c..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/ForeignMessageKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/NestedTestAllTypesKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/proto3_unittest/NestedTestAllTypesKt$Dsl$Companion.class
deleted file mode 100644
index 181d79a..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/NestedTestAllTypesKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/NestedTestAllTypesKt$Dsl.class b/java/kotlin-lite/target/test-classes/proto3_unittest/NestedTestAllTypesKt$Dsl.class
deleted file mode 100644
index 0e00ad7..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/NestedTestAllTypesKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/NestedTestAllTypesKt.class b/java/kotlin-lite/target/test-classes/proto3_unittest/NestedTestAllTypesKt.class
deleted file mode 100644
index 42d7ed4..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/NestedTestAllTypesKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/NestedTestAllTypesKtKt.class b/java/kotlin-lite/target/test-classes/proto3_unittest/NestedTestAllTypesKtKt.class
deleted file mode 100644
index 55682ce..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/NestedTestAllTypesKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$Companion.class
deleted file mode 100644
index 9985d22..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedBoolProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedBoolProxy.class
deleted file mode 100644
index 391aa22..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedBoolProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedBytesProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedBytesProxy.class
deleted file mode 100644
index 38e0030..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedBytesProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedCordProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedCordProxy.class
deleted file mode 100644
index 3dffd43..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedCordProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedDoubleProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedDoubleProxy.class
deleted file mode 100644
index b1b90d0..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedDoubleProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedFixed32Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedFixed32Proxy.class
deleted file mode 100644
index 9891d5f..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedFixed32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedFixed64Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedFixed64Proxy.class
deleted file mode 100644
index 0ed6546..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedFixed64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedFloatProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedFloatProxy.class
deleted file mode 100644
index 2feafd1..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedFloatProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedForeignEnumProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedForeignEnumProxy.class
deleted file mode 100644
index 6fb54e9..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedForeignEnumProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedForeignMessageProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedForeignMessageProxy.class
deleted file mode 100644
index 1f568b0..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedForeignMessageProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedImportMessageProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedImportMessageProxy.class
deleted file mode 100644
index f88da06..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedImportMessageProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedInt32Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedInt32Proxy.class
deleted file mode 100644
index 119e9f3..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedInt32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedInt64Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedInt64Proxy.class
deleted file mode 100644
index 6e88925..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedInt64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedLazyMessageProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedLazyMessageProxy.class
deleted file mode 100644
index fe3ddac..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedLazyMessageProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedNestedEnumProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedNestedEnumProxy.class
deleted file mode 100644
index 4a5ff6f..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedNestedEnumProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedNestedMessageProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedNestedMessageProxy.class
deleted file mode 100644
index dd4a051..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedNestedMessageProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedSfixed32Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedSfixed32Proxy.class
deleted file mode 100644
index b4ea6c7..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedSfixed32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedSfixed64Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedSfixed64Proxy.class
deleted file mode 100644
index d1674bc..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedSfixed64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedSint32Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedSint32Proxy.class
deleted file mode 100644
index 855061e..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedSint32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedSint64Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedSint64Proxy.class
deleted file mode 100644
index 8806b27..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedSint64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedStringPieceProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedStringPieceProxy.class
deleted file mode 100644
index 81f0ff7..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedStringPieceProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedStringProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedStringProxy.class
deleted file mode 100644
index 1158060..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedStringProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedUint32Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedUint32Proxy.class
deleted file mode 100644
index ecf8e37..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedUint32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedUint64Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedUint64Proxy.class
deleted file mode 100644
index 2831381..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl$RepeatedUint64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl.class
deleted file mode 100644
index 4f01c3f..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$NestedMessageKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$NestedMessageKt$Dsl$Companion.class
deleted file mode 100644
index 3f86f33..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$NestedMessageKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$NestedMessageKt$Dsl.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$NestedMessageKt$Dsl.class
deleted file mode 100644
index 0500252..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$NestedMessageKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$NestedMessageKt.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$NestedMessageKt.class
deleted file mode 100644
index b8ac5e7..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt$NestedMessageKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt.class
deleted file mode 100644
index 38b8254..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKtKt.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKtKt.class
deleted file mode 100644
index 7fddb1a5..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestAllTypesKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestEmptyMessageKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestEmptyMessageKt$Dsl$Companion.class
deleted file mode 100644
index 975866c..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestEmptyMessageKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestEmptyMessageKt$Dsl.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestEmptyMessageKt$Dsl.class
deleted file mode 100644
index 0637dbd..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestEmptyMessageKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestEmptyMessageKt.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestEmptyMessageKt.class
deleted file mode 100644
index 11d2d45..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestEmptyMessageKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestEmptyMessageKtKt.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestEmptyMessageKtKt.class
deleted file mode 100644
index 0e532d7..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestEmptyMessageKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestMessageWithDummyKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestMessageWithDummyKt$Dsl$Companion.class
deleted file mode 100644
index 45289cb..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestMessageWithDummyKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestMessageWithDummyKt$Dsl.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestMessageWithDummyKt$Dsl.class
deleted file mode 100644
index 717b4fd..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestMessageWithDummyKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestMessageWithDummyKt.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestMessageWithDummyKt.class
deleted file mode 100644
index 1b72acb..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestMessageWithDummyKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestMessageWithDummyKtKt.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestMessageWithDummyKtKt.class
deleted file mode 100644
index 2d9db6c..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestMessageWithDummyKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestOneof2Kt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestOneof2Kt$Dsl$Companion.class
deleted file mode 100644
index b9f4994..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestOneof2Kt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestOneof2Kt$Dsl.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestOneof2Kt$Dsl.class
deleted file mode 100644
index f0aa305..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestOneof2Kt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestOneof2Kt.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestOneof2Kt.class
deleted file mode 100644
index 39f5ef3..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestOneof2Kt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestOneof2KtKt.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestOneof2KtKt.class
deleted file mode 100644
index 5d30323..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestOneof2KtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$Companion.class
deleted file mode 100644
index 4012b8c..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedBoolProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedBoolProxy.class
deleted file mode 100644
index f6a47d4..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedBoolProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedDoubleProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedDoubleProxy.class
deleted file mode 100644
index ce6b93c..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedDoubleProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedEnumProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedEnumProxy.class
deleted file mode 100644
index 4058ea5..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedEnumProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedFixed32Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedFixed32Proxy.class
deleted file mode 100644
index 41f06c6..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedFixed32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedFixed64Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedFixed64Proxy.class
deleted file mode 100644
index 49192de..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedFixed64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedFloatProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedFloatProxy.class
deleted file mode 100644
index f9af836..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedFloatProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedInt32Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedInt32Proxy.class
deleted file mode 100644
index b30658d..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedInt32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedInt64Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedInt64Proxy.class
deleted file mode 100644
index 6ce4102..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedInt64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedSfixed32Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedSfixed32Proxy.class
deleted file mode 100644
index f2d2c21..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedSfixed32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedSfixed64Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedSfixed64Proxy.class
deleted file mode 100644
index 7060443..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedSfixed64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedSint32Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedSint32Proxy.class
deleted file mode 100644
index cee583d..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedSint32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedSint64Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedSint64Proxy.class
deleted file mode 100644
index da749e5..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedSint64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedUint32Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedUint32Proxy.class
deleted file mode 100644
index 198c750..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedUint32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedUint64Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedUint64Proxy.class
deleted file mode 100644
index 9738b9b..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl$PackedUint64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl.class
deleted file mode 100644
index 9635648..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt.class
deleted file mode 100644
index 234c678..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKtKt.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKtKt.class
deleted file mode 100644
index 99b3191..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestPackedTypesKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$Companion.class
deleted file mode 100644
index af37b5d..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedBoolProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedBoolProxy.class
deleted file mode 100644
index a57339a..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedBoolProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedDoubleProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedDoubleProxy.class
deleted file mode 100644
index fc611f2..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedDoubleProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedFixed32Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedFixed32Proxy.class
deleted file mode 100644
index 5d4a4de..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedFixed32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedFixed64Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedFixed64Proxy.class
deleted file mode 100644
index 4b9a8c5..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedFixed64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedFloatProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedFloatProxy.class
deleted file mode 100644
index 96eed1e..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedFloatProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedInt32Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedInt32Proxy.class
deleted file mode 100644
index c4c50f9..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedInt32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedInt64Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedInt64Proxy.class
deleted file mode 100644
index 1852a29..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedInt64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedNestedEnumProxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedNestedEnumProxy.class
deleted file mode 100644
index 85afbb5..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedNestedEnumProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedSfixed32Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedSfixed32Proxy.class
deleted file mode 100644
index ff8afc0..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedSfixed32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedSfixed64Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedSfixed64Proxy.class
deleted file mode 100644
index 1ff44fe..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedSfixed64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedSint32Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedSint32Proxy.class
deleted file mode 100644
index 7368082..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedSint32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedSint64Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedSint64Proxy.class
deleted file mode 100644
index 0fe578e..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedSint64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedUint32Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedUint32Proxy.class
deleted file mode 100644
index df08a2f..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedUint32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedUint64Proxy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedUint64Proxy.class
deleted file mode 100644
index 0a5f46d..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl$RepeatedUint64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl.class
deleted file mode 100644
index 578eba9..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt.class
deleted file mode 100644
index 0826bd5..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKtKt.class b/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKtKt.class
deleted file mode 100644
index ef7251b..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/TestUnpackedTypesKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$1.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$1.class
deleted file mode 100644
index a70fd29..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$ForeignEnum$1.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$ForeignEnum$1.class
deleted file mode 100644
index 3858d28..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$ForeignEnum$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$ForeignEnum$ForeignEnumVerifier.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$ForeignEnum$ForeignEnumVerifier.class
deleted file mode 100644
index 87ada00..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$ForeignEnum$ForeignEnumVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$ForeignEnum.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$ForeignEnum.class
deleted file mode 100644
index c8344c9..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$ForeignEnum.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$ForeignMessage$Builder.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$ForeignMessage$Builder.class
deleted file mode 100644
index 0692b04..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$ForeignMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$ForeignMessage.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$ForeignMessage.class
deleted file mode 100644
index 03ebf28..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$ForeignMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$ForeignMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$ForeignMessageOrBuilder.class
deleted file mode 100644
index 87cf755..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$ForeignMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$NestedTestAllTypes$Builder.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$NestedTestAllTypes$Builder.class
deleted file mode 100644
index 8ffff0b..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$NestedTestAllTypes$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$NestedTestAllTypes.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$NestedTestAllTypes.class
deleted file mode 100644
index 2a717ca..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$NestedTestAllTypes.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$NestedTestAllTypesOrBuilder.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$NestedTestAllTypesOrBuilder.class
deleted file mode 100644
index 5d3b328..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$NestedTestAllTypesOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$1.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$1.class
deleted file mode 100644
index d2e402b..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$2.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$2.class
deleted file mode 100644
index e3fe505..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$2.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$Builder.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$Builder.class
deleted file mode 100644
index cdba04e..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$NestedEnum$1.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$NestedEnum$1.class
deleted file mode 100644
index bd60b8a..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$NestedEnum$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$NestedEnum$NestedEnumVerifier.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$NestedEnum$NestedEnumVerifier.class
deleted file mode 100644
index 34cced35..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$NestedEnum$NestedEnumVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$NestedEnum.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$NestedEnum.class
deleted file mode 100644
index d60f7ce..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$NestedEnum.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$NestedMessage$Builder.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$NestedMessage$Builder.class
deleted file mode 100644
index f994cc7..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$NestedMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$NestedMessage.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$NestedMessage.class
deleted file mode 100644
index 542c47d..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$NestedMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$NestedMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$NestedMessageOrBuilder.class
deleted file mode 100644
index aa56dcc..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$NestedMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$OneofFieldCase.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$OneofFieldCase.class
deleted file mode 100644
index 63c1c1a..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes$OneofFieldCase.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes.class
deleted file mode 100644
index ceaad4f..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypes.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypesOrBuilder.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypesOrBuilder.class
deleted file mode 100644
index d9f71ab0..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestAllTypesOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestEmptyMessage$Builder.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestEmptyMessage$Builder.class
deleted file mode 100644
index 34f55a9..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestEmptyMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestEmptyMessage.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestEmptyMessage.class
deleted file mode 100644
index b7ab618..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestEmptyMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestEmptyMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestEmptyMessageOrBuilder.class
deleted file mode 100644
index f114682..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestEmptyMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestMessageWithDummy$Builder.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestMessageWithDummy$Builder.class
deleted file mode 100644
index ec3b751..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestMessageWithDummy$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestMessageWithDummy.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestMessageWithDummy.class
deleted file mode 100644
index f8f82df..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestMessageWithDummy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestMessageWithDummyOrBuilder.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestMessageWithDummyOrBuilder.class
deleted file mode 100644
index a6b27c4..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestMessageWithDummyOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2$Builder.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2$Builder.class
deleted file mode 100644
index ca38d7f..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2$FooCase.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2$FooCase.class
deleted file mode 100644
index 759207f..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2$FooCase.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2$NestedEnum$1.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2$NestedEnum$1.class
deleted file mode 100644
index cc350ab..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2$NestedEnum$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2$NestedEnum$NestedEnumVerifier.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2$NestedEnum$NestedEnumVerifier.class
deleted file mode 100644
index a54190e..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2$NestedEnum$NestedEnumVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2$NestedEnum.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2$NestedEnum.class
deleted file mode 100644
index 6f98914..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2$NestedEnum.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2.class
deleted file mode 100644
index 0e66ba2..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2OrBuilder.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2OrBuilder.class
deleted file mode 100644
index 3a98fa5..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestOneof2OrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestPackedTypes$1.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestPackedTypes$1.class
deleted file mode 100644
index 1554e95..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestPackedTypes$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestPackedTypes$Builder.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestPackedTypes$Builder.class
deleted file mode 100644
index f413f87..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestPackedTypes$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestPackedTypes.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestPackedTypes.class
deleted file mode 100644
index 95bf72e..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestPackedTypes.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestPackedTypesOrBuilder.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestPackedTypesOrBuilder.class
deleted file mode 100644
index 5268f71..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestPackedTypesOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestUnpackedTypes$1.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestUnpackedTypes$1.class
deleted file mode 100644
index ac2b409..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestUnpackedTypes$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestUnpackedTypes$Builder.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestUnpackedTypes$Builder.class
deleted file mode 100644
index 4cc86b7..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestUnpackedTypes$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestUnpackedTypes.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestUnpackedTypes.class
deleted file mode 100644
index 00a9074..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestUnpackedTypes.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestUnpackedTypesOrBuilder.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestUnpackedTypesOrBuilder.class
deleted file mode 100644
index 93c2f4d..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3$TestUnpackedTypesOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3.class b/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3.class
deleted file mode 100644
index e840446..0000000
--- a/java/kotlin-lite/target/test-classes/proto3_unittest/UnittestProto3.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/ForeignMessageArenaLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/ForeignMessageArenaLiteKt$Dsl$Companion.class
deleted file mode 100644
index a158e85..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/ForeignMessageArenaLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/ForeignMessageArenaLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/ForeignMessageArenaLiteKt$Dsl.class
deleted file mode 100644
index 786d1d8..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/ForeignMessageArenaLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/ForeignMessageArenaLiteKt.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/ForeignMessageArenaLiteKt.class
deleted file mode 100644
index d73a23b..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/ForeignMessageArenaLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/ForeignMessageArenaLiteKtKt.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/ForeignMessageArenaLiteKtKt.class
deleted file mode 100644
index 614c79f..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/ForeignMessageArenaLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$1.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$1.class
deleted file mode 100644
index 728010a..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$ForeignMessageArenaLite$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$ForeignMessageArenaLite$Builder.class
deleted file mode 100644
index 7839bd2..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$ForeignMessageArenaLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$ForeignMessageArenaLite.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$ForeignMessageArenaLite.class
deleted file mode 100644
index eb8e033..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$ForeignMessageArenaLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$ForeignMessageArenaLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$ForeignMessageArenaLiteOrBuilder.class
deleted file mode 100644
index b67d005..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$ForeignMessageArenaLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$MapEnumLite$1.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$MapEnumLite$1.class
deleted file mode 100644
index 4a8a75f..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$MapEnumLite$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$MapEnumLite$MapEnumLiteVerifier.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$MapEnumLite$MapEnumLiteVerifier.class
deleted file mode 100644
index fa05896..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$MapEnumLite$MapEnumLiteVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$MapEnumLite.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$MapEnumLite.class
deleted file mode 100644
index 07a76a9..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$MapEnumLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$Proto2MapEnumLite$1.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$Proto2MapEnumLite$1.class
deleted file mode 100644
index 80e9014..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$Proto2MapEnumLite$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$Proto2MapEnumLite$Proto2MapEnumLiteVerifier.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$Proto2MapEnumLite$Proto2MapEnumLiteVerifier.class
deleted file mode 100644
index 763e8d9..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$Proto2MapEnumLite$Proto2MapEnumLiteVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$Proto2MapEnumLite.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$Proto2MapEnumLite.class
deleted file mode 100644
index 73da4be..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$Proto2MapEnumLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$Proto2MapEnumPlusExtraLite$1.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$Proto2MapEnumPlusExtraLite$1.class
deleted file mode 100644
index ae5bbc8..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$Proto2MapEnumPlusExtraLite$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$Proto2MapEnumPlusExtraLite$Proto2MapEnumPlusExtraLiteVerifier.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$Proto2MapEnumPlusExtraLite$Proto2MapEnumPlusExtraLiteVerifier.class
deleted file mode 100644
index c074452..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$Proto2MapEnumPlusExtraLite$Proto2MapEnumPlusExtraLiteVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$Proto2MapEnumPlusExtraLite.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$Proto2MapEnumPlusExtraLite.class
deleted file mode 100644
index 1f21349..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$Proto2MapEnumPlusExtraLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$Builder.class
deleted file mode 100644
index a42752a..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapBoolBoolDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapBoolBoolDefaultEntryHolder.class
deleted file mode 100644
index 0e828b2..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapBoolBoolDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapFixed32Fixed32DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapFixed32Fixed32DefaultEntryHolder.class
deleted file mode 100644
index f8d0b01..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapFixed32Fixed32DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapFixed64Fixed64DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapFixed64Fixed64DefaultEntryHolder.class
deleted file mode 100644
index bebf651..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapFixed64Fixed64DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32BytesDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32BytesDefaultEntryHolder.class
deleted file mode 100644
index 8288e85..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32BytesDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32DoubleDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32DoubleDefaultEntryHolder.class
deleted file mode 100644
index 72b9f35..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32DoubleDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32EnumDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32EnumDefaultEntryHolder.class
deleted file mode 100644
index 1e391a0..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32EnumDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32FloatDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32FloatDefaultEntryHolder.class
deleted file mode 100644
index c415c25..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32FloatDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32ForeignMessageDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32ForeignMessageDefaultEntryHolder.class
deleted file mode 100644
index a395ca3..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32ForeignMessageDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32Int32DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32Int32DefaultEntryHolder.class
deleted file mode 100644
index 609b1eb..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt32Int32DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt64Int64DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt64Int64DefaultEntryHolder.class
deleted file mode 100644
index 79ae3b5..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapInt64Int64DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapSfixed32Sfixed32DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapSfixed32Sfixed32DefaultEntryHolder.class
deleted file mode 100644
index 605f397..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapSfixed32Sfixed32DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapSfixed64Sfixed64DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapSfixed64Sfixed64DefaultEntryHolder.class
deleted file mode 100644
index b4820a2..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapSfixed64Sfixed64DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapSint32Sint32DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapSint32Sint32DefaultEntryHolder.class
deleted file mode 100644
index fb067dd..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapSint32Sint32DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapSint64Sint64DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapSint64Sint64DefaultEntryHolder.class
deleted file mode 100644
index 7234d56..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapSint64Sint64DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapStringStringDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapStringStringDefaultEntryHolder.class
deleted file mode 100644
index dde54b0..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapStringStringDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapUint32Uint32DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapUint32Uint32DefaultEntryHolder.class
deleted file mode 100644
index 0d4a668..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapUint32Uint32DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapUint64Uint64DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapUint64Uint64DefaultEntryHolder.class
deleted file mode 100644
index 724e902..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite$MapUint64Uint64DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite.class
deleted file mode 100644
index ac66aaf..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLiteOrBuilder.class
deleted file mode 100644
index 4f3a9a1..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestArenaMapLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapLite$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapLite$Builder.class
deleted file mode 100644
index f53378d..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapLite$KnownMapFieldDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapLite$KnownMapFieldDefaultEntryHolder.class
deleted file mode 100644
index 7bc0f21..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapLite$KnownMapFieldDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapLite$UnknownMapFieldDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapLite$UnknownMapFieldDefaultEntryHolder.class
deleted file mode 100644
index 4f49cea..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapLite$UnknownMapFieldDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapLite.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapLite.class
deleted file mode 100644
index 61c964a..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapLiteOrBuilder.class
deleted file mode 100644
index e31314a..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLite$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLite$Builder.class
deleted file mode 100644
index 284f968..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLite$KnownMapFieldDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLite$KnownMapFieldDefaultEntryHolder.class
deleted file mode 100644
index 5b73486..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLite$KnownMapFieldDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLite$UnknownMapFieldDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLite$UnknownMapFieldDefaultEntryHolder.class
deleted file mode 100644
index f27c944..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLite$UnknownMapFieldDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLite.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLite.class
deleted file mode 100644
index eacece2..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLiteOrBuilder.class
deleted file mode 100644
index 885b94f..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestEnumMapPlusExtraLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$Builder.class
deleted file mode 100644
index 0bba59a..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapBoolBoolDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapBoolBoolDefaultEntryHolder.class
deleted file mode 100644
index d79ada0..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapBoolBoolDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapFixed32Fixed32DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapFixed32Fixed32DefaultEntryHolder.class
deleted file mode 100644
index 47e377b..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapFixed32Fixed32DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapFixed64Fixed64DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapFixed64Fixed64DefaultEntryHolder.class
deleted file mode 100644
index 85eb2d8..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapFixed64Fixed64DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32BytesDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32BytesDefaultEntryHolder.class
deleted file mode 100644
index 3f0fb37..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32BytesDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32DoubleDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32DoubleDefaultEntryHolder.class
deleted file mode 100644
index 2e30b12..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32DoubleDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32EnumDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32EnumDefaultEntryHolder.class
deleted file mode 100644
index 871f4b1..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32EnumDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32FloatDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32FloatDefaultEntryHolder.class
deleted file mode 100644
index 0c94602..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32FloatDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32ForeignMessageDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32ForeignMessageDefaultEntryHolder.class
deleted file mode 100644
index bfc73ce..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32ForeignMessageDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32Int32DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32Int32DefaultEntryHolder.class
deleted file mode 100644
index 15b32cd..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt32Int32DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt64Int64DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt64Int64DefaultEntryHolder.class
deleted file mode 100644
index 9920b87..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapInt64Int64DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapSfixed32Sfixed32DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapSfixed32Sfixed32DefaultEntryHolder.class
deleted file mode 100644
index c18bb8b..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapSfixed32Sfixed32DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapSfixed64Sfixed64DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapSfixed64Sfixed64DefaultEntryHolder.class
deleted file mode 100644
index 8901f39..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapSfixed64Sfixed64DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapSint32Sint32DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapSint32Sint32DefaultEntryHolder.class
deleted file mode 100644
index 96d5052..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapSint32Sint32DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapSint64Sint64DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapSint64Sint64DefaultEntryHolder.class
deleted file mode 100644
index 79d7e3c..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapSint64Sint64DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapStringStringDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapStringStringDefaultEntryHolder.class
deleted file mode 100644
index f0c1bb28..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapStringStringDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapUint32Uint32DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapUint32Uint32DefaultEntryHolder.class
deleted file mode 100644
index 31427f4..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapUint32Uint32DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapUint64Uint64DefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapUint64Uint64DefaultEntryHolder.class
deleted file mode 100644
index 7546f34..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$MapUint64Uint64DefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$TeboringDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$TeboringDefaultEntryHolder.class
deleted file mode 100644
index e5d53f2..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite$TeboringDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite.class
deleted file mode 100644
index 429bbc3..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLiteOrBuilder.class
deleted file mode 100644
index f278599..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMapLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMessageMapLite$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMessageMapLite$Builder.class
deleted file mode 100644
index c0d9d5d..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMessageMapLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMessageMapLite$MapInt32MessageDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMessageMapLite$MapInt32MessageDefaultEntryHolder.class
deleted file mode 100644
index c9d4244..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMessageMapLite$MapInt32MessageDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMessageMapLite.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMessageMapLite.class
deleted file mode 100644
index d77996d..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMessageMapLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMessageMapLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMessageMapLiteOrBuilder.class
deleted file mode 100644
index f3810bd..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestMessageMapLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredLite$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredLite$Builder.class
deleted file mode 100644
index 7951eb5..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredLite.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredLite.class
deleted file mode 100644
index a66c29f..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredLiteOrBuilder.class
deleted file mode 100644
index 8ecc523..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredMessageMapLite$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredMessageMapLite$Builder.class
deleted file mode 100644
index 1105a5c..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredMessageMapLite$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredMessageMapLite$MapFieldDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredMessageMapLite$MapFieldDefaultEntryHolder.class
deleted file mode 100644
index a9ae4fb..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredMessageMapLite$MapFieldDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredMessageMapLite.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredMessageMapLite.class
deleted file mode 100644
index 5fdb663..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredMessageMapLite.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredMessageMapLiteOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredMessageMapLiteOrBuilder.class
deleted file mode 100644
index cd99039..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest$TestRequiredMessageMapLiteOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest.class
deleted file mode 100644
index e18ff06..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/MapLiteUnittest.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$Companion.class
deleted file mode 100644
index 5db8117..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapBoolBoolProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapBoolBoolProxy.class
deleted file mode 100644
index bb2103e..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapBoolBoolProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapFixed32Fixed32Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapFixed32Fixed32Proxy.class
deleted file mode 100644
index 4e0ee90..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapFixed32Fixed32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapFixed64Fixed64Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapFixed64Fixed64Proxy.class
deleted file mode 100644
index fe156ce..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapFixed64Fixed64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt32BytesProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt32BytesProxy.class
deleted file mode 100644
index 16d3b53..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt32BytesProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt32DoubleProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt32DoubleProxy.class
deleted file mode 100644
index 2e25e58..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt32DoubleProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt32EnumProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt32EnumProxy.class
deleted file mode 100644
index 05cf273..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt32EnumProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt32FloatProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt32FloatProxy.class
deleted file mode 100644
index 95e7e84..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt32FloatProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt32ForeignMessageProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt32ForeignMessageProxy.class
deleted file mode 100644
index 72c0fa1..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt32ForeignMessageProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt32Int32Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt32Int32Proxy.class
deleted file mode 100644
index 37237a6..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt32Int32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt64Int64Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt64Int64Proxy.class
deleted file mode 100644
index 16c23d1..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapInt64Int64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapSfixed32Sfixed32Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapSfixed32Sfixed32Proxy.class
deleted file mode 100644
index 8186257..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapSfixed32Sfixed32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapSfixed64Sfixed64Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapSfixed64Sfixed64Proxy.class
deleted file mode 100644
index 672681e..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapSfixed64Sfixed64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapSint32Sint32Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapSint32Sint32Proxy.class
deleted file mode 100644
index 593de42..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapSint32Sint32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapSint64Sint64Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapSint64Sint64Proxy.class
deleted file mode 100644
index 48c7cf6..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapSint64Sint64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapStringStringProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapStringStringProxy.class
deleted file mode 100644
index fea9794..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapStringStringProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapUint32Uint32Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapUint32Uint32Proxy.class
deleted file mode 100644
index f48a6aa..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapUint32Uint32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapUint64Uint64Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapUint64Uint64Proxy.class
deleted file mode 100644
index bc47efc..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl$MapUint64Uint64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl.class
deleted file mode 100644
index 2f4a9c9..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt.class
deleted file mode 100644
index 4aa248d..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKtKt.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKtKt.class
deleted file mode 100644
index 7cdd06f..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestArenaMapLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapLiteKt$Dsl$Companion.class
deleted file mode 100644
index a4be83c..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapLiteKt$Dsl$KnownMapFieldProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapLiteKt$Dsl$KnownMapFieldProxy.class
deleted file mode 100644
index fa76720..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapLiteKt$Dsl$KnownMapFieldProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapLiteKt$Dsl$UnknownMapFieldProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapLiteKt$Dsl$UnknownMapFieldProxy.class
deleted file mode 100644
index d2db092..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapLiteKt$Dsl$UnknownMapFieldProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapLiteKt$Dsl.class
deleted file mode 100644
index 2409500..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapLiteKt.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapLiteKt.class
deleted file mode 100644
index d0a1e02..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapLiteKtKt.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapLiteKtKt.class
deleted file mode 100644
index 0683e7a..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapPlusExtraLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapPlusExtraLiteKt$Dsl$Companion.class
deleted file mode 100644
index 3a326d5..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapPlusExtraLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapPlusExtraLiteKt$Dsl$KnownMapFieldProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapPlusExtraLiteKt$Dsl$KnownMapFieldProxy.class
deleted file mode 100644
index 300855a..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapPlusExtraLiteKt$Dsl$KnownMapFieldProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapPlusExtraLiteKt$Dsl$UnknownMapFieldProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapPlusExtraLiteKt$Dsl$UnknownMapFieldProxy.class
deleted file mode 100644
index c0091f9..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapPlusExtraLiteKt$Dsl$UnknownMapFieldProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapPlusExtraLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapPlusExtraLiteKt$Dsl.class
deleted file mode 100644
index 06524ce..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapPlusExtraLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapPlusExtraLiteKt.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapPlusExtraLiteKt.class
deleted file mode 100644
index 365f96b..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapPlusExtraLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapPlusExtraLiteKtKt.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapPlusExtraLiteKtKt.class
deleted file mode 100644
index af27cec..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestEnumMapPlusExtraLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$Companion.class
deleted file mode 100644
index 667cb0d..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapBoolBoolProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapBoolBoolProxy.class
deleted file mode 100644
index b1b0e74..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapBoolBoolProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapFixed32Fixed32Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapFixed32Fixed32Proxy.class
deleted file mode 100644
index 7c83132..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapFixed32Fixed32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapFixed64Fixed64Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapFixed64Fixed64Proxy.class
deleted file mode 100644
index 03463ab..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapFixed64Fixed64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt32BytesProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt32BytesProxy.class
deleted file mode 100644
index e7bd7e0..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt32BytesProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt32DoubleProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt32DoubleProxy.class
deleted file mode 100644
index c575b48..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt32DoubleProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt32EnumProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt32EnumProxy.class
deleted file mode 100644
index be79f16..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt32EnumProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt32FloatProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt32FloatProxy.class
deleted file mode 100644
index 173a52d..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt32FloatProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt32ForeignMessageProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt32ForeignMessageProxy.class
deleted file mode 100644
index dd8b848..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt32ForeignMessageProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt32Int32Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt32Int32Proxy.class
deleted file mode 100644
index 8129360..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt32Int32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt64Int64Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt64Int64Proxy.class
deleted file mode 100644
index e2ddfd1..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapInt64Int64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapSfixed32Sfixed32Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapSfixed32Sfixed32Proxy.class
deleted file mode 100644
index 45725f8..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapSfixed32Sfixed32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapSfixed64Sfixed64Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapSfixed64Sfixed64Proxy.class
deleted file mode 100644
index 6b78e07..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapSfixed64Sfixed64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapSint32Sint32Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapSint32Sint32Proxy.class
deleted file mode 100644
index 755c365..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapSint32Sint32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapSint64Sint64Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapSint64Sint64Proxy.class
deleted file mode 100644
index d243911..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapSint64Sint64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapStringStringProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapStringStringProxy.class
deleted file mode 100644
index 371dfd7..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapStringStringProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapUint32Uint32Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapUint32Uint32Proxy.class
deleted file mode 100644
index aa83332..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapUint32Uint32Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapUint64Uint64Proxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapUint64Uint64Proxy.class
deleted file mode 100644
index 07faded..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$MapUint64Uint64Proxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$TeboringProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$TeboringProxy.class
deleted file mode 100644
index 321baa7..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl$TeboringProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl.class
deleted file mode 100644
index 2c2d5d2..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt.class
deleted file mode 100644
index 3d10d7a..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKtKt.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKtKt.class
deleted file mode 100644
index 9762122..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMapLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMessageMapLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMessageMapLiteKt$Dsl$Companion.class
deleted file mode 100644
index c2bccf5..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMessageMapLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMessageMapLiteKt$Dsl$MapInt32MessageProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMessageMapLiteKt$Dsl$MapInt32MessageProxy.class
deleted file mode 100644
index d939365..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMessageMapLiteKt$Dsl$MapInt32MessageProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMessageMapLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMessageMapLiteKt$Dsl.class
deleted file mode 100644
index 795c2c9..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMessageMapLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMessageMapLiteKt.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMessageMapLiteKt.class
deleted file mode 100644
index eaafd44..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMessageMapLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMessageMapLiteKtKt.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMessageMapLiteKtKt.class
deleted file mode 100644
index f14a995..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestMessageMapLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredLiteKt$Dsl$Companion.class
deleted file mode 100644
index db5e124..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredLiteKt$Dsl.class
deleted file mode 100644
index 149ac73..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredLiteKt.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredLiteKt.class
deleted file mode 100644
index 8b5669b..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredLiteKtKt.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredLiteKtKt.class
deleted file mode 100644
index 3c39813..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredMessageMapLiteKt$Dsl$Companion.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredMessageMapLiteKt$Dsl$Companion.class
deleted file mode 100644
index bffd3b2..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredMessageMapLiteKt$Dsl$Companion.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredMessageMapLiteKt$Dsl$MapFieldProxy.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredMessageMapLiteKt$Dsl$MapFieldProxy.class
deleted file mode 100644
index 50e7bb0..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredMessageMapLiteKt$Dsl$MapFieldProxy.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredMessageMapLiteKt$Dsl.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredMessageMapLiteKt$Dsl.class
deleted file mode 100644
index b2d2350..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredMessageMapLiteKt$Dsl.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredMessageMapLiteKt.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredMessageMapLiteKt.class
deleted file mode 100644
index 9ced633..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredMessageMapLiteKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredMessageMapLiteKtKt.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredMessageMapLiteKtKt.class
deleted file mode 100644
index 699efee..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/TestRequiredMessageMapLiteKtKt.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$1.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$1.class
deleted file mode 100644
index fbe167b..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BarRequest$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BarRequest$Builder.class
deleted file mode 100644
index 69a537d..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BarRequest$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BarRequest.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BarRequest.class
deleted file mode 100644
index fc58bef..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BarRequest.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BarRequestOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BarRequestOrBuilder.class
deleted file mode 100644
index a0bf9d6..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BarRequestOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BarResponse$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BarResponse$Builder.class
deleted file mode 100644
index 61f42fa..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BarResponse$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BarResponse.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BarResponse.class
deleted file mode 100644
index a9e1dc8..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BarResponse.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BarResponseOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BarResponseOrBuilder.class
deleted file mode 100644
index c584447..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BarResponseOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BoolMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BoolMessage$Builder.class
deleted file mode 100644
index 19b6963..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BoolMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BoolMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BoolMessage.class
deleted file mode 100644
index e333c10..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BoolMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BoolMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BoolMessageOrBuilder.class
deleted file mode 100644
index 85072d5..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$BoolMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooClientMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooClientMessage$Builder.class
deleted file mode 100644
index d57645a..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooClientMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooClientMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooClientMessage.class
deleted file mode 100644
index b3a1a47..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooClientMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooClientMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooClientMessageOrBuilder.class
deleted file mode 100644
index 17dd238..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooClientMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooRequest$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooRequest$Builder.class
deleted file mode 100644
index 663d825..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooRequest$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooRequest.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooRequest.class
deleted file mode 100644
index bca13a7..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooRequest.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooRequestOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooRequestOrBuilder.class
deleted file mode 100644
index 52ac965..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooRequestOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooResponse$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooResponse$Builder.class
deleted file mode 100644
index 519387d..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooResponse$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooResponse.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooResponse.class
deleted file mode 100644
index 724a2d8..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooResponse.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooResponseOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooResponseOrBuilder.class
deleted file mode 100644
index 557352d..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooResponseOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooServerMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooServerMessage$Builder.class
deleted file mode 100644
index 13cad18..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooServerMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooServerMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooServerMessage.class
deleted file mode 100644
index 37a1cff..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooServerMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooServerMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooServerMessageOrBuilder.class
deleted file mode 100644
index babe01f..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$FooServerMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$ForeignEnum$1.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$ForeignEnum$1.class
deleted file mode 100644
index 866d079..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$ForeignEnum$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$ForeignEnum$ForeignEnumVerifier.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$ForeignEnum$ForeignEnumVerifier.class
deleted file mode 100644
index 8d00fdf..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$ForeignEnum$ForeignEnumVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$ForeignEnum.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$ForeignEnum.class
deleted file mode 100644
index 97bbfe1..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$ForeignEnum.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$ForeignMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$ForeignMessage$Builder.class
deleted file mode 100644
index 0c9efa2..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$ForeignMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$ForeignMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$ForeignMessage.class
deleted file mode 100644
index ccc3f8a..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$ForeignMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$ForeignMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$ForeignMessageOrBuilder.class
deleted file mode 100644
index 355c5e1..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$ForeignMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Int32Message$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Int32Message$Builder.class
deleted file mode 100644
index d31bc9e..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Int32Message$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Int32Message.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Int32Message.class
deleted file mode 100644
index f6ce8e9..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Int32Message.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Int32MessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Int32MessageOrBuilder.class
deleted file mode 100644
index cf6ba4d..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Int32MessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Int64Message$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Int64Message$Builder.class
deleted file mode 100644
index d8f93f5..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Int64Message$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Int64Message.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Int64Message.class
deleted file mode 100644
index ee813ff..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Int64Message.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Int64MessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Int64MessageOrBuilder.class
deleted file mode 100644
index 7e9e6f2..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Int64MessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$MoreBytes$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$MoreBytes$Builder.class
deleted file mode 100644
index bcfba05..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$MoreBytes$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$MoreBytes.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$MoreBytes.class
deleted file mode 100644
index 2d3093e..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$MoreBytes.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$MoreBytesOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$MoreBytesOrBuilder.class
deleted file mode 100644
index 5f0d899d..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$MoreBytesOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$MoreString$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$MoreString$Builder.class
deleted file mode 100644
index d032184..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$MoreString$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$MoreString.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$MoreString.class
deleted file mode 100644
index 83da822..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$MoreString.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$MoreStringOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$MoreStringOrBuilder.class
deleted file mode 100644
index cb74b1f..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$MoreStringOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$NestedTestAllTypes$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$NestedTestAllTypes$Builder.class
deleted file mode 100644
index 4ec6ab1..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$NestedTestAllTypes$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$NestedTestAllTypes.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$NestedTestAllTypes.class
deleted file mode 100644
index 4a57245..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$NestedTestAllTypes.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$NestedTestAllTypesOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$NestedTestAllTypesOrBuilder.class
deleted file mode 100644
index 3e6b4fa..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$NestedTestAllTypesOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OneBytes$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OneBytes$Builder.class
deleted file mode 100644
index f22e5a1..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OneBytes$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OneBytes.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OneBytes.class
deleted file mode 100644
index c5af9d7..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OneBytes.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OneBytesOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OneBytesOrBuilder.class
deleted file mode 100644
index 6eb1803..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OneBytesOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OneString$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OneString$Builder.class
deleted file mode 100644
index 5d7c5b6..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OneString$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OneString.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OneString.class
deleted file mode 100644
index c630969..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OneString.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OneStringOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OneStringOrBuilder.class
deleted file mode 100644
index 98ff647..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OneStringOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OptionalGroup_extension$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OptionalGroup_extension$Builder.class
deleted file mode 100644
index 9646c0e..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OptionalGroup_extension$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OptionalGroup_extension.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OptionalGroup_extension.class
deleted file mode 100644
index 9783f66..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OptionalGroup_extension.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OptionalGroup_extensionOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OptionalGroup_extensionOrBuilder.class
deleted file mode 100644
index ddfdad5..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$OptionalGroup_extensionOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$RepeatedGroup_extension$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$RepeatedGroup_extension$Builder.class
deleted file mode 100644
index 7cf40d3..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$RepeatedGroup_extension$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$RepeatedGroup_extension.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$RepeatedGroup_extension.class
deleted file mode 100644
index 0ae9bd4..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$RepeatedGroup_extension.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$RepeatedGroup_extensionOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$RepeatedGroup_extensionOrBuilder.class
deleted file mode 100644
index 88193eb..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$RepeatedGroup_extensionOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$SparseEnumMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$SparseEnumMessage$Builder.class
deleted file mode 100644
index a099d3e..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$SparseEnumMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$SparseEnumMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$SparseEnumMessage.class
deleted file mode 100644
index f033685..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$SparseEnumMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$SparseEnumMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$SparseEnumMessageOrBuilder.class
deleted file mode 100644
index 4b094ad..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$SparseEnumMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllExtensions$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllExtensions$Builder.class
deleted file mode 100644
index f32ab25..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllExtensions$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllExtensions.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllExtensions.class
deleted file mode 100644
index 849e4e4..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllExtensions.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllExtensionsOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllExtensionsOrBuilder.class
deleted file mode 100644
index 22ec5da..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllExtensionsOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$1.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$1.class
deleted file mode 100644
index 2738de6..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$2.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$2.class
deleted file mode 100644
index 53276a0..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$2.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$3.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$3.class
deleted file mode 100644
index ca96d80..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$3.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$Builder.class
deleted file mode 100644
index 9d2b3c5..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$NestedEnum$1.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$NestedEnum$1.class
deleted file mode 100644
index dacd681..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$NestedEnum$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$NestedEnum$NestedEnumVerifier.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$NestedEnum$NestedEnumVerifier.class
deleted file mode 100644
index 4e5bb10..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$NestedEnum$NestedEnumVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$NestedEnum.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$NestedEnum.class
deleted file mode 100644
index b51a4a7..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$NestedEnum.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$NestedMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$NestedMessage$Builder.class
deleted file mode 100644
index 05e402f..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$NestedMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$NestedMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$NestedMessage.class
deleted file mode 100644
index a2225fe..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$NestedMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$NestedMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$NestedMessageOrBuilder.class
deleted file mode 100644
index fda8ff6..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$NestedMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$OneofFieldCase.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$OneofFieldCase.class
deleted file mode 100644
index 1095254..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$OneofFieldCase.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$OptionalGroup$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$OptionalGroup$Builder.class
deleted file mode 100644
index d8e0efc..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$OptionalGroup$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$OptionalGroup.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$OptionalGroup.class
deleted file mode 100644
index e93df78..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$OptionalGroup.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$OptionalGroupOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$OptionalGroupOrBuilder.class
deleted file mode 100644
index 2310d4e..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$OptionalGroupOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$RepeatedGroup$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$RepeatedGroup$Builder.class
deleted file mode 100644
index facc5c7..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$RepeatedGroup$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$RepeatedGroup.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$RepeatedGroup.class
deleted file mode 100644
index 082014f..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$RepeatedGroup.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$RepeatedGroupOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$RepeatedGroupOrBuilder.class
deleted file mode 100644
index 0638277..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes$RepeatedGroupOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes.class
deleted file mode 100644
index 68178ba..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypes.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypesOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypesOrBuilder.class
deleted file mode 100644
index f19b220..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestAllTypesOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCamelCaseFieldNames$1.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCamelCaseFieldNames$1.class
deleted file mode 100644
index 5379307..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCamelCaseFieldNames$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCamelCaseFieldNames$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCamelCaseFieldNames$Builder.class
deleted file mode 100644
index f48eaf3..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCamelCaseFieldNames$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCamelCaseFieldNames.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCamelCaseFieldNames.class
deleted file mode 100644
index 680c11f..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCamelCaseFieldNames.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCamelCaseFieldNamesOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCamelCaseFieldNamesOrBuilder.class
deleted file mode 100644
index f23ccb3..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCamelCaseFieldNamesOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCommentInjectionMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCommentInjectionMessage$Builder.class
deleted file mode 100644
index 9024c7d..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCommentInjectionMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCommentInjectionMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCommentInjectionMessage.class
deleted file mode 100644
index 8d0a8ae..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCommentInjectionMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCommentInjectionMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCommentInjectionMessageOrBuilder.class
deleted file mode 100644
index f5eb042..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestCommentInjectionMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedFields$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedFields$Builder.class
deleted file mode 100644
index 409d882..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedFields$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedFields$OneofFieldsCase.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedFields$OneofFieldsCase.class
deleted file mode 100644
index b723f45..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedFields$OneofFieldsCase.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedFields.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedFields.class
deleted file mode 100644
index a3cf537..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedFields.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedFieldsOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedFieldsOrBuilder.class
deleted file mode 100644
index c8764ab..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedFieldsOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedMessage$Builder.class
deleted file mode 100644
index 9b2617a..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedMessage.class
deleted file mode 100644
index 3fde09c..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedMessageOrBuilder.class
deleted file mode 100644
index 6de2216..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDeprecatedMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$Bar$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$Bar$Builder.class
deleted file mode 100644
index cbb4f50..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$Bar$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$Bar.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$Bar.class
deleted file mode 100644
index 4fea5b4..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$Bar.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$BarOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$BarOrBuilder.class
deleted file mode 100644
index 0144fd9..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$BarOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$Builder.class
deleted file mode 100644
index 410180e..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$Foo$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$Foo$Builder.class
deleted file mode 100644
index 43de780..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$Foo$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$Foo.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$Foo.class
deleted file mode 100644
index 53ba6e4..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$Foo.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$FooOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$FooOrBuilder.class
deleted file mode 100644
index bae5e30..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber$FooOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber.class
deleted file mode 100644
index 34be3e7..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumber.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumberOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumberOrBuilder.class
deleted file mode 100644
index 768a18c..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDupFieldNumberOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$Builder.class
deleted file mode 100644
index 1f59bca..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicEnumType$1.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicEnumType$1.class
deleted file mode 100644
index 586863b..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicEnumType$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicEnumType$DynamicEnumTypeVerifier.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicEnumType$DynamicEnumTypeVerifier.class
deleted file mode 100644
index 5d49306..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicEnumType$DynamicEnumTypeVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicEnumType.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicEnumType.class
deleted file mode 100644
index 90f6e27..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicEnumType.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicMessageType$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicMessageType$Builder.class
deleted file mode 100644
index 9791ecb..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicMessageType$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicMessageType.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicMessageType.class
deleted file mode 100644
index 62c866a..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicMessageType.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicMessageTypeOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicMessageTypeOrBuilder.class
deleted file mode 100644
index e4a98fe..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions$DynamicMessageTypeOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions.class
deleted file mode 100644
index a47d7f0..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensions.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensionsOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensionsOrBuilder.class
deleted file mode 100644
index 4db25f6..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestDynamicExtensionsOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEagerMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEagerMessage$Builder.class
deleted file mode 100644
index ff743f3..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEagerMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEagerMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEagerMessage.class
deleted file mode 100644
index 0842d34..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEagerMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEagerMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEagerMessageOrBuilder.class
deleted file mode 100644
index d450735..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEagerMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEmptyMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEmptyMessage$Builder.class
deleted file mode 100644
index 668945d..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEmptyMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEmptyMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEmptyMessage.class
deleted file mode 100644
index 53a2bec..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEmptyMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEmptyMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEmptyMessageOrBuilder.class
deleted file mode 100644
index 7759464..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEmptyMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEmptyMessageWithExtensions$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEmptyMessageWithExtensions$Builder.class
deleted file mode 100644
index e3ef7e2..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEmptyMessageWithExtensions$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEmptyMessageWithExtensions.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEmptyMessageWithExtensions.class
deleted file mode 100644
index fea26bf..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEmptyMessageWithExtensions.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEmptyMessageWithExtensionsOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEmptyMessageWithExtensionsOrBuilder.class
deleted file mode 100644
index 00ded2c..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEmptyMessageWithExtensionsOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEnumWithDupValue$1.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEnumWithDupValue$1.class
deleted file mode 100644
index 156b7f4..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEnumWithDupValue$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEnumWithDupValue$TestEnumWithDupValueVerifier.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEnumWithDupValue$TestEnumWithDupValueVerifier.class
deleted file mode 100644
index 8859e1b..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEnumWithDupValue$TestEnumWithDupValueVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEnumWithDupValue.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEnumWithDupValue.class
deleted file mode 100644
index 4a87797..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestEnumWithDupValue.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionInsideTable$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionInsideTable$Builder.class
deleted file mode 100644
index 7bf1afd..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionInsideTable$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionInsideTable.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionInsideTable.class
deleted file mode 100644
index 7890607..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionInsideTable.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionInsideTableOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionInsideTableOrBuilder.class
deleted file mode 100644
index 82097cf..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionInsideTableOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings1$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings1$Builder.class
deleted file mode 100644
index e45ec82..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings1$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings1.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings1.class
deleted file mode 100644
index 4ced9da..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings1OrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings1OrBuilder.class
deleted file mode 100644
index 3019621..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings1OrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings2$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings2$Builder.class
deleted file mode 100644
index 1af35d1..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings2$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings2$TestExtensionOrderings3$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings2$TestExtensionOrderings3$Builder.class
deleted file mode 100644
index e2d683f..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings2$TestExtensionOrderings3$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings2$TestExtensionOrderings3.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings2$TestExtensionOrderings3.class
deleted file mode 100644
index 4c295f0..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings2$TestExtensionOrderings3.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings2$TestExtensionOrderings3OrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings2$TestExtensionOrderings3OrBuilder.class
deleted file mode 100644
index 919077f..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings2$TestExtensionOrderings3OrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings2.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings2.class
deleted file mode 100644
index 1591fc5..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings2.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings2OrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings2OrBuilder.class
deleted file mode 100644
index e7829e5..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionOrderings2OrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionRangeSerialize$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionRangeSerialize$Builder.class
deleted file mode 100644
index 3ff10c9..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionRangeSerialize$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionRangeSerialize.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionRangeSerialize.class
deleted file mode 100644
index d2a735f..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionRangeSerialize.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionRangeSerializeOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionRangeSerializeOrBuilder.class
deleted file mode 100644
index ea4bc8d..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtensionRangeSerializeOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtremeDefaultValues$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtremeDefaultValues$Builder.class
deleted file mode 100644
index 49286db..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtremeDefaultValues$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtremeDefaultValues.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtremeDefaultValues.class
deleted file mode 100644
index 1f489c6..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtremeDefaultValues.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtremeDefaultValuesOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtremeDefaultValuesOrBuilder.class
deleted file mode 100644
index f5acd20..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestExtremeDefaultValuesOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestFieldOrderings$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestFieldOrderings$Builder.class
deleted file mode 100644
index ff16719..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestFieldOrderings$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestFieldOrderings$NestedMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestFieldOrderings$NestedMessage$Builder.class
deleted file mode 100644
index 019ffa4..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestFieldOrderings$NestedMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestFieldOrderings$NestedMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestFieldOrderings$NestedMessage.class
deleted file mode 100644
index 66289a1..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestFieldOrderings$NestedMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestFieldOrderings$NestedMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestFieldOrderings$NestedMessageOrBuilder.class
deleted file mode 100644
index bf20eb3..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestFieldOrderings$NestedMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestFieldOrderings.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestFieldOrderings.class
deleted file mode 100644
index 7f51587..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestFieldOrderings.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestFieldOrderingsOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestFieldOrderingsOrBuilder.class
deleted file mode 100644
index aee794c..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestFieldOrderingsOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestForeignNested$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestForeignNested$Builder.class
deleted file mode 100644
index 39f0a9d..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestForeignNested$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestForeignNested.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestForeignNested.class
deleted file mode 100644
index 83a3d64..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestForeignNested.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestForeignNestedOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestForeignNestedOrBuilder.class
deleted file mode 100644
index 0824f51..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestForeignNestedOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroup$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroup$Builder.class
deleted file mode 100644
index 1d62a1f..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroup$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroup$OptionalGroup$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroup$OptionalGroup$Builder.class
deleted file mode 100644
index 8da2679..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroup$OptionalGroup$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroup$OptionalGroup.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroup$OptionalGroup.class
deleted file mode 100644
index 9cfcbed..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroup$OptionalGroup.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroup$OptionalGroupOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroup$OptionalGroupOrBuilder.class
deleted file mode 100644
index 4bcf458..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroup$OptionalGroupOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroup.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroup.class
deleted file mode 100644
index 037dc8f..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroup.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroupExtension$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroupExtension$Builder.class
deleted file mode 100644
index 2fcf3ef..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroupExtension$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroupExtension.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroupExtension.class
deleted file mode 100644
index 1a12e79..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroupExtension.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroupExtensionOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroupExtensionOrBuilder.class
deleted file mode 100644
index e7801cc..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroupExtensionOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroupOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroupOrBuilder.class
deleted file mode 100644
index e741b23..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestGroupOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers$Builder.class
deleted file mode 100644
index 86368f1..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers$OneofFieldCase.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers$OneofFieldCase.class
deleted file mode 100644
index 194eb2c..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers$OneofFieldCase.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers$OptionalGroup$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers$OptionalGroup$Builder.class
deleted file mode 100644
index c47e0bf..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers$OptionalGroup$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers$OptionalGroup.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers$OptionalGroup.class
deleted file mode 100644
index bb9fff8..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers$OptionalGroup.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers$OptionalGroupOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers$OptionalGroupOrBuilder.class
deleted file mode 100644
index 51f5c8b..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers$OptionalGroupOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers$StringStringMapDefaultEntryHolder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers$StringStringMapDefaultEntryHolder.class
deleted file mode 100644
index 6d4f001..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers$StringStringMapDefaultEntryHolder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers.class
deleted file mode 100644
index dda28b7..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbers.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbersOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbersOrBuilder.class
deleted file mode 100644
index e34a522..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestHugeFieldNumbersOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$Builder.class
deleted file mode 100644
index d3c5377..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage$Builder.class
deleted file mode 100644
index 21af6ef..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage$SubGroup$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage$SubGroup$Builder.class
deleted file mode 100644
index 9c59828..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage$SubGroup$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage$SubGroup.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage$SubGroup.class
deleted file mode 100644
index 2901bce..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage$SubGroup.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage$SubGroupOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage$SubGroupOrBuilder.class
deleted file mode 100644
index 9db6dd7..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage$SubGroupOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage.class
deleted file mode 100644
index 15adf92..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$SubMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$SubMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$SubMessageOrBuilder.class
deleted file mode 100644
index b7f5da1..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized$SubMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized.class
deleted file mode 100644
index 3f352a9..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitialized.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitializedOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitializedOrBuilder.class
deleted file mode 100644
index abd2ac9..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestIsInitializedOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestJsonName$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestJsonName$Builder.class
deleted file mode 100644
index d60ac70..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestJsonName$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestJsonName.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestJsonName.class
deleted file mode 100644
index a638e38..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestJsonName.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestJsonNameOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestJsonNameOrBuilder.class
deleted file mode 100644
index a1eecab..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestJsonNameOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestLazyMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestLazyMessage$Builder.class
deleted file mode 100644
index 9fdf7a4..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestLazyMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestLazyMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestLazyMessage.class
deleted file mode 100644
index 9e69c00..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestLazyMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestLazyMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestLazyMessageOrBuilder.class
deleted file mode 100644
index 012cf0c..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestLazyMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMultipleExtensionRanges$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMultipleExtensionRanges$Builder.class
deleted file mode 100644
index 4536187..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMultipleExtensionRanges$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMultipleExtensionRanges.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMultipleExtensionRanges.class
deleted file mode 100644
index 6eb265c..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMultipleExtensionRanges.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMultipleExtensionRangesOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMultipleExtensionRangesOrBuilder.class
deleted file mode 100644
index 203df64..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMultipleExtensionRangesOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$Builder.class
deleted file mode 100644
index 4f17c35..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$SubGroup$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$SubGroup$Builder.class
deleted file mode 100644
index e49bcec..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$SubGroup$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$SubGroup.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$SubGroup.class
deleted file mode 100644
index e20ed33..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$SubGroup.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$SubGroupOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$SubGroupOrBuilder.class
deleted file mode 100644
index 9602e84..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$SubGroupOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$SubMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$SubMessage$Builder.class
deleted file mode 100644
index 01d7308..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$SubMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$SubMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$SubMessage.class
deleted file mode 100644
index 8f61b47..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$SubMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$SubMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$SubMessageOrBuilder.class
deleted file mode 100644
index 681b7a9..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA$SubMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA.class
deleted file mode 100644
index aa42f36..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionA.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionAOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionAOrBuilder.class
deleted file mode 100644
index 8453f1d..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionAOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionB$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionB$Builder.class
deleted file mode 100644
index 910bf6a..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionB$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionB.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionB.class
deleted file mode 100644
index bb8c44e..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionB.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionBOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionBOrBuilder.class
deleted file mode 100644
index 696527d..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestMutualRecursionBOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedExtension$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedExtension$Builder.class
deleted file mode 100644
index 0d10709..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedExtension$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedExtension$OptionalGroup_extension$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedExtension$OptionalGroup_extension$Builder.class
deleted file mode 100644
index 958d763..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedExtension$OptionalGroup_extension$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedExtension$OptionalGroup_extension.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedExtension$OptionalGroup_extension.class
deleted file mode 100644
index 56e9d35..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedExtension$OptionalGroup_extension.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedExtension$OptionalGroup_extensionOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedExtension$OptionalGroup_extensionOrBuilder.class
deleted file mode 100644
index fcd5cbf..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedExtension$OptionalGroup_extensionOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedExtension.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedExtension.class
deleted file mode 100644
index 4f506f3..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedExtension.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedExtensionOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedExtensionOrBuilder.class
deleted file mode 100644
index ad349de..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedExtensionOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedMessageHasBits$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedMessageHasBits$Builder.class
deleted file mode 100644
index d8eaedf..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedMessageHasBits$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedMessageHasBits$NestedMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedMessageHasBits$NestedMessage$Builder.class
deleted file mode 100644
index c4c26fb..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedMessageHasBits$NestedMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedMessageHasBits$NestedMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedMessageHasBits$NestedMessage.class
deleted file mode 100644
index 380dca2..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedMessageHasBits$NestedMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedMessageHasBits$NestedMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedMessageHasBits$NestedMessageOrBuilder.class
deleted file mode 100644
index 574c801..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedMessageHasBits$NestedMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedMessageHasBits.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedMessageHasBits.class
deleted file mode 100644
index 24a3c77..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedMessageHasBits.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedMessageHasBitsOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedMessageHasBitsOrBuilder.class
deleted file mode 100644
index 872f715..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestNestedMessageHasBitsOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof$Builder.class
deleted file mode 100644
index f01ebdc..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof$FooCase.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof$FooCase.class
deleted file mode 100644
index 3f625d1..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof$FooCase.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof$FooGroup$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof$FooGroup$Builder.class
deleted file mode 100644
index 11ad2b8..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof$FooGroup$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof$FooGroup.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof$FooGroup.class
deleted file mode 100644
index 3203382..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof$FooGroup.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof$FooGroupOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof$FooGroupOrBuilder.class
deleted file mode 100644
index a7b4eb2..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof$FooGroupOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof.class
deleted file mode 100644
index 6e62904..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$BarCase.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$BarCase.class
deleted file mode 100644
index 5ae565d..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$BarCase.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$Builder.class
deleted file mode 100644
index 90675f5..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$FooCase.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$FooCase.class
deleted file mode 100644
index 133f79b..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$FooCase.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$FooGroup$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$FooGroup$Builder.class
deleted file mode 100644
index 5141053..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$FooGroup$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$FooGroup.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$FooGroup.class
deleted file mode 100644
index e321fa8..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$FooGroup.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$FooGroupOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$FooGroupOrBuilder.class
deleted file mode 100644
index de29b91..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$FooGroupOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$NestedEnum$1.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$NestedEnum$1.class
deleted file mode 100644
index da0addd..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$NestedEnum$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$NestedEnum$NestedEnumVerifier.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$NestedEnum$NestedEnumVerifier.class
deleted file mode 100644
index 8f1cc7c..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$NestedEnum$NestedEnumVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$NestedEnum.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$NestedEnum.class
deleted file mode 100644
index 8a010c6..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$NestedEnum.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$NestedMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$NestedMessage$Builder.class
deleted file mode 100644
index 4d6011e..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$NestedMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$NestedMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$NestedMessage.class
deleted file mode 100644
index 55cfd78..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$NestedMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$NestedMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$NestedMessageOrBuilder.class
deleted file mode 100644
index 5888f35..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2$NestedMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2.class
deleted file mode 100644
index ddc47de..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2OrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2OrBuilder.class
deleted file mode 100644
index bb56865..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneof2OrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible$Builder.class
deleted file mode 100644
index 9f636db..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible$FooGroup$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible$FooGroup$Builder.class
deleted file mode 100644
index 0541e4e..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible$FooGroup$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible$FooGroup.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible$FooGroup.class
deleted file mode 100644
index 6d122e3..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible$FooGroup.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible$FooGroupOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible$FooGroupOrBuilder.class
deleted file mode 100644
index 2b80878..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible$FooGroupOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible.class
deleted file mode 100644
index ba5b898..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofBackwardsCompatible.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofBackwardsCompatibleOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofBackwardsCompatibleOrBuilder.class
deleted file mode 100644
index e01a8ba..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofBackwardsCompatibleOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofOrBuilder.class
deleted file mode 100644
index 35ef017..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestOneofOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedExtensions$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedExtensions$Builder.class
deleted file mode 100644
index b6c2789..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedExtensions$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedExtensions.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedExtensions.class
deleted file mode 100644
index 77584c4..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedExtensions.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedExtensionsOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedExtensionsOrBuilder.class
deleted file mode 100644
index ec54099..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedExtensionsOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedTypes$1.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedTypes$1.class
deleted file mode 100644
index 35477be..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedTypes$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedTypes$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedTypes$Builder.class
deleted file mode 100644
index d578c53..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedTypes$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedTypes.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedTypes.class
deleted file mode 100644
index 484b708..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedTypes.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedTypesOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedTypesOrBuilder.class
deleted file mode 100644
index 169ede3..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPackedTypesOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$Builder.class
deleted file mode 100644
index adf69b5..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$OptionalGroup$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$OptionalGroup$Builder.class
deleted file mode 100644
index b921c94..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$OptionalGroup$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$OptionalGroup.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$OptionalGroup.class
deleted file mode 100644
index 4eaf212..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$OptionalGroup.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$OptionalGroupOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$OptionalGroupOrBuilder.class
deleted file mode 100644
index c7a7db7..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$OptionalGroupOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Builder.class
deleted file mode 100644
index 808f4b2..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group1$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group1$Builder.class
deleted file mode 100644
index 45e9e5b..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group1$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group1.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group1.class
deleted file mode 100644
index b008275..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group1OrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group1OrBuilder.class
deleted file mode 100644
index 5e30fa4..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group1OrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group2$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group2$Builder.class
deleted file mode 100644
index d098a4b..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group2$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group2.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group2.class
deleted file mode 100644
index f55bccc..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group2.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group2OrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group2OrBuilder.class
deleted file mode 100644
index 27db1cf..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator$Group2OrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator.class
deleted file mode 100644
index dc7b8ea..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGenerator.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGeneratorOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGeneratorOrBuilder.class
deleted file mode 100644
index f4a5fdc..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedFieldsGeneratorOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedGroup$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedGroup$Builder.class
deleted file mode 100644
index 24fbb15..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedGroup$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedGroup.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedGroup.class
deleted file mode 100644
index 7e4fc3b..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedGroup.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedGroupOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedGroupOrBuilder.class
deleted file mode 100644
index 282f2cc..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge$RepeatedGroupOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge.class
deleted file mode 100644
index f6d0afe..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMerge.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMergeOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMergeOrBuilder.class
deleted file mode 100644
index d3a56ce..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestParsingMergeOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$Builder.class
deleted file mode 100644
index ad96de3..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage$Builder.class
deleted file mode 100644
index 0d0d054..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage$NestedNestedMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage$NestedNestedMessage$Builder.class
deleted file mode 100644
index 19df0b9..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage$NestedNestedMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage$NestedNestedMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage$NestedNestedMessage.class
deleted file mode 100644
index 1342391..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage$NestedNestedMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage$NestedNestedMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage$NestedNestedMessageOrBuilder.class
deleted file mode 100644
index 09272cb..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage$NestedNestedMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage.class
deleted file mode 100644
index 0ea440e..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessageOrBuilder.class
deleted file mode 100644
index 2711e01..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage$NestedMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage.class
deleted file mode 100644
index e35cebe..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessageOrBuilder.class
deleted file mode 100644
index dbe9eb5..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestPickleNestedMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestReallyLargeTagNumber$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestReallyLargeTagNumber$Builder.class
deleted file mode 100644
index dfcd4dd..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestReallyLargeTagNumber$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestReallyLargeTagNumber.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestReallyLargeTagNumber.class
deleted file mode 100644
index d4da2de..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestReallyLargeTagNumber.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestReallyLargeTagNumberOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestReallyLargeTagNumberOrBuilder.class
deleted file mode 100644
index 148aac9..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestReallyLargeTagNumberOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRecursiveMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRecursiveMessage$Builder.class
deleted file mode 100644
index 5ec4b2e..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRecursiveMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRecursiveMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRecursiveMessage.class
deleted file mode 100644
index 0663ca9..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRecursiveMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRecursiveMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRecursiveMessageOrBuilder.class
deleted file mode 100644
index c384b4e..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRecursiveMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRepeatedScalarDifferentTagSizes$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRepeatedScalarDifferentTagSizes$Builder.class
deleted file mode 100644
index 041279e..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRepeatedScalarDifferentTagSizes$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRepeatedScalarDifferentTagSizes.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRepeatedScalarDifferentTagSizes.class
deleted file mode 100644
index 8bbdd7f..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRepeatedScalarDifferentTagSizes.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRepeatedScalarDifferentTagSizesOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRepeatedScalarDifferentTagSizesOrBuilder.class
deleted file mode 100644
index e6cb34e..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRepeatedScalarDifferentTagSizesOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequired$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequired$Builder.class
deleted file mode 100644
index f6a7f15..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequired$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequired.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequired.class
deleted file mode 100644
index b5100aa..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequired.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredForeign$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredForeign$Builder.class
deleted file mode 100644
index d05c50a..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredForeign$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredForeign.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredForeign.class
deleted file mode 100644
index acc6604..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredForeign.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredForeignOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredForeignOrBuilder.class
deleted file mode 100644
index e84dde5..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredForeignOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredMessage$Builder.class
deleted file mode 100644
index 10ec346..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredMessage.class
deleted file mode 100644
index be36366..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredMessageOrBuilder.class
deleted file mode 100644
index 2b824e7..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneof$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneof$Builder.class
deleted file mode 100644
index 5ba0251..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneof$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneof$FooCase.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneof$FooCase.class
deleted file mode 100644
index e403313..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneof$FooCase.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneof$NestedMessage$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneof$NestedMessage$Builder.class
deleted file mode 100644
index ad7d5db..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneof$NestedMessage$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneof$NestedMessage.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneof$NestedMessage.class
deleted file mode 100644
index 8600962..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneof$NestedMessage.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneof$NestedMessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneof$NestedMessageOrBuilder.class
deleted file mode 100644
index fe48fd5..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneof$NestedMessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneof.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneof.class
deleted file mode 100644
index 4a5f5b0..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneof.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneofOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneofOrBuilder.class
deleted file mode 100644
index 500f021..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOneofOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOrBuilder.class
deleted file mode 100644
index 9e390ae..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestRequiredOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestReservedFields$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestReservedFields$Builder.class
deleted file mode 100644
index 966df1a..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestReservedFields$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestReservedFields.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestReservedFields.class
deleted file mode 100644
index b99f1f8..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestReservedFields.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestReservedFieldsOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestReservedFieldsOrBuilder.class
deleted file mode 100644
index de739f1..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestReservedFieldsOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestSparseEnum$1.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestSparseEnum$1.class
deleted file mode 100644
index 2f61d9e..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestSparseEnum$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestSparseEnum$TestSparseEnumVerifier.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestSparseEnum$TestSparseEnumVerifier.class
deleted file mode 100644
index c2885fb..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestSparseEnum$TestSparseEnumVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestSparseEnum.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestSparseEnum.class
deleted file mode 100644
index 4543a0a..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestSparseEnum.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedExtensions$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedExtensions$Builder.class
deleted file mode 100644
index 6ce6892..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedExtensions$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedExtensions.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedExtensions.class
deleted file mode 100644
index 29b9dde..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedExtensions.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedExtensionsOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedExtensionsOrBuilder.class
deleted file mode 100644
index f6651ee..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedExtensionsOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedTypes$1.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedTypes$1.class
deleted file mode 100644
index 3bb7ebe..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedTypes$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedTypes$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedTypes$Builder.class
deleted file mode 100644
index 9202fb3..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedTypes$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedTypes.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedTypes.class
deleted file mode 100644
index 6a2d8fc..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedTypes.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedTypesOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedTypesOrBuilder.class
deleted file mode 100644
index 89a2bd4..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$TestUnpackedTypesOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Uint32Message$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Uint32Message$Builder.class
deleted file mode 100644
index 515333e..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Uint32Message$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Uint32Message.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Uint32Message.class
deleted file mode 100644
index 6498701..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Uint32Message.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Uint32MessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Uint32MessageOrBuilder.class
deleted file mode 100644
index 68383ab..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Uint32MessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Uint64Message$Builder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Uint64Message$Builder.class
deleted file mode 100644
index f148df3..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Uint64Message$Builder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Uint64Message.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Uint64Message.class
deleted file mode 100644
index 43e5331..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Uint64Message.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Uint64MessageOrBuilder.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Uint64MessageOrBuilder.class
deleted file mode 100644
index 3ff13c5..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$Uint64MessageOrBuilder.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$VeryLargeEnum$1.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$VeryLargeEnum$1.class
deleted file mode 100644
index 1fc9da6..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$VeryLargeEnum$1.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$VeryLargeEnum$VeryLargeEnumVerifier.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$VeryLargeEnum$VeryLargeEnumVerifier.class
deleted file mode 100644
index 20fc098..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$VeryLargeEnum$VeryLargeEnumVerifier.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$VeryLargeEnum.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$VeryLargeEnum.class
deleted file mode 100644
index cce65eb..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto$VeryLargeEnum.class
+++ /dev/null
Binary files differ
diff --git a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto.class b/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto.class
deleted file mode 100644
index d984fce..0000000
--- a/java/kotlin-lite/target/test-classes/protobuf_unittest/UnittestProto.class
+++ /dev/null
Binary files differ
diff --git a/java/lite/generate-test-sources-build.xml b/java/lite/generate-test-sources-build.xml
index 6af99de..65e62ce 100644
--- a/java/lite/generate-test-sources-build.xml
+++ b/java/lite/generate-test-sources-build.xml
@@ -4,9 +4,7 @@
         <arg value="--java_out=lite:${generated.testsources.dir}"/>
         <arg value="--proto_path=${protobuf.source.dir}"/>
         <arg value="--proto_path=${protobuf.basedir}/java/core/${test.proto.dir}"/>
-        <arg value="--experimental_allow_proto3_optional"/>
         <arg value="${protobuf.source.dir}/google/protobuf/descriptor.proto"/>
-        <arg value="${protobuf.source.dir}/google/protobuf/map_lite_unittest.proto"/>
         <arg value="${protobuf.source.dir}/google/protobuf/unittest.proto"/>
         <arg value="${protobuf.source.dir}/google/protobuf/unittest_import.proto"/>
         <arg value="${protobuf.source.dir}/google/protobuf/unittest_import_lite.proto"/>
diff --git a/java/lite/pom.xml b/java/lite/pom.xml
index 0aafd3f..021eac0 100644
--- a/java/lite/pom.xml
+++ b/java/lite/pom.xml
@@ -38,11 +38,6 @@
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava-testlib</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
       <groupId>com.google.truth</groupId>
       <artifactId>truth</artifactId>
       <scope>test</scope>
@@ -90,7 +85,7 @@
               <goal>copy-resources</goal>
             </goals>
             <configuration>
-              <outputDirectory>${generated.sources.dir}/java/com/google/protobuf</outputDirectory>
+              <outputDirectory>${generated.sources.dir}/com/google/protobuf</outputDirectory>
               <resources>
                 <resource>
                   <directory>${basedir}/../core/src/main/java/com/google/protobuf</directory>
@@ -345,4 +340,5 @@
       </plugin>
     </plugins>
   </build>
+
 </project>
diff --git a/third_party/build_defs/BUILD b/third_party/build_defs/BUILD
deleted file mode 100644
index 15cf88c..0000000
--- a/third_party/build_defs/BUILD
+++ /dev/null
@@ -1,20 +0,0 @@
-load("//tools/build_defs/testing:bzl_library.bzl", "bzl_library")
-
-licenses(["notice"])
-
-bzl_library(
-    name = "kt_jvm_proto_library_helper",
-    srcs = ["kt_jvm_proto_library.internal.bzl"],
-    visibility = ["//visibility:private"],
-    deps = [
-        "//tools/build_defs/kotlin/release/rules:android_jvm_compile_bzl",
-        "//tools/build_defs/kotlin/release/toolchains/kotlin_jvm:toolchain_bzl",
-    ],
-)
-
-bzl_library(
-    name = "kt_jvm_proto_library",
-    srcs = ["kt_jvm_proto_library.bzl"],
-    visibility = ["//visibility:private"],
-    deps = [":kt_jvm_proto_library_helper"],
-)
diff --git a/third_party/build_defs/kt_jvm_proto_library.bzl b/third_party/build_defs/kt_jvm_proto_library.bzl
deleted file mode 100644
index 5e5115f..0000000
--- a/third_party/build_defs/kt_jvm_proto_library.bzl
+++ /dev/null
@@ -1,140 +0,0 @@
-"""Definitions for Kotlin proto libraries."""
-
-load(":kt_jvm_proto_library.internal.bzl", _kt_proto_library_helper = "kt_proto_library_helper")
-load("//devtools/build_cleaner/skylark:build_defs.bzl", "register_extension_info")
-
-def _lite_proto_name(name):
-    return ":%s_DO_NOT_DEPEND_java_lite_proto" % name
-
-def _proto_name(name):
-    return ":%s_DO_NOT_DEPEND_java_proto" % name
-
-def kt_jvm_lite_proto_library(
-        name,
-        deps = None,
-        tags = None,
-        testonly = None,
-        compatible_with = None,
-        restricted_to = None,
-        visibility = None,
-        deprecation = None,
-        features = []):
-    """
-    This rule generates and compiles lite Java and Kotlin APIs for a specified proto_library.
-
-    Args:
-      name: A name for the target
-      deps: One or more proto_library targets
-      tags: List of string tags passed to generated targets.
-      testonly: Whether this target is intended only for tests.
-      compatible_with: Standard attribute, see http://go/be-common#common.compatible_with
-      restricted_to: Standard attribute, see http://go/be-common#common.restricted_to
-      visibility: A list of targets allowed to depend on this rule.
-      deprecation: Standard attribute, see http://go/be-common#common.deprecation
-      features: Features enabled.
-    """
-
-    tags = (tags or []) + ["kt_jvm_lite_proto_library"]
-
-    native.java_lite_proto_library(
-        name = _lite_proto_name(name)[1:],
-        deps = deps,
-        testonly = testonly,
-        compatible_with = compatible_with,
-        visibility = ["//visibility:private"],
-        restricted_to = restricted_to,
-        tags = tags + ["avoid_dep"],
-        deprecation = deprecation,
-        features = features,
-    )
-
-    _kt_proto_library_helper(
-        name = name,
-        proto_deps = deps,
-        deps = [
-            _lite_proto_name(name),
-            "//java/com/google/protobuf:protobuf_lite",
-            "//java/com/google/protobuf/kotlin:only_for_use_in_proto_generated_code_its_generator_and_tests",
-            "//java/com/google/protobuf/kotlin:shared_runtime",
-        ],
-        exports = [_lite_proto_name(name)],
-        testonly = testonly,
-        compatible_with = compatible_with,
-        restricted_to = restricted_to,
-        constraints = ["android"],
-        tags = tags,
-        variant = "lite",
-        visibility = visibility,
-        deprecation = deprecation,
-        features = features,
-    )
-
-def kt_jvm_proto_library(
-        name,
-        deps = None,
-        tags = None,
-        testonly = None,
-        compatible_with = None,
-        restricted_to = None,
-        visibility = None,
-        deprecation = None,
-        features = []):
-    """
-    This rule generates and compiles full Java and Kotlin APIs for a specified proto_library.
-
-    Args:
-      name: A name for the target
-      deps: One or more proto_library targets
-      tags: List of string tags passed to generated targets.
-      testonly: Whether this target is intended only for tests.
-      compatible_with: Standard attribute, see http://go/be-common#common.compatible_with
-      restricted_to: Standard attribute, see http://go/be-common#common.restricted_to
-      visibility: A list of targets allowed to depend on this rule.
-      deprecation: Standard attribute, see http://go/be-common#common.deprecation
-      features: Features enabled.
-    """
-
-    tags = (tags or []) + ["kt_jvm_proto_library"]
-
-    native.java_proto_library(
-        name = _proto_name(name)[1:],
-        deps = deps,
-        testonly = testonly,
-        compatible_with = compatible_with,
-        visibility = ["//visibility:private"],
-        restricted_to = restricted_to,
-        tags = tags + ["avoid_dep"],
-        deprecation = deprecation,
-        features = features,
-    )
-
-    _kt_proto_library_helper(
-        name = name,
-        proto_deps = deps,
-        deps = [
-            _proto_name(name),
-            "//java/com/google/protobuf",
-            "//java/com/google/protobuf/kotlin:only_for_use_in_proto_generated_code_its_generator_and_tests",
-            "//java/com/google/protobuf/kotlin:shared_runtime",
-        ],
-        exports = [_proto_name(name)],
-        testonly = testonly,
-        compatible_with = compatible_with,
-        constraints = [],
-        restricted_to = restricted_to,
-        tags = tags,
-        variant = "full",
-        visibility = visibility,
-        deprecation = deprecation,
-        features = features,
-    )
-
-register_extension_info(
-    extension = kt_jvm_proto_library,
-    label_regex_for_dep = "{extension_name}",
-)
-
-register_extension_info(
-    extension = kt_jvm_lite_proto_library,
-    label_regex_for_dep = "{extension_name}",
-)
diff --git a/third_party/build_defs/kt_jvm_proto_library.internal.bzl b/third_party/build_defs/kt_jvm_proto_library.internal.bzl
deleted file mode 100644
index fcb2cd1..0000000
--- a/third_party/build_defs/kt_jvm_proto_library.internal.bzl
+++ /dev/null
@@ -1,177 +0,0 @@
-"""Definitions for internals of Kotlin proto libraries."""
-
-load("//tools/build_defs/kotlin/release/rules:common.bzl", "common")
-load(
-    "//tools/build_defs/kotlin/release/rules:dep_checks_aspect.bzl",
-    "KtForbiddenInfo",
-    "dep_checks_aspect",
-)
-load(
-    "//tools/build_defs/kotlin/release/toolchains/kotlin_jvm:toolchain.bzl",
-    _toolchain = "toolchain",
-)
-
-def _get_real_short_path(file):
-    """Returns the correct short path file name to be used by protoc."""
-    short_path = file.short_path
-    if short_path.startswith("../"):
-        second_slash = short_path.index("/", 3)
-        short_path = short_path[second_slash + 1:]
-
-    virtual_imports = "_virtual_imports/"
-    if virtual_imports in short_path:
-        short_path = short_path.split(virtual_imports)[1].split("/", 1)[1]
-    return short_path
-
-def _kt_proto_extensions_impl(ctx):
-    for dep in ctx.attr.proto_deps + ctx.attr.deps + ctx.attr.exports:
-        if dep[KtForbiddenInfo].forbidden:
-            fail("""Not allowed to depend on %s from Kotlin code, see go/kotlin/build-rules#restrictions:
-           %s""" % (dep.label, "\n".join(dep[KtForbiddenInfo].forbidden)))
-
-    transitive_set = depset(
-        transitive =
-            [dep[ProtoInfo].transitive_descriptor_sets for dep in ctx.attr.proto_deps],
-    )
-    proto_sources = []
-    for dep in ctx.attr.proto_deps:
-        for file in dep[ProtoInfo].direct_sources:
-            proto_sources.append(_get_real_short_path(file))
-
-    gen_src_dir = ctx.actions.declare_directory(ctx.label.name + "/ktproto")
-    codegen_params = "lite:" if ctx.attr.variant == "lite" else ""
-
-    protoc_args = ctx.actions.args()
-    protoc_args.add("--kotlin_out=" + codegen_params + gen_src_dir.path)
-    protoc_args.add_joined(
-        transitive_set,
-        join_with = ctx.configuration.host_path_separator,
-        format_joined = "--descriptor_set_in=%s",
-    )
-    protoc_args.add_all(proto_sources)
-
-    ctx.actions.run(
-        inputs = depset(transitive = [transitive_set]),
-        outputs = [gen_src_dir],
-        executable = ctx.executable._protoc,
-        arguments = [protoc_args],
-        progress_message = "Generating kotlin proto extensions for " +
-                           ", ".join([
-                               str(dep.label)
-                               for dep in ctx.attr.proto_deps
-                           ]),
-    )
-
-    kt_toolchain = _toolchain.get(ctx)
-    compiler_plugins = [
-        kt_toolchain.marker_plugin,
-        kt_toolchain.strictdeps_plugin,
-    ]
-    result = common.kt_jvm_library(
-        ctx,
-        srcs = [gen_src_dir],
-        output = ctx.outputs.jar,
-        deps = [dep[JavaInfo] for dep in ctx.attr.deps],
-        exports = [dep[JavaInfo] for dep in ctx.attr.exports],
-        kotlincopts = ["-Xopt-in=kotlin.RequiresOptIn", "-nowarn"],
-        kt_toolchain = kt_toolchain,
-        java_toolchain = ctx.attr._java_toolchain,
-        compiler_plugins = compiler_plugins,
-        android_compatible = "android" in ctx.attr.constraints,
-        enforce_strict_deps = False,
-    )
-    java_info = java_common.add_constraints(
-        result.java_info,
-        constraints = ctx.attr.constraints,
-    )
-
-    transitive_runfiles = []
-    for p in common.collect_providers(DefaultInfo, ctx.attr.deps + ctx.attr.exports):
-        transitive_runfiles.append(p.data_runfiles.files)
-        transitive_runfiles.append(p.default_runfiles.files)
-    runfiles = ctx.runfiles(
-        files = [ctx.outputs.jar],
-        transitive_files = depset(transitive = transitive_runfiles),
-        collect_default = True,
-    )
-
-    return [
-        java_info,
-        OutputGroupInfo(_validation = depset(result.validations)),
-        DefaultInfo(
-            files = depset([ctx.outputs.jar]),
-            runfiles = runfiles,
-        ),
-        ProguardSpecProvider(depset(ctx.files._proguard_specs)),
-    ]
-
-kt_proto_library_helper = rule(
-    doc = """
-    This is a helper rule to combine the kotlin code generation work
-    of kt_jvm_proto_library and kt_jvm_lite_proto_library.
-
-    It generates Kotlin proto code with the protoc compiler using the
-    --kotlin_out flag and compiles that Kotlin code. It requires as a dependency
-    a proto_library and either a java_proto_library or java_lite_proto_library.
-    """,
-    attrs = dict(
-        proto_deps = attr.label_list(
-            providers = [ProtoInfo],
-            aspects = [dep_checks_aspect],
-        ),
-        deps = attr.label_list(
-            providers = [JavaInfo],
-            aspects = [dep_checks_aspect],
-        ),
-        exports = attr.label_list(
-            allow_rules = ["java_proto_library", "java_lite_proto_library"],
-            aspects = [dep_checks_aspect],
-        ),
-        constraints = attr.string_list(
-            doc = """Extra constraints imposed on this library, most commonly, 'android'. Constraints
-                     typically indicate that the library may be used in binaries running outside of
-                     Google production services. See go/be-java#java_library.constraints for details on
-                     supported constraints and what they mean. Note that all Java and Kotlin `deps` are
-                     required to carry compatible constraints.""",
-        ),
-        variant = attr.string(
-            mandatory = True,
-            values = ["lite", "full"],
-            doc = """Indicator of which Kotlin proto runtime to use.""",
-        ),
-        _protoc = attr.label(
-            default = Label("//net/proto2/compiler/public:protocol_compiler"),
-            cfg = "host",
-            executable = True,
-        ),
-        _java_toolchain = attr.label(
-            default = Label(
-                "//tools/jdk:current_java_toolchain",
-            ),
-        ),
-        _coverage_instrumenter = attr.label(
-            default = Label("//tools/build_defs/kotlin/release/rules:kt_coverage_instrumenter"),
-            cfg = "host",
-            executable = True,
-        ),
-        _coverage_runtime = attr.label(
-            default = Label("//third_party/java/jacoco:blaze-agent"),
-        ),
-        _toolchain = attr.label(
-            default = Label(
-                "//tools/build_defs/kotlin/release/toolchains/kotlin_jvm:kt_jvm_toolchain_internal_DO_NOT_USE",
-            ),
-        ),
-        _proguard_specs = attr.label_list(
-            allow_files = [".pgcfg"],
-            default = ["//java/com/google/protobuf/kotlin:kt_proto.pgcfg"],
-        ),
-    ),
-    fragments = ["java"],
-    outputs = dict(
-        jar = "lib%{name}.ktproto.jar",
-    ),
-    provides = [JavaInfo],
-    implementation = _kt_proto_extensions_impl,
-    toolchains = [_toolchain.type],
-)
